15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/trace_event_analyzer.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <math.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_reader.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace trace_analyzer { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TraceEvent 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TraceEvent::TraceEvent() 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : thread(0, 0), 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timestamp(0), 228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) duration(0), 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) phase(TRACE_EVENT_PHASE_BEGIN), 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_event(NULL) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TraceEvent::~TraceEvent() { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TraceEvent::SetFromJSON(const base::Value* event_value) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_value->GetType() != base::Value::TYPE_DICTIONARY) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Value must be TYPE_DICTIONARY"; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::DictionaryValue* dictionary = 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<const base::DictionaryValue*>(event_value); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string phase_str; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::DictionaryValue* args = NULL; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!dictionary->GetString("ph", &phase_str)) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "ph is missing from TraceEvent JSON"; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) phase = *phase_str.data(); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bool may_have_duration = (phase == TRACE_EVENT_PHASE_COMPLETE); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool require_origin = (phase != TRACE_EVENT_PHASE_METADATA); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool require_id = (phase == TRACE_EVENT_PHASE_ASYNC_BEGIN || 511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) phase == TRACE_EVENT_PHASE_ASYNC_STEP_INTO || 521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) phase == TRACE_EVENT_PHASE_ASYNC_STEP_PAST || 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) phase == TRACE_EVENT_PHASE_ASYNC_END); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (require_origin && !dictionary->GetInteger("pid", &thread.process_id)) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "pid is missing from TraceEvent JSON"; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (require_origin && !dictionary->GetInteger("tid", &thread.thread_id)) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "tid is missing from TraceEvent JSON"; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (require_origin && !dictionary->GetDouble("ts", ×tamp)) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "ts is missing from TraceEvent JSON"; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (may_have_duration) { 688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) dictionary->GetDouble("dur", &duration); 698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!dictionary->GetString("cat", &category)) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "cat is missing from TraceEvent JSON"; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!dictionary->GetString("name", &name)) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "name is missing from TraceEvent JSON"; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!dictionary->GetDictionary("args", &args)) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "args is missing from TraceEvent JSON"; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (require_id && !dictionary->GetString("id", &id)) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "id is missing from ASYNC_BEGIN/ASYNC_END TraceEvent JSON"; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For each argument, copy the type and create a trace_analyzer::TraceValue. 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (base::DictionaryValue::Iterator it(*args); !it.IsAtEnd(); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it.Advance()) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string str; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool boolean = false; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int int_num = 0; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double double_num = 0.0; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it.value().GetAsString(&str)) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) arg_strings[it.key()] = str; 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (it.value().GetAsInteger(&int_num)) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) arg_numbers[it.key()] = static_cast<double>(int_num); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (it.value().GetAsBoolean(&boolean)) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) arg_numbers[it.key()] = static_cast<double>(boolean ? 1 : 0); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (it.value().GetAsDouble(&double_num)) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) arg_numbers[it.key()] = double_num; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else { 1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LOG(WARNING) << "Value type of argument is not supported: " << 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<int>(it.value().GetType()); 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) continue; // Skip non-supported arguments. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)double TraceEvent::GetAbsTimeToOtherEvent() const { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return fabs(other_event->timestamp - timestamp); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TraceEvent::GetArgAsString(const std::string& name, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* arg) const { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, std::string>::const_iterator i = arg_strings.find(name); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != arg_strings.end()) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *arg = i->second; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TraceEvent::GetArgAsNumber(const std::string& name, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double* arg) const { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, double>::const_iterator i = arg_numbers.find(name); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != arg_numbers.end()) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *arg = i->second; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TraceEvent::HasStringArg(const std::string& name) const { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (arg_strings.find(name) != arg_strings.end()); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TraceEvent::HasNumberArg(const std::string& name) const { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (arg_numbers.find(name) != arg_numbers.end()); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TraceEvent::GetKnownArgAsString(const std::string& name) const { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string arg_string; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetArgAsString(name, &arg_string)) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return arg_string; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::string(); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)double TraceEvent::GetKnownArgAsDouble(const std::string& name) const { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double arg_double; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetArgAsNumber(name, &arg_double)) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return arg_double; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TraceEvent::GetKnownArgAsInt(const std::string& name) const { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double arg_double; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetArgAsNumber(name, &arg_double)) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<int>(arg_double); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TraceEvent::GetKnownArgAsBool(const std::string& name) const { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double arg_double; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetArgAsNumber(name, &arg_double)) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (arg_double != 0.0); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// QueryNode 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QueryNode::QueryNode(const Query& query) : query_(query) { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QueryNode::~QueryNode() { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Query 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query::Query(TraceEventMember member) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : type_(QUERY_EVENT_MEMBER), 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operator_(OP_INVALID), 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) member_(member), 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) number_(0), 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_pattern_(false) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query::Query(TraceEventMember member, const std::string& arg_name) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : type_(QUERY_EVENT_MEMBER), 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operator_(OP_INVALID), 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) member_(member), 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) number_(0), 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_(arg_name), 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_pattern_(false) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query::Query(const Query& query) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : type_(query.type_), 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operator_(query.operator_), 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) left_(query.left_), 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) right_(query.right_), 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) member_(query.member_), 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) number_(query.number_), 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_(query.string_), 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_pattern_(query.is_pattern_) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query::~Query() { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::String(const std::string& str) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(str); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::Double(double num) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(num); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::Int(int32 num) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(static_cast<double>(num)); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::Uint(uint32 num) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(static_cast<double>(num)); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::Bool(bool boolean) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(boolean ? 1.0 : 0.0); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::Phase(char phase) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(static_cast<double>(phase)); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::Pattern(const std::string& pattern) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Query query(pattern); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) query.is_pattern_ = true; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return query; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Query::Evaluate(const TraceEvent& event) const { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First check for values that can convert to bool. 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // double is true if != 0: 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double bool_value = 0.0; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_bool = GetAsDouble(event, &bool_value); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_bool) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (bool_value != 0.0); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // string is true if it is non-empty: 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string str_value; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_str = GetAsString(event, &str_value); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_str) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !str_value.empty(); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(type_ == QUERY_BOOLEAN_OPERATOR) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Invalid query: missing boolean expression"; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(left_.get() && (right_.get() || is_unary_operator())); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_comparison_operator()) { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(left().is_value() && right().is_value()) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Invalid query: comparison operator used between event member and " 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "value."; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool compare_result = false; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CompareAsDouble(event, &compare_result)) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return compare_result; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (CompareAsString(event, &compare_result)) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return compare_result; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's a logical operator. 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (operator_) { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_AND: 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return left().Evaluate(event) && right().Evaluate(event); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_OR: 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return left().Evaluate(event) || right().Evaluate(event); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_NOT: 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !left().Evaluate(event); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Query::CompareAsDouble(const TraceEvent& event, bool* result) const { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double lhs, rhs; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!left().GetAsDouble(event, &lhs) || !right().GetAsDouble(event, &rhs)) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (operator_) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_EQ: 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = (lhs == rhs); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_NE: 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = (lhs != rhs); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_LT: 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = (lhs < rhs); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_LE: 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = (lhs <= rhs); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_GT: 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = (lhs > rhs); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_GE: 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = (lhs >= rhs); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Query::CompareAsString(const TraceEvent& event, bool* result) const { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string lhs, rhs; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!left().GetAsString(event, &lhs) || !right().GetAsString(event, &rhs)) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (operator_) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_EQ: 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (right().is_pattern_) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = MatchPattern(lhs, rhs); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (left().is_pattern_) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = MatchPattern(rhs, lhs); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = (lhs == rhs); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_NE: 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (right().is_pattern_) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = !MatchPattern(lhs, rhs); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (left().is_pattern_) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = !MatchPattern(rhs, lhs); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = (lhs != rhs); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_LT: 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = (lhs < rhs); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_LE: 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = (lhs <= rhs); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_GT: 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = (lhs > rhs); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_GE: 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = (lhs >= rhs); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Query::EvaluateArithmeticOperator(const TraceEvent& event, 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double* num) const { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(type_ == QUERY_ARITHMETIC_OPERATOR); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(left_.get() && (right_.get() || is_unary_operator())); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double lhs = 0, rhs = 0; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!left().GetAsDouble(event, &lhs)) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_unary_operator() && !right().GetAsDouble(event, &rhs)) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (operator_) { 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_ADD: 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *num = lhs + rhs; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_SUB: 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *num = lhs - rhs; 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_MUL: 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *num = lhs * rhs; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_DIV: 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *num = lhs / rhs; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_MOD: 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *num = static_cast<double>(static_cast<int64>(lhs) % 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int64>(rhs)); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OP_NEGATE: 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *num = -lhs; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Query::GetAsDouble(const TraceEvent& event, double* num) const { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type_) { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case QUERY_ARITHMETIC_OPERATOR: 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EvaluateArithmeticOperator(event, num); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case QUERY_EVENT_MEMBER: 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetMemberValueAsDouble(event, num); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case QUERY_NUMBER: 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *num = number_; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Query::GetAsString(const TraceEvent& event, std::string* str) const { 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type_) { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case QUERY_EVENT_MEMBER: 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetMemberValueAsString(event, str); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case QUERY_STRING: 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *str = string_; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Query::GetMemberValueAsDouble(const TraceEvent& event, 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double* num) const { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(type_ == QUERY_EVENT_MEMBER); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This could be a request for a member of |event| or a member of |event|'s 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // associated event. Store the target event in the_event: 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TraceEvent* the_event = (member_ < OTHER_PID) ? 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &event : event.other_event; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Request for member of associated event, but there is no associated event. 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!the_event) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (member_) { 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVENT_PID: 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OTHER_PID: 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *num = static_cast<double>(the_event->thread.process_id); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVENT_TID: 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OTHER_TID: 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *num = static_cast<double>(the_event->thread.thread_id); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVENT_TIME: 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OTHER_TIME: 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *num = the_event->timestamp; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVENT_DURATION: 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (the_event->has_other_event()) { 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *num = the_event->GetAbsTimeToOtherEvent(); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case EVENT_COMPLETE_DURATION: 4598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (the_event->phase == TRACE_EVENT_PHASE_COMPLETE) { 4608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) *num = the_event->duration; 4618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return true; 4628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return false; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVENT_PHASE: 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OTHER_PHASE: 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *num = static_cast<double>(the_event->phase); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVENT_HAS_STRING_ARG: 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OTHER_HAS_STRING_ARG: 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *num = (the_event->HasStringArg(string_) ? 1.0 : 0.0); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVENT_HAS_NUMBER_ARG: 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OTHER_HAS_NUMBER_ARG: 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *num = (the_event->HasNumberArg(string_) ? 1.0 : 0.0); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVENT_ARG: 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OTHER_ARG: { 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Search for the argument name and return its value if found. 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, double>::const_iterator num_i = 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) the_event->arg_numbers.find(string_); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_i == the_event->arg_numbers.end()) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *num = num_i->second; 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVENT_HAS_OTHER: 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // return 1.0 (true) if the other event exists 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *num = event.other_event ? 1.0 : 0.0; 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Query::GetMemberValueAsString(const TraceEvent& event, 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* str) const { 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(type_ == QUERY_EVENT_MEMBER); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This could be a request for a member of |event| or a member of |event|'s 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // associated event. Store the target event in the_event: 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TraceEvent* the_event = (member_ < OTHER_PID) ? 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &event : event.other_event; 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Request for member of associated event, but there is no associated event. 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!the_event) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (member_) { 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVENT_CATEGORY: 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OTHER_CATEGORY: 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *str = the_event->category; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVENT_NAME: 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OTHER_NAME: 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *str = the_event->name; 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVENT_ID: 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OTHER_ID: 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *str = the_event->id; 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVENT_ARG: 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OTHER_ARG: { 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Search for the argument name and return its value if found. 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, std::string>::const_iterator str_i = 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) the_event->arg_strings.find(string_); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (str_i == the_event->arg_strings.end()) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *str = str_i->second; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query::Query(const std::string& str) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : type_(QUERY_STRING), 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operator_(OP_INVALID), 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) member_(EVENT_INVALID), 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) number_(0), 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_(str), 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_pattern_(false) { 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query::Query(double num) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : type_(QUERY_NUMBER), 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operator_(OP_INVALID), 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) member_(EVENT_INVALID), 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) number_(num), 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_pattern_(false) { 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Query& Query::left() const { 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return left_->query(); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Query& Query::right() const { 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return right_->query(); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::operator==(const Query& rhs) const { 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(*this, rhs, OP_EQ); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::operator!=(const Query& rhs) const { 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(*this, rhs, OP_NE); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::operator<(const Query& rhs) const { 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(*this, rhs, OP_LT); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::operator<=(const Query& rhs) const { 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(*this, rhs, OP_LE); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::operator>(const Query& rhs) const { 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(*this, rhs, OP_GT); 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::operator>=(const Query& rhs) const { 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(*this, rhs, OP_GE); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::operator&&(const Query& rhs) const { 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(*this, rhs, OP_AND); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::operator||(const Query& rhs) const { 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(*this, rhs, OP_OR); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::operator!() const { 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(*this, OP_NOT); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::operator+(const Query& rhs) const { 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(*this, rhs, OP_ADD); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::operator-(const Query& rhs) const { 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(*this, rhs, OP_SUB); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::operator*(const Query& rhs) const { 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(*this, rhs, OP_MUL); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::operator/(const Query& rhs) const { 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(*this, rhs, OP_DIV); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::operator%(const Query& rhs) const { 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(*this, rhs, OP_MOD); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query Query::operator-() const { 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Query(*this, OP_NEGATE); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query::Query(const Query& left, const Query& right, Operator binary_op) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : operator_(binary_op), 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) left_(new QueryNode(left)), 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) right_(new QueryNode(right)), 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) member_(EVENT_INVALID), 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) number_(0) { 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_ = (binary_op < OP_ADD ? 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QUERY_BOOLEAN_OPERATOR : QUERY_ARITHMETIC_OPERATOR); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Query::Query(const Query& left, Operator unary_op) 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : operator_(unary_op), 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) left_(new QueryNode(left)), 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) member_(EVENT_INVALID), 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) number_(0) { 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_ = (unary_op < OP_ADD ? 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QUERY_BOOLEAN_OPERATOR : QUERY_ARITHMETIC_OPERATOR); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Search |events| for |query| and add matches to |output|. 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t FindMatchingEvents(const std::vector<TraceEvent>& events, 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Query& query, 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceEventVector* output) { 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < events.size(); ++i) { 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (query.Evaluate(events[i])) 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->push_back(&events[i]); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return output->size(); 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParseEventsFromJson(const std::string& json, 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<TraceEvent>* output) { 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::Value> root; 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root.reset(base::JSONReader::Read(json)); 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::ListValue* root_list = NULL; 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!root.get() || !root->GetAsList(&root_list)) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < root_list->GetSize(); ++i) { 6637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Value* item = NULL; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (root_list->Get(i, &item)) { 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceEvent event; 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.SetFromJSON(item)) 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->push_back(event); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TraceAnalyzer 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TraceAnalyzer::TraceAnalyzer() : allow_assocation_changes_(true) { 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TraceAnalyzer::~TraceAnalyzer() { 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TraceAnalyzer* TraceAnalyzer::Create(const std::string& json_events) { 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<TraceAnalyzer> analyzer(new TraceAnalyzer()); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (analyzer->SetEvents(json_events)) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return analyzer.release(); 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TraceAnalyzer::SetEvents(const std::string& json_events) { 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw_events_.clear(); 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ParseEventsFromJson(json_events, &raw_events_)) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::stable_sort(raw_events_.begin(), raw_events_.end()); 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParseMetadata(); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceAnalyzer::AssociateBeginEndEvents() { 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using trace_analyzer::Query; 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Query begin(Query::EventPhaseIs(TRACE_EVENT_PHASE_BEGIN)); 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Query end(Query::EventPhaseIs(TRACE_EVENT_PHASE_END)); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Query match(Query::EventName() == Query::OtherName() && 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Query::EventCategory() == Query::OtherCategory() && 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Query::EventTid() == Query::OtherTid() && 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Query::EventPid() == Query::OtherPid()); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssociateEvents(begin, end, match); 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceAnalyzer::AssociateAsyncBeginEndEvents() { 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using trace_analyzer::Query; 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Query begin( 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Query::EventPhaseIs(TRACE_EVENT_PHASE_ASYNC_BEGIN) || 7211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Query::EventPhaseIs(TRACE_EVENT_PHASE_ASYNC_STEP_INTO) || 7221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Query::EventPhaseIs(TRACE_EVENT_PHASE_ASYNC_STEP_PAST)); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Query end(Query::EventPhaseIs(TRACE_EVENT_PHASE_ASYNC_END) || 7241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Query::EventPhaseIs(TRACE_EVENT_PHASE_ASYNC_STEP_INTO) || 7251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Query::EventPhaseIs(TRACE_EVENT_PHASE_ASYNC_STEP_PAST)); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Query match(Query::EventName() == Query::OtherName() && 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Query::EventCategory() == Query::OtherCategory() && 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Query::EventId() == Query::OtherId()); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssociateEvents(begin, end, match); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceAnalyzer::AssociateEvents(const Query& first, 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Query& second, 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Query& match) { 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(allow_assocation_changes_) << "AssociateEvents not allowed after " 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "FindEvents"; 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Search for matching begin/end event pairs. When a matching end is found, 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it is associated with the begin event. 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<TraceEvent*> begin_stack; 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t event_index = 0; event_index < raw_events_.size(); 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++event_index) { 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceEvent& this_event = raw_events_[event_index]; 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (second.Evaluate(this_event)) { 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Search stack for matching begin, starting from end. 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int stack_index = static_cast<int>(begin_stack.size()) - 1; 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stack_index >= 0; --stack_index) { 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceEvent& begin_event = *begin_stack[stack_index]; 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Temporarily set other to test against the match query. 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TraceEvent* other_backup = begin_event.other_event; 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) begin_event.other_event = &this_event; 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (match.Evaluate(begin_event)) { 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Found a matching begin/end pair. 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Erase the matching begin event index from the stack. 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) begin_stack.erase(begin_stack.begin() + stack_index); 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Not a match, restore original other and continue. 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) begin_event.other_event = other_backup; 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Even if this_event is a |second| event that has matched an earlier 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |first| event, it can still also be a |first| event and be associated 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with a later |second| event. 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first.Evaluate(this_event)) { 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) begin_stack.push_back(&this_event); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceAnalyzer::MergeAssociatedEventArgs() { 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < raw_events_.size(); ++i) { 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Merge all associated events with the first event. 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TraceEvent* other = raw_events_[i].other_event; 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Avoid looping by keeping set of encountered TraceEvents. 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<const TraceEvent*> encounters; 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encounters.insert(&raw_events_[i]); 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (other && encounters.find(other) == encounters.end()) { 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encounters.insert(other); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw_events_[i].arg_numbers.insert( 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other->arg_numbers.begin(), 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other->arg_numbers.end()); 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw_events_[i].arg_strings.insert( 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other->arg_strings.begin(), 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other->arg_strings.end()); 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other = other->other_event; 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t TraceAnalyzer::FindEvents(const Query& query, TraceEventVector* output) { 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allow_assocation_changes_ = false; 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->clear(); 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FindMatchingEvents(raw_events_, query, output); 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const TraceEvent* TraceAnalyzer::FindFirstOf(const Query& query) { 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceEventVector output; 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FindEvents(query, &output) > 0) 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return output.front(); 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const TraceEvent* TraceAnalyzer::FindLastOf(const Query& query) { 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceEventVector output; 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FindEvents(query, &output) > 0) 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return output.back(); 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::string& TraceAnalyzer::GetThreadName( 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TraceEvent::ProcessThreadID& thread) { 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If thread is not found, just add and return empty string. 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return thread_names_[thread]; 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceAnalyzer::ParseMetadata() { 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < raw_events_.size(); ++i) { 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceEvent& this_event = raw_events_[i]; 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check for thread name metadata. 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this_event.phase != TRACE_EVENT_PHASE_METADATA || 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this_event.name != "thread_name") 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, std::string>::const_iterator string_it = 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this_event.arg_strings.find("name"); 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (string_it != this_event.arg_strings.end()) 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_names_[this_event.thread] = string_it->second; 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TraceEventVector utility functions. 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetRateStats(const TraceEventVector& events, 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RateStats* stats, 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RateStatsOptions* options) { 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(stats); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Need at least 3 events to calculate rate stats. 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t kMinEvents = 3; 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (events.size() < kMinEvents) { 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Not enough events: " << events.size(); 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<double> deltas; 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t num_deltas = events.size() - 1; 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < num_deltas; ++i) { 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double delta = events.at(i + 1)->timestamp - events.at(i)->timestamp; 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delta < 0.0) { 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Events are out of order"; 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deltas.push_back(delta); 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(deltas.begin(), deltas.end()); 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (options) { 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (options->trim_min + options->trim_max > events.size() - kMinEvents) { 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Attempt to trim too many events"; 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deltas.erase(deltas.begin(), deltas.begin() + options->trim_min); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deltas.erase(deltas.end() - options->trim_max, deltas.end()); 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_deltas = deltas.size(); 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double delta_sum = 0.0; 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < num_deltas; ++i) 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delta_sum += deltas[i]; 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stats->min_us = *std::min_element(deltas.begin(), deltas.end()); 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stats->max_us = *std::max_element(deltas.begin(), deltas.end()); 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stats->mean_us = delta_sum / static_cast<double>(num_deltas); 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double sum_mean_offsets_squared = 0.0; 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < num_deltas; ++i) { 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double offset = fabs(deltas[i] - stats->mean_us); 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sum_mean_offsets_squared += offset * offset; 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stats->standard_deviation_us = 8863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sqrt(sum_mean_offsets_squared / static_cast<double>(num_deltas - 1)); 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FindFirstOf(const TraceEventVector& events, 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Query& query, 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t position, 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t* return_index) { 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(return_index); 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = position; i < events.size(); ++i) { 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (query.Evaluate(*events.at(i))) { 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *return_index = i; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FindLastOf(const TraceEventVector& events, 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Query& query, 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t position, 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t* return_index) { 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(return_index); 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (events.empty()) 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position = (position < events.size()) ? position : events.size() - 1; 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (;;) { 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (query.Evaluate(*events.at(position))) { 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *return_index = position; 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (position == 0) 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --position; 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FindClosest(const TraceEventVector& events, 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Query& query, 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t position, 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t* return_closest, 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t* return_second_closest) { 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(return_closest); 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (events.empty() || position >= events.size()) 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t closest = events.size(); 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t second_closest = events.size(); 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < events.size(); ++i) { 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!query.Evaluate(*events.at(i))) 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (closest == events.size()) { 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) closest = i; 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fabs(events.at(i)->timestamp - events.at(position)->timestamp) < 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fabs(events.at(closest)->timestamp - events.at(position)->timestamp)) { 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) second_closest = closest; 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) closest = i; 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (second_closest == events.size()) { 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) second_closest = i; 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (closest < events.size() && 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (!return_second_closest || second_closest < events.size())) { 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *return_closest = closest; 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (return_second_closest) 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *return_second_closest = second_closest; 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t CountMatches(const TraceEventVector& events, 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Query& query, 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t begin_position, 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t end_position) { 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (begin_position >= events.size()) 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0u; 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end_position = (end_position < events.size()) ? end_position : events.size(); 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t count = 0u; 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = begin_position; i < end_position; ++i) { 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (query.Evaluate(*events.at(i))) 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++count; 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return count; 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace trace_analyzer 978