OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/test/trace_event_analyzer.h" | 5 #include "base/test/trace_event_analyzer.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <math.h> | 8 #include <math.h> |
9 #include <set> | 9 #include <set> |
10 | 10 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
84 return false; | 84 return false; |
85 } | 85 } |
86 | 86 |
87 // For each argument, copy the type and create a trace_analyzer::TraceValue. | 87 // For each argument, copy the type and create a trace_analyzer::TraceValue. |
88 for (base::DictionaryValue::Iterator it(*args); !it.IsAtEnd(); | 88 for (base::DictionaryValue::Iterator it(*args); !it.IsAtEnd(); |
89 it.Advance()) { | 89 it.Advance()) { |
90 std::string str; | 90 std::string str; |
91 bool boolean = false; | 91 bool boolean = false; |
92 int int_num = 0; | 92 int int_num = 0; |
93 double double_num = 0.0; | 93 double double_num = 0.0; |
94 if (it.value().GetAsString(&str)) | 94 if (it.value().GetAsString(&str)) { |
95 arg_strings[it.key()] = str; | 95 arg_strings[it.key()] = str; |
96 else if (it.value().GetAsInteger(&int_num)) | 96 } else if (it.value().GetAsInteger(&int_num)) { |
97 arg_numbers[it.key()] = static_cast<double>(int_num); | 97 arg_numbers[it.key()] = static_cast<double>(int_num); |
98 else if (it.value().GetAsBoolean(&boolean)) | 98 } else if (it.value().GetAsBoolean(&boolean)) { |
99 arg_numbers[it.key()] = static_cast<double>(boolean ? 1 : 0); | 99 arg_numbers[it.key()] = static_cast<double>(boolean ? 1 : 0); |
100 else if (it.value().GetAsDouble(&double_num)) | 100 } else if (it.value().GetAsDouble(&double_num)) { |
101 arg_numbers[it.key()] = double_num; | 101 arg_numbers[it.key()] = double_num; |
102 else { | 102 } else { |
103 LOG(WARNING) << "Value type of argument is not supported: " << | 103 LOG(WARNING) << "Value type of argument is not supported: " << |
104 static_cast<int>(it.value().GetType()); | 104 static_cast<int>(it.value().GetType()); |
105 continue; // Skip non-supported arguments. | 105 continue; // Skip non-supported arguments. |
106 } | 106 } |
107 } | 107 } |
108 | 108 |
109 return true; | 109 return true; |
110 } | 110 } |
111 | 111 |
112 double TraceEvent::GetAbsTimeToOtherEvent() const { | 112 double TraceEvent::GetAbsTimeToOtherEvent() const { |
(...skipping 23 matching lines...) Expand all Loading... | |
136 bool TraceEvent::HasStringArg(const std::string& name) const { | 136 bool TraceEvent::HasStringArg(const std::string& name) const { |
137 return (arg_strings.find(name) != arg_strings.end()); | 137 return (arg_strings.find(name) != arg_strings.end()); |
138 } | 138 } |
139 | 139 |
140 bool TraceEvent::HasNumberArg(const std::string& name) const { | 140 bool TraceEvent::HasNumberArg(const std::string& name) const { |
141 return (arg_numbers.find(name) != arg_numbers.end()); | 141 return (arg_numbers.find(name) != arg_numbers.end()); |
142 } | 142 } |
143 | 143 |
144 std::string TraceEvent::GetKnownArgAsString(const std::string& name) const { | 144 std::string TraceEvent::GetKnownArgAsString(const std::string& name) const { |
145 std::string arg_string; | 145 std::string arg_string; |
146 if (GetArgAsString(name, &arg_string)) | 146 bool result = GetArgAsString(name, &arg_string); |
147 return arg_string; | 147 DCHECK(result); |
148 NOTREACHED(); | 148 return arg_string; |
149 return std::string(); | |
150 } | 149 } |
151 | 150 |
152 double TraceEvent::GetKnownArgAsDouble(const std::string& name) const { | 151 double TraceEvent::GetKnownArgAsDouble(const std::string& name) const { |
153 double arg_double; | 152 double arg_double; |
154 if (GetArgAsNumber(name, &arg_double)) | 153 bool result = GetArgAsNumber(name, &arg_double); |
155 return arg_double; | 154 DCHECK(result); |
156 NOTREACHED(); | 155 return arg_double; |
157 return 0; | |
158 } | 156 } |
159 | 157 |
160 int TraceEvent::GetKnownArgAsInt(const std::string& name) const { | 158 int TraceEvent::GetKnownArgAsInt(const std::string& name) const { |
161 double arg_double; | 159 double arg_double; |
162 if (GetArgAsNumber(name, &arg_double)) | 160 bool result = GetArgAsNumber(name, &arg_double); |
163 return static_cast<int>(arg_double); | 161 DCHECK(result); |
164 NOTREACHED(); | 162 return static_cast<int>(arg_double); |
165 return 0; | |
166 } | 163 } |
167 | 164 |
168 bool TraceEvent::GetKnownArgAsBool(const std::string& name) const { | 165 bool TraceEvent::GetKnownArgAsBool(const std::string& name) const { |
169 double arg_double; | 166 double arg_double; |
170 if (GetArgAsNumber(name, &arg_double)) | 167 bool result = GetArgAsNumber(name, &arg_double); |
171 return (arg_double != 0.0); | 168 DCHECK(result); |
172 NOTREACHED(); | 169 return (arg_double != 0.0); |
173 return false; | |
174 } | 170 } |
175 | 171 |
176 // QueryNode | 172 // QueryNode |
177 | 173 |
178 QueryNode::QueryNode(const Query& query) : query_(query) { | 174 QueryNode::QueryNode(const Query& query) : query_(query) { |
179 } | 175 } |
180 | 176 |
181 QueryNode::~QueryNode() { | 177 QueryNode::~QueryNode() { |
182 } | 178 } |
183 | 179 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
252 bool is_bool = GetAsDouble(event, &bool_value); | 248 bool is_bool = GetAsDouble(event, &bool_value); |
253 if (is_bool) | 249 if (is_bool) |
254 return (bool_value != 0.0); | 250 return (bool_value != 0.0); |
255 | 251 |
256 // string is true if it is non-empty: | 252 // string is true if it is non-empty: |
257 std::string str_value; | 253 std::string str_value; |
258 bool is_str = GetAsString(event, &str_value); | 254 bool is_str = GetAsString(event, &str_value); |
259 if (is_str) | 255 if (is_str) |
260 return !str_value.empty(); | 256 return !str_value.empty(); |
261 | 257 |
262 DCHECK(type_ == QUERY_BOOLEAN_OPERATOR) | 258 DCHECK_EQ(QUERY_BOOLEAN_OPERATOR, type_) |
263 << "Invalid query: missing boolean expression"; | 259 << "Invalid query: missing boolean expression"; |
264 DCHECK(left_.get() && (right_.get() || is_unary_operator())); | 260 DCHECK(left_.get()); |
261 DCHECK(right_.get() || is_unary_operator()); | |
265 | 262 |
266 if (is_comparison_operator()) { | 263 if (is_comparison_operator()) { |
267 DCHECK(left().is_value() && right().is_value()) | 264 DCHECK(left().is_value() && right().is_value()) |
268 << "Invalid query: comparison operator used between event member and " | 265 << "Invalid query: comparison operator used between event member and " |
269 "value."; | 266 "value."; |
270 bool compare_result = false; | 267 bool compare_result = false; |
271 if (CompareAsDouble(event, &compare_result)) | 268 if (CompareAsDouble(event, &compare_result)) |
272 return compare_result; | 269 return compare_result; |
273 else if (CompareAsString(event, &compare_result)) | 270 return CompareAsString(event, &compare_result) ? compare_result : false; |
274 return compare_result; | |
275 return false; | |
276 } | 271 } |
272 | |
277 // It's a logical operator. | 273 // It's a logical operator. |
278 switch (operator_) { | 274 switch (operator_) { |
279 case OP_AND: | 275 case OP_AND: |
280 return left().Evaluate(event) && right().Evaluate(event); | 276 return left().Evaluate(event) && right().Evaluate(event); |
277 | |
281 case OP_OR: | 278 case OP_OR: |
282 return left().Evaluate(event) || right().Evaluate(event); | 279 return left().Evaluate(event) || right().Evaluate(event); |
280 | |
283 case OP_NOT: | 281 case OP_NOT: |
284 return !left().Evaluate(event); | 282 return !left().Evaluate(event); |
283 | |
285 default: | 284 default: |
286 NOTREACHED(); | 285 NOTREACHED(); |
286 return false; | |
287 } | 287 } |
288 | |
289 NOTREACHED(); | |
290 return false; | |
291 } | 288 } |
292 | 289 |
293 bool Query::CompareAsDouble(const TraceEvent& event, bool* result) const { | 290 bool Query::CompareAsDouble(const TraceEvent& event, bool* result) const { |
294 double lhs, rhs; | 291 double lhs, rhs; |
295 if (!left().GetAsDouble(event, &lhs) || !right().GetAsDouble(event, &rhs)) | 292 if (!left().GetAsDouble(event, &lhs) || !right().GetAsDouble(event, &rhs)) |
296 return false; | 293 return false; |
294 | |
297 switch (operator_) { | 295 switch (operator_) { |
298 case OP_EQ: | 296 case OP_EQ: |
299 *result = (lhs == rhs); | 297 *result = (lhs == rhs); |
300 return true; | 298 return true; |
299 | |
301 case OP_NE: | 300 case OP_NE: |
302 *result = (lhs != rhs); | 301 *result = (lhs != rhs); |
303 return true; | 302 return true; |
303 | |
304 case OP_LT: | 304 case OP_LT: |
305 *result = (lhs < rhs); | 305 *result = (lhs < rhs); |
306 return true; | 306 return true; |
307 | |
307 case OP_LE: | 308 case OP_LE: |
308 *result = (lhs <= rhs); | 309 *result = (lhs <= rhs); |
309 return true; | 310 return true; |
311 | |
310 case OP_GT: | 312 case OP_GT: |
311 *result = (lhs > rhs); | 313 *result = (lhs > rhs); |
312 return true; | 314 return true; |
315 | |
313 case OP_GE: | 316 case OP_GE: |
314 *result = (lhs >= rhs); | 317 *result = (lhs >= rhs); |
315 return true; | 318 return true; |
319 | |
316 default: | 320 default: |
317 NOTREACHED(); | 321 NOTREACHED(); |
318 return false; | 322 return false; |
319 } | 323 } |
320 return true; | |
321 } | 324 } |
322 | 325 |
323 bool Query::CompareAsString(const TraceEvent& event, bool* result) const { | 326 bool Query::CompareAsString(const TraceEvent& event, bool* result) const { |
324 std::string lhs, rhs; | 327 std::string lhs, rhs; |
325 if (!left().GetAsString(event, &lhs) || !right().GetAsString(event, &rhs)) | 328 if (!left().GetAsString(event, &lhs) || !right().GetAsString(event, &rhs)) |
326 return false; | 329 return false; |
330 | |
327 switch (operator_) { | 331 switch (operator_) { |
328 case OP_EQ: | 332 case OP_EQ: |
329 if (right().is_pattern_) | 333 if (right().is_pattern_) |
330 *result = MatchPattern(lhs, rhs); | 334 *result = MatchPattern(lhs, rhs); |
331 else if (left().is_pattern_) | 335 else if (left().is_pattern_) |
332 *result = MatchPattern(rhs, lhs); | 336 *result = MatchPattern(rhs, lhs); |
333 else | 337 else |
334 *result = (lhs == rhs); | 338 *result = (lhs == rhs); |
335 return true; | 339 return true; |
340 | |
336 case OP_NE: | 341 case OP_NE: |
337 if (right().is_pattern_) | 342 if (right().is_pattern_) |
338 *result = !MatchPattern(lhs, rhs); | 343 *result = !MatchPattern(lhs, rhs); |
339 else if (left().is_pattern_) | 344 else if (left().is_pattern_) |
340 *result = !MatchPattern(rhs, lhs); | 345 *result = !MatchPattern(rhs, lhs); |
341 else | 346 else |
342 *result = (lhs != rhs); | 347 *result = (lhs != rhs); |
343 return true; | 348 return true; |
349 | |
344 case OP_LT: | 350 case OP_LT: |
345 *result = (lhs < rhs); | 351 *result = (lhs < rhs); |
346 return true; | 352 return true; |
353 | |
347 case OP_LE: | 354 case OP_LE: |
348 *result = (lhs <= rhs); | 355 *result = (lhs <= rhs); |
349 return true; | 356 return true; |
357 | |
350 case OP_GT: | 358 case OP_GT: |
351 *result = (lhs > rhs); | 359 *result = (lhs > rhs); |
352 return true; | 360 return true; |
361 | |
353 case OP_GE: | 362 case OP_GE: |
354 *result = (lhs >= rhs); | 363 *result = (lhs >= rhs); |
355 return true; | 364 return true; |
365 | |
356 default: | 366 default: |
357 NOTREACHED(); | 367 NOTREACHED(); |
358 return false; | 368 return false; |
359 } | 369 } |
360 return true; | |
361 } | 370 } |
362 | 371 |
363 bool Query::EvaluateArithmeticOperator(const TraceEvent& event, | 372 bool Query::EvaluateArithmeticOperator(const TraceEvent& event, |
364 double* num) const { | 373 double* num) const { |
365 DCHECK(type_ == QUERY_ARITHMETIC_OPERATOR); | 374 DCHECK_EQ(QUERY_ARITHMETIC_OPERATOR, type_); |
366 DCHECK(left_.get() && (right_.get() || is_unary_operator())); | 375 DCHECK(left_.get()); |
376 DCHECK(right_.get() || is_unary_operator()); | |
367 | 377 |
368 double lhs = 0, rhs = 0; | 378 double lhs = 0, rhs = 0; |
369 if (!left().GetAsDouble(event, &lhs)) | 379 if (!left().GetAsDouble(event, &lhs)) |
370 return false; | 380 return false; |
371 if (!is_unary_operator() && !right().GetAsDouble(event, &rhs)) | 381 if (!is_unary_operator() && !right().GetAsDouble(event, &rhs)) |
372 return false; | 382 return false; |
373 | 383 |
374 switch (operator_) { | 384 switch (operator_) { |
375 case OP_ADD: | 385 case OP_ADD: |
376 *num = lhs + rhs; | 386 *num = lhs + rhs; |
377 return true; | 387 return true; |
388 | |
378 case OP_SUB: | 389 case OP_SUB: |
379 *num = lhs - rhs; | 390 *num = lhs - rhs; |
380 return true; | 391 return true; |
392 | |
381 case OP_MUL: | 393 case OP_MUL: |
382 *num = lhs * rhs; | 394 *num = lhs * rhs; |
383 return true; | 395 return true; |
396 | |
384 case OP_DIV: | 397 case OP_DIV: |
385 *num = lhs / rhs; | 398 *num = lhs / rhs; |
386 return true; | 399 return true; |
400 | |
387 case OP_MOD: | 401 case OP_MOD: |
388 *num = static_cast<double>(static_cast<int64>(lhs) % | 402 *num = static_cast<double>(static_cast<int64>(lhs) % |
389 static_cast<int64>(rhs)); | 403 static_cast<int64>(rhs)); |
390 return true; | 404 return true; |
405 | |
391 case OP_NEGATE: | 406 case OP_NEGATE: |
392 *num = -lhs; | 407 *num = -lhs; |
393 return true; | 408 return true; |
409 | |
394 default: | 410 default: |
395 NOTREACHED(); | 411 NOTREACHED(); |
396 return false; | 412 return false; |
397 } | 413 } |
398 } | 414 } |
399 | 415 |
400 bool Query::GetAsDouble(const TraceEvent& event, double* num) const { | 416 bool Query::GetAsDouble(const TraceEvent& event, double* num) const { |
401 switch (type_) { | 417 switch (type_) { |
402 case QUERY_ARITHMETIC_OPERATOR: | 418 case QUERY_ARITHMETIC_OPERATOR: |
403 return EvaluateArithmeticOperator(event, num); | 419 return EvaluateArithmeticOperator(event, num); |
420 | |
404 case QUERY_EVENT_MEMBER: | 421 case QUERY_EVENT_MEMBER: |
405 return GetMemberValueAsDouble(event, num); | 422 return GetMemberValueAsDouble(event, num); |
423 | |
406 case QUERY_NUMBER: | 424 case QUERY_NUMBER: |
407 *num = number_; | 425 *num = number_; |
408 return true; | 426 return true; |
427 | |
409 default: | 428 default: |
410 return false; | 429 return false; |
411 } | 430 } |
412 } | 431 } |
413 | 432 |
414 bool Query::GetAsString(const TraceEvent& event, std::string* str) const { | 433 bool Query::GetAsString(const TraceEvent& event, std::string* str) const { |
415 switch (type_) { | 434 switch (type_) { |
416 case QUERY_EVENT_MEMBER: | 435 case QUERY_EVENT_MEMBER: |
417 return GetMemberValueAsString(event, str); | 436 return GetMemberValueAsString(event, str); |
437 | |
418 case QUERY_STRING: | 438 case QUERY_STRING: |
419 *str = string_; | 439 *str = string_; |
420 return true; | 440 return true; |
441 | |
421 default: | 442 default: |
422 return false; | 443 return false; |
423 } | 444 } |
424 } | 445 } |
425 | 446 |
426 bool Query::GetMemberValueAsDouble(const TraceEvent& event, | 447 bool Query::GetMemberValueAsDouble(const TraceEvent& event, |
427 double* num) const { | 448 double* num) const { |
428 DCHECK(type_ == QUERY_EVENT_MEMBER); | 449 DCHECK_EQ(QUERY_EVENT_MEMBER, type_); |
429 | 450 |
430 // This could be a request for a member of |event| or a member of |event|'s | 451 // This could be a request for a member of |event| or a member of |event|'s |
431 // associated event. Store the target event in the_event: | 452 // associated event. Store the target event in the_event: |
432 const TraceEvent* the_event = (member_ < OTHER_PID) ? | 453 const TraceEvent* the_event = |
433 &event : event.other_event; | 454 (member_ < OTHER_PID) ? &event : event.other_event; |
434 | 455 |
435 // Request for member of associated event, but there is no associated event. | 456 // Request for member of associated event, but there is no associated event. |
436 if (!the_event) | 457 if (!the_event) |
437 return false; | 458 return false; |
438 | 459 |
439 switch (member_) { | 460 switch (member_) { |
440 case EVENT_PID: | 461 case EVENT_PID: |
441 case OTHER_PID: | 462 case OTHER_PID: |
442 *num = static_cast<double>(the_event->thread.process_id); | 463 *num = static_cast<double>(the_event->thread.process_id); |
443 return true; | 464 return true; |
465 | |
444 case EVENT_TID: | 466 case EVENT_TID: |
445 case OTHER_TID: | 467 case OTHER_TID: |
446 *num = static_cast<double>(the_event->thread.thread_id); | 468 *num = static_cast<double>(the_event->thread.thread_id); |
447 return true; | 469 return true; |
470 | |
448 case EVENT_TIME: | 471 case EVENT_TIME: |
449 case OTHER_TIME: | 472 case OTHER_TIME: |
450 *num = the_event->timestamp; | 473 *num = the_event->timestamp; |
451 return true; | 474 return true; |
475 | |
452 case EVENT_DURATION: | 476 case EVENT_DURATION: |
453 if (the_event->has_other_event()) { | 477 if (!the_event->has_other_event()) |
454 *num = the_event->GetAbsTimeToOtherEvent(); | 478 return false; |
455 return true; | 479 *num = the_event->GetAbsTimeToOtherEvent(); |
456 } | 480 return true; |
457 return false; | 481 |
458 case EVENT_COMPLETE_DURATION: | 482 case EVENT_COMPLETE_DURATION: |
459 if (the_event->phase == TRACE_EVENT_PHASE_COMPLETE) { | 483 if (the_event->phase != TRACE_EVENT_PHASE_COMPLETE) |
460 *num = the_event->duration; | 484 return false; |
461 return true; | 485 *num = the_event->duration; |
462 } | 486 return true; |
463 return false; | 487 |
464 case EVENT_PHASE: | 488 case EVENT_PHASE: |
465 case OTHER_PHASE: | 489 case OTHER_PHASE: |
466 *num = static_cast<double>(the_event->phase); | 490 *num = static_cast<double>(the_event->phase); |
467 return true; | 491 return true; |
492 | |
468 case EVENT_HAS_STRING_ARG: | 493 case EVENT_HAS_STRING_ARG: |
469 case OTHER_HAS_STRING_ARG: | 494 case OTHER_HAS_STRING_ARG: |
470 *num = (the_event->HasStringArg(string_) ? 1.0 : 0.0); | 495 *num = (the_event->HasStringArg(string_) ? 1.0 : 0.0); |
471 return true; | 496 return true; |
497 | |
472 case EVENT_HAS_NUMBER_ARG: | 498 case EVENT_HAS_NUMBER_ARG: |
473 case OTHER_HAS_NUMBER_ARG: | 499 case OTHER_HAS_NUMBER_ARG: |
474 *num = (the_event->HasNumberArg(string_) ? 1.0 : 0.0); | 500 *num = (the_event->HasNumberArg(string_) ? 1.0 : 0.0); |
475 return true; | 501 return true; |
502 | |
476 case EVENT_ARG: | 503 case EVENT_ARG: |
477 case OTHER_ARG: { | 504 case OTHER_ARG: { |
478 // Search for the argument name and return its value if found. | 505 // Search for the argument name and return its value if found. |
479 std::map<std::string, double>::const_iterator num_i = | 506 std::map<std::string, double>::const_iterator num_i = |
480 the_event->arg_numbers.find(string_); | 507 the_event->arg_numbers.find(string_); |
481 if (num_i == the_event->arg_numbers.end()) | 508 if (num_i == the_event->arg_numbers.end()) |
482 return false; | 509 return false; |
483 *num = num_i->second; | 510 *num = num_i->second; |
484 return true; | 511 return true; |
485 } | 512 } |
513 | |
486 case EVENT_HAS_OTHER: | 514 case EVENT_HAS_OTHER: |
487 // return 1.0 (true) if the other event exists | 515 // return 1.0 (true) if the other event exists |
488 *num = event.other_event ? 1.0 : 0.0; | 516 *num = event.other_event ? 1.0 : 0.0; |
489 return true; | 517 return true; |
518 | |
490 default: | 519 default: |
491 return false; | 520 return false; |
492 } | 521 } |
493 } | 522 } |
494 | 523 |
495 bool Query::GetMemberValueAsString(const TraceEvent& event, | 524 bool Query::GetMemberValueAsString(const TraceEvent& event, |
496 std::string* str) const { | 525 std::string* str) const { |
497 DCHECK(type_ == QUERY_EVENT_MEMBER); | 526 DCHECK_EQ(QUERY_EVENT_MEMBER, type_); |
498 | 527 |
499 // This could be a request for a member of |event| or a member of |event|'s | 528 // This could be a request for a member of |event| or a member of |event|'s |
500 // associated event. Store the target event in the_event: | 529 // associated event. Store the target event in the_event: |
501 const TraceEvent* the_event = (member_ < OTHER_PID) ? | 530 const TraceEvent* the_event = |
502 &event : event.other_event; | 531 (member_ < OTHER_PID) ? &event : event.other_event; |
503 | 532 |
504 // Request for member of associated event, but there is no associated event. | 533 // Request for member of associated event, but there is no associated event. |
505 if (!the_event) | 534 if (!the_event) |
506 return false; | 535 return false; |
507 | 536 |
508 switch (member_) { | 537 switch (member_) { |
509 case EVENT_CATEGORY: | 538 case EVENT_CATEGORY: |
510 case OTHER_CATEGORY: | 539 case OTHER_CATEGORY: |
511 *str = the_event->category; | 540 *str = the_event->category; |
512 return true; | 541 return true; |
542 | |
513 case EVENT_NAME: | 543 case EVENT_NAME: |
514 case OTHER_NAME: | 544 case OTHER_NAME: |
515 *str = the_event->name; | 545 *str = the_event->name; |
516 return true; | 546 return true; |
547 | |
517 case EVENT_ID: | 548 case EVENT_ID: |
518 case OTHER_ID: | 549 case OTHER_ID: |
519 *str = the_event->id; | 550 *str = the_event->id; |
520 return true; | 551 return true; |
552 | |
521 case EVENT_ARG: | 553 case EVENT_ARG: |
522 case OTHER_ARG: { | 554 case OTHER_ARG: { |
523 // Search for the argument name and return its value if found. | 555 // Search for the argument name and return its value if found. |
524 std::map<std::string, std::string>::const_iterator str_i = | 556 std::map<std::string, std::string>::const_iterator str_i = |
525 the_event->arg_strings.find(string_); | 557 the_event->arg_strings.find(string_); |
526 if (str_i == the_event->arg_strings.end()) | 558 if (str_i == the_event->arg_strings.end()) |
527 return false; | 559 return false; |
528 *str = str_i->second; | 560 *str = str_i->second; |
529 return true; | 561 return true; |
530 } | 562 } |
563 | |
531 default: | 564 default: |
532 return false; | 565 return false; |
533 } | 566 } |
534 } | 567 } |
535 | 568 |
536 Query::Query(const std::string& str) | 569 Query::Query(const std::string& str) |
537 : type_(QUERY_STRING), | 570 : type_(QUERY_STRING), |
538 operator_(OP_INVALID), | 571 operator_(OP_INVALID), |
539 member_(EVENT_INVALID), | 572 member_(EVENT_INVALID), |
540 number_(0), | 573 number_(0), |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
679 | 712 |
680 TraceAnalyzer::TraceAnalyzer() : allow_assocation_changes_(true) { | 713 TraceAnalyzer::TraceAnalyzer() : allow_assocation_changes_(true) { |
681 } | 714 } |
682 | 715 |
683 TraceAnalyzer::~TraceAnalyzer() { | 716 TraceAnalyzer::~TraceAnalyzer() { |
684 } | 717 } |
685 | 718 |
686 // static | 719 // static |
687 TraceAnalyzer* TraceAnalyzer::Create(const std::string& json_events) { | 720 TraceAnalyzer* TraceAnalyzer::Create(const std::string& json_events) { |
688 scoped_ptr<TraceAnalyzer> analyzer(new TraceAnalyzer()); | 721 scoped_ptr<TraceAnalyzer> analyzer(new TraceAnalyzer()); |
689 if (analyzer->SetEvents(json_events)) | 722 return analyzer->SetEvents(json_events) ? analyzer.release() : NULL; |
690 return analyzer.release(); | |
691 return NULL; | |
692 } | 723 } |
693 | 724 |
694 bool TraceAnalyzer::SetEvents(const std::string& json_events) { | 725 bool TraceAnalyzer::SetEvents(const std::string& json_events) { |
695 raw_events_.clear(); | 726 raw_events_.clear(); |
696 if (!ParseEventsFromJson(json_events, &raw_events_)) | 727 if (!ParseEventsFromJson(json_events, &raw_events_)) |
697 return false; | 728 return false; |
698 std::stable_sort(raw_events_.begin(), raw_events_.end()); | 729 std::stable_sort(raw_events_.begin(), raw_events_.end()); |
699 ParseMetadata(); | 730 ParseMetadata(); |
700 return true; | 731 return true; |
701 } | 732 } |
(...skipping 24 matching lines...) Expand all Loading... | |
726 Query match(Query::EventName() == Query::OtherName() && | 757 Query match(Query::EventName() == Query::OtherName() && |
727 Query::EventCategory() == Query::OtherCategory() && | 758 Query::EventCategory() == Query::OtherCategory() && |
728 Query::EventId() == Query::OtherId()); | 759 Query::EventId() == Query::OtherId()); |
729 | 760 |
730 AssociateEvents(begin, end, match); | 761 AssociateEvents(begin, end, match); |
731 } | 762 } |
732 | 763 |
733 void TraceAnalyzer::AssociateEvents(const Query& first, | 764 void TraceAnalyzer::AssociateEvents(const Query& first, |
734 const Query& second, | 765 const Query& second, |
735 const Query& match) { | 766 const Query& match) { |
736 DCHECK(allow_assocation_changes_) << "AssociateEvents not allowed after " | 767 DCHECK(allow_assocation_changes_) |
737 "FindEvents"; | 768 << "AssociateEvents not allowed after FindEvents"; |
738 | 769 |
739 // Search for matching begin/end event pairs. When a matching end is found, | 770 // Search for matching begin/end event pairs. When a matching end is found, |
740 // it is associated with the begin event. | 771 // it is associated with the begin event. |
741 std::vector<TraceEvent*> begin_stack; | 772 std::vector<TraceEvent*> begin_stack; |
742 for (size_t event_index = 0; event_index < raw_events_.size(); | 773 for (size_t event_index = 0; event_index < raw_events_.size(); |
743 ++event_index) { | 774 ++event_index) { |
744 | 775 |
745 TraceEvent& this_event = raw_events_[event_index]; | 776 TraceEvent& this_event = raw_events_[event_index]; |
746 | 777 |
747 if (second.Evaluate(this_event)) { | 778 if (second.Evaluate(this_event)) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
794 } | 825 } |
795 | 826 |
796 size_t TraceAnalyzer::FindEvents(const Query& query, TraceEventVector* output) { | 827 size_t TraceAnalyzer::FindEvents(const Query& query, TraceEventVector* output) { |
797 allow_assocation_changes_ = false; | 828 allow_assocation_changes_ = false; |
798 output->clear(); | 829 output->clear(); |
799 return FindMatchingEvents(raw_events_, query, output); | 830 return FindMatchingEvents(raw_events_, query, output); |
800 } | 831 } |
801 | 832 |
802 const TraceEvent* TraceAnalyzer::FindFirstOf(const Query& query) { | 833 const TraceEvent* TraceAnalyzer::FindFirstOf(const Query& query) { |
803 TraceEventVector output; | 834 TraceEventVector output; |
804 if (FindEvents(query, &output) > 0) | 835 return (FindEvents(query, &output) > 0) ? output.front() : NULL; |
Nico
2014/03/18 10:29:48
no parens
| |
805 return output.front(); | |
806 return NULL; | |
807 } | 836 } |
808 | 837 |
809 const TraceEvent* TraceAnalyzer::FindLastOf(const Query& query) { | 838 const TraceEvent* TraceAnalyzer::FindLastOf(const Query& query) { |
810 TraceEventVector output; | 839 TraceEventVector output; |
811 if (FindEvents(query, &output) > 0) | 840 return (FindEvents(query, &output) > 0) ? output.back() : NULL; |
Nico
2014/03/18 10:29:48
no parens
| |
812 return output.back(); | |
813 return NULL; | |
814 } | 841 } |
815 | 842 |
816 const std::string& TraceAnalyzer::GetThreadName( | 843 const std::string& TraceAnalyzer::GetThreadName( |
817 const TraceEvent::ProcessThreadID& thread) { | 844 const TraceEvent::ProcessThreadID& thread) { |
818 // If thread is not found, just add and return empty string. | 845 // If thread is not found, just add and return empty string. |
819 return thread_names_[thread]; | 846 return thread_names_[thread]; |
820 } | 847 } |
821 | 848 |
822 void TraceAnalyzer::ParseMetadata() { | 849 void TraceAnalyzer::ParseMetadata() { |
823 for (size_t i = 0; i < raw_events_.size(); ++i) { | 850 for (size_t i = 0; i < raw_events_.size(); ++i) { |
824 TraceEvent& this_event = raw_events_[i]; | 851 TraceEvent& this_event = raw_events_[i]; |
825 // Check for thread name metadata. | 852 // Check for thread name metadata. |
826 if (this_event.phase != TRACE_EVENT_PHASE_METADATA || | 853 if (this_event.phase != TRACE_EVENT_PHASE_METADATA || |
827 this_event.name != "thread_name") | 854 this_event.name != "thread_name") |
828 continue; | 855 continue; |
829 std::map<std::string, std::string>::const_iterator string_it = | 856 std::map<std::string, std::string>::const_iterator string_it = |
830 this_event.arg_strings.find("name"); | 857 this_event.arg_strings.find("name"); |
831 if (string_it != this_event.arg_strings.end()) | 858 if (string_it != this_event.arg_strings.end()) |
832 thread_names_[this_event.thread] = string_it->second; | 859 thread_names_[this_event.thread] = string_it->second; |
833 } | 860 } |
834 } | 861 } |
835 | 862 |
836 // TraceEventVector utility functions. | 863 // TraceEventVector utility functions. |
837 | 864 |
838 bool GetRateStats(const TraceEventVector& events, | 865 bool GetRateStats(const TraceEventVector& events, |
839 RateStats* stats, | 866 RateStats* stats, |
840 const RateStatsOptions* options) { | 867 const RateStatsOptions* options) { |
841 CHECK(stats); | 868 DCHECK(stats); |
842 // Need at least 3 events to calculate rate stats. | 869 // Need at least 3 events to calculate rate stats. |
843 const size_t kMinEvents = 3; | 870 const size_t kMinEvents = 3; |
844 if (events.size() < kMinEvents) { | 871 if (events.size() < kMinEvents) { |
845 LOG(ERROR) << "Not enough events: " << events.size(); | 872 LOG(ERROR) << "Not enough events: " << events.size(); |
846 return false; | 873 return false; |
847 } | 874 } |
848 | 875 |
849 std::vector<double> deltas; | 876 std::vector<double> deltas; |
850 size_t num_deltas = events.size() - 1; | 877 size_t num_deltas = events.size() - 1; |
851 for (size_t i = 0; i < num_deltas; ++i) { | 878 for (size_t i = 0; i < num_deltas; ++i) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
885 stats->standard_deviation_us = | 912 stats->standard_deviation_us = |
886 sqrt(sum_mean_offsets_squared / static_cast<double>(num_deltas - 1)); | 913 sqrt(sum_mean_offsets_squared / static_cast<double>(num_deltas - 1)); |
887 | 914 |
888 return true; | 915 return true; |
889 } | 916 } |
890 | 917 |
891 bool FindFirstOf(const TraceEventVector& events, | 918 bool FindFirstOf(const TraceEventVector& events, |
892 const Query& query, | 919 const Query& query, |
893 size_t position, | 920 size_t position, |
894 size_t* return_index) { | 921 size_t* return_index) { |
895 CHECK(return_index); | 922 DCHECK(return_index); |
896 for (size_t i = position; i < events.size(); ++i) { | 923 for (size_t i = position; i < events.size(); ++i) { |
897 if (query.Evaluate(*events.at(i))) { | 924 if (query.Evaluate(*events[i])) { |
Nico
2014/03/18 10:29:48
at() does bounds checking, operator[] doesn't. Is
Peter Kasting
2014/03/18 19:26:18
at() bounds-checks by way of exceptions. We don't
| |
898 *return_index = i; | 925 *return_index = i; |
899 return true; | 926 return true; |
900 } | 927 } |
901 } | 928 } |
902 return false; | 929 return false; |
903 } | 930 } |
904 | 931 |
905 bool FindLastOf(const TraceEventVector& events, | 932 bool FindLastOf(const TraceEventVector& events, |
906 const Query& query, | 933 const Query& query, |
907 size_t position, | 934 size_t position, |
908 size_t* return_index) { | 935 size_t* return_index) { |
909 CHECK(return_index); | 936 DCHECK(return_index); |
910 if (events.empty()) | 937 for (size_t i = std::min(position + 1, events.size()); i != 0; --i) { |
911 return false; | 938 if (query.Evaluate(*events[i - 1])) { |
912 position = (position < events.size()) ? position : events.size() - 1; | 939 *return_index = i - 1; |
913 for (;;) { | |
914 if (query.Evaluate(*events.at(position))) { | |
915 *return_index = position; | |
916 return true; | 940 return true; |
917 } | 941 } |
918 if (position == 0) | |
919 return false; | |
920 --position; | |
921 } | 942 } |
922 return false; | 943 return false; |
923 } | 944 } |
924 | 945 |
925 bool FindClosest(const TraceEventVector& events, | 946 bool FindClosest(const TraceEventVector& events, |
926 const Query& query, | 947 const Query& query, |
927 size_t position, | 948 size_t position, |
928 size_t* return_closest, | 949 size_t* return_closest, |
929 size_t* return_second_closest) { | 950 size_t* return_second_closest) { |
930 CHECK(return_closest); | 951 DCHECK(return_closest); |
931 if (events.empty() || position >= events.size()) | 952 if (events.empty() || position >= events.size()) |
932 return false; | 953 return false; |
933 size_t closest = events.size(); | 954 size_t closest = events.size(); |
934 size_t second_closest = events.size(); | 955 size_t second_closest = events.size(); |
935 for (size_t i = 0; i < events.size(); ++i) { | 956 for (size_t i = 0; i < events.size(); ++i) { |
936 if (!query.Evaluate(*events.at(i))) | 957 if (!query.Evaluate(*events.at(i))) |
937 continue; | 958 continue; |
938 if (closest == events.size()) { | 959 if (closest == events.size()) { |
939 closest = i; | 960 closest = i; |
940 continue; | 961 continue; |
(...skipping 27 matching lines...) Expand all Loading... | |
968 end_position = (end_position < events.size()) ? end_position : events.size(); | 989 end_position = (end_position < events.size()) ? end_position : events.size(); |
969 size_t count = 0u; | 990 size_t count = 0u; |
970 for (size_t i = begin_position; i < end_position; ++i) { | 991 for (size_t i = begin_position; i < end_position; ++i) { |
971 if (query.Evaluate(*events.at(i))) | 992 if (query.Evaluate(*events.at(i))) |
972 ++count; | 993 ++count; |
973 } | 994 } |
974 return count; | 995 return count; |
975 } | 996 } |
976 | 997 |
977 } // namespace trace_analyzer | 998 } // namespace trace_analyzer |
OLD | NEW |