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 // Histogram is an object that aggregates statistics, and can summarize them in | 5 // Histogram is an object that aggregates statistics, and can summarize them in |
6 // various forms, including ASCII graphical, HTML, and numerically (as a | 6 // various forms, including ASCII graphical, HTML, and numerically (as a |
7 // vector of numbers corresponding to each of the aggregating buckets). | 7 // vector of numbers corresponding to each of the aggregating buckets). |
8 // See header file for details and examples. | 8 // See header file for details and examples. |
9 | 9 |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 | 11 |
| 12 #include <limits.h> |
12 #include <math.h> | 13 #include <math.h> |
13 | 14 |
14 #include <algorithm> | 15 #include <algorithm> |
15 #include <string> | 16 #include <string> |
16 | 17 |
17 #include "base/compiler_specific.h" | 18 #include "base/compiler_specific.h" |
18 #include "base/debug/alias.h" | 19 #include "base/debug/alias.h" |
19 #include "base/logging.h" | 20 #include "base/logging.h" |
20 #include "base/metrics/histogram_macros.h" | 21 #include "base/metrics/histogram_macros.h" |
21 #include "base/metrics/metrics_hashes.h" | 22 #include "base/metrics/metrics_hashes.h" |
22 #include "base/metrics/sample_vector.h" | 23 #include "base/metrics/sample_vector.h" |
23 #include "base/metrics/statistics_recorder.h" | 24 #include "base/metrics/statistics_recorder.h" |
24 #include "base/pickle.h" | 25 #include "base/pickle.h" |
25 #include "base/strings/string_util.h" | 26 #include "base/strings/string_util.h" |
26 #include "base/strings/stringprintf.h" | 27 #include "base/strings/stringprintf.h" |
27 #include "base/synchronization/lock.h" | 28 #include "base/synchronization/lock.h" |
28 #include "base/values.h" | 29 #include "base/values.h" |
29 | 30 |
30 namespace base { | 31 namespace base { |
31 | 32 |
32 namespace { | 33 namespace { |
33 | 34 |
34 bool ReadHistogramArguments(PickleIterator* iter, | 35 bool ReadHistogramArguments(PickleIterator* iter, |
35 std::string* histogram_name, | 36 std::string* histogram_name, |
36 int* flags, | 37 int* flags, |
37 int* declared_min, | 38 int* declared_min, |
38 int* declared_max, | 39 int* declared_max, |
39 size_t* bucket_count, | 40 size_t* bucket_count, |
40 uint32* range_checksum) { | 41 uint32_t* range_checksum) { |
41 if (!iter->ReadString(histogram_name) || | 42 if (!iter->ReadString(histogram_name) || |
42 !iter->ReadInt(flags) || | 43 !iter->ReadInt(flags) || |
43 !iter->ReadInt(declared_min) || | 44 !iter->ReadInt(declared_min) || |
44 !iter->ReadInt(declared_max) || | 45 !iter->ReadInt(declared_max) || |
45 !iter->ReadSizeT(bucket_count) || | 46 !iter->ReadSizeT(bucket_count) || |
46 !iter->ReadUInt32(range_checksum)) { | 47 !iter->ReadUInt32(range_checksum)) { |
47 DLOG(ERROR) << "Pickle error decoding Histogram: " << *histogram_name; | 48 DLOG(ERROR) << "Pickle error decoding Histogram: " << *histogram_name; |
48 return false; | 49 return false; |
49 } | 50 } |
50 | 51 |
(...skipping 10 matching lines...) Expand all Loading... |
61 | 62 |
62 // We use the arguments to find or create the local version of the histogram | 63 // We use the arguments to find or create the local version of the histogram |
63 // in this process, so we need to clear the IPC flag. | 64 // in this process, so we need to clear the IPC flag. |
64 DCHECK(*flags & HistogramBase::kIPCSerializationSourceFlag); | 65 DCHECK(*flags & HistogramBase::kIPCSerializationSourceFlag); |
65 *flags &= ~HistogramBase::kIPCSerializationSourceFlag; | 66 *flags &= ~HistogramBase::kIPCSerializationSourceFlag; |
66 | 67 |
67 return true; | 68 return true; |
68 } | 69 } |
69 | 70 |
70 bool ValidateRangeChecksum(const HistogramBase& histogram, | 71 bool ValidateRangeChecksum(const HistogramBase& histogram, |
71 uint32 range_checksum) { | 72 uint32_t range_checksum) { |
72 const Histogram& casted_histogram = | 73 const Histogram& casted_histogram = |
73 static_cast<const Histogram&>(histogram); | 74 static_cast<const Histogram&>(histogram); |
74 | 75 |
75 return casted_histogram.bucket_ranges()->checksum() == range_checksum; | 76 return casted_histogram.bucket_ranges()->checksum() == range_checksum; |
76 } | 77 } |
77 | 78 |
78 } // namespace | 79 } // namespace |
79 | 80 |
80 typedef HistogramBase::Count Count; | 81 typedef HistogramBase::Count Count; |
81 typedef HistogramBase::Sample Sample; | 82 typedef HistogramBase::Sample Sample; |
82 | 83 |
83 // static | 84 // static |
84 const size_t Histogram::kBucketCount_MAX = 16384u; | 85 const size_t Histogram::kBucketCount_MAX = 16384u; |
85 | 86 |
86 HistogramBase* Histogram::FactoryGet(const std::string& name, | 87 HistogramBase* Histogram::FactoryGet(const std::string& name, |
87 Sample minimum, | 88 Sample minimum, |
88 Sample maximum, | 89 Sample maximum, |
89 size_t bucket_count, | 90 size_t bucket_count, |
90 int32 flags) { | 91 int32_t flags) { |
91 bool valid_arguments = | 92 bool valid_arguments = |
92 InspectConstructionArguments(name, &minimum, &maximum, &bucket_count); | 93 InspectConstructionArguments(name, &minimum, &maximum, &bucket_count); |
93 DCHECK(valid_arguments); | 94 DCHECK(valid_arguments); |
94 | 95 |
95 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name); | 96 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name); |
96 if (!histogram) { | 97 if (!histogram) { |
97 // To avoid racy destruction at shutdown, the following will be leaked. | 98 // To avoid racy destruction at shutdown, the following will be leaked. |
98 BucketRanges* ranges = new BucketRanges(bucket_count + 1); | 99 BucketRanges* ranges = new BucketRanges(bucket_count + 1); |
99 InitializeBucketRanges(minimum, maximum, ranges); | 100 InitializeBucketRanges(minimum, maximum, ranges); |
100 const BucketRanges* registered_ranges = | 101 const BucketRanges* registered_ranges = |
(...skipping 18 matching lines...) Expand all Loading... |
119 DLOG(ERROR) << "Histogram " << name << " has bad construction arguments"; | 120 DLOG(ERROR) << "Histogram " << name << " has bad construction arguments"; |
120 return NULL; | 121 return NULL; |
121 } | 122 } |
122 return histogram; | 123 return histogram; |
123 } | 124 } |
124 | 125 |
125 HistogramBase* Histogram::FactoryTimeGet(const std::string& name, | 126 HistogramBase* Histogram::FactoryTimeGet(const std::string& name, |
126 TimeDelta minimum, | 127 TimeDelta minimum, |
127 TimeDelta maximum, | 128 TimeDelta maximum, |
128 size_t bucket_count, | 129 size_t bucket_count, |
129 int32 flags) { | 130 int32_t flags) { |
130 return FactoryGet(name, static_cast<Sample>(minimum.InMilliseconds()), | 131 return FactoryGet(name, static_cast<Sample>(minimum.InMilliseconds()), |
131 static_cast<Sample>(maximum.InMilliseconds()), bucket_count, | 132 static_cast<Sample>(maximum.InMilliseconds()), bucket_count, |
132 flags); | 133 flags); |
133 } | 134 } |
134 | 135 |
135 HistogramBase* Histogram::FactoryGet(const char* name, | 136 HistogramBase* Histogram::FactoryGet(const char* name, |
136 Sample minimum, | 137 Sample minimum, |
137 Sample maximum, | 138 Sample maximum, |
138 size_t bucket_count, | 139 size_t bucket_count, |
139 int32 flags) { | 140 int32_t flags) { |
140 return FactoryGet(std::string(name), minimum, maximum, bucket_count, flags); | 141 return FactoryGet(std::string(name), minimum, maximum, bucket_count, flags); |
141 } | 142 } |
142 | 143 |
143 HistogramBase* Histogram::FactoryTimeGet(const char* name, | 144 HistogramBase* Histogram::FactoryTimeGet(const char* name, |
144 TimeDelta minimum, | 145 TimeDelta minimum, |
145 TimeDelta maximum, | 146 TimeDelta maximum, |
146 size_t bucket_count, | 147 size_t bucket_count, |
147 int32 flags) { | 148 int32_t flags) { |
148 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count, | 149 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count, |
149 flags); | 150 flags); |
150 } | 151 } |
151 | 152 |
152 // Calculate what range of values are held in each bucket. | 153 // Calculate what range of values are held in each bucket. |
153 // We have to be careful that we don't pick a ratio between starting points in | 154 // We have to be careful that we don't pick a ratio between starting points in |
154 // consecutive buckets that is sooo small, that the integer bounds are the same | 155 // consecutive buckets that is sooo small, that the integer bounds are the same |
155 // (effectively making one bucket get no values). We need to avoid: | 156 // (effectively making one bucket get no values). We need to avoid: |
156 // ranges(i) == ranges(i + 1) | 157 // ranges(i) == ranges(i + 1) |
157 // To avoid that, we just do a fine-grained bucket width as far as we need to | 158 // To avoid that, we just do a fine-grained bucket width as far as we need to |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 for (size_t index = 0; index < bucket_count(); ++index) { | 198 for (size_t index = 0; index < bucket_count(); ++index) { |
198 int new_range = ranges(index); | 199 int new_range = ranges(index); |
199 if (previous_range >= new_range) | 200 if (previous_range >= new_range) |
200 inconsistencies |= BUCKET_ORDER_ERROR; | 201 inconsistencies |= BUCKET_ORDER_ERROR; |
201 previous_range = new_range; | 202 previous_range = new_range; |
202 } | 203 } |
203 | 204 |
204 if (!bucket_ranges()->HasValidChecksum()) | 205 if (!bucket_ranges()->HasValidChecksum()) |
205 inconsistencies |= RANGE_CHECKSUM_ERROR; | 206 inconsistencies |= RANGE_CHECKSUM_ERROR; |
206 | 207 |
207 int64 delta64 = samples.redundant_count() - samples.TotalCount(); | 208 int64_t delta64 = samples.redundant_count() - samples.TotalCount(); |
208 if (delta64 != 0) { | 209 if (delta64 != 0) { |
209 int delta = static_cast<int>(delta64); | 210 int delta = static_cast<int>(delta64); |
210 if (delta != delta64) | 211 if (delta != delta64) |
211 delta = INT_MAX; // Flag all giant errors as INT_MAX. | 212 delta = INT_MAX; // Flag all giant errors as INT_MAX. |
212 if (delta > 0) { | 213 if (delta > 0) { |
213 UMA_HISTOGRAM_COUNTS("Histogram.InconsistentCountHigh", delta); | 214 UMA_HISTOGRAM_COUNTS("Histogram.InconsistentCountHigh", delta); |
214 if (delta > kCommonRaceBasedCountMismatch) | 215 if (delta > kCommonRaceBasedCountMismatch) |
215 inconsistencies |= COUNT_HIGH_ERROR; | 216 inconsistencies |= COUNT_HIGH_ERROR; |
216 } else { | 217 } else { |
217 DCHECK_GT(0, delta); | 218 DCHECK_GT(0, delta); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 //------------------------------------------------------------------------------ | 372 //------------------------------------------------------------------------------ |
372 // Private methods | 373 // Private methods |
373 | 374 |
374 // static | 375 // static |
375 HistogramBase* Histogram::DeserializeInfoImpl(PickleIterator* iter) { | 376 HistogramBase* Histogram::DeserializeInfoImpl(PickleIterator* iter) { |
376 std::string histogram_name; | 377 std::string histogram_name; |
377 int flags; | 378 int flags; |
378 int declared_min; | 379 int declared_min; |
379 int declared_max; | 380 int declared_max; |
380 size_t bucket_count; | 381 size_t bucket_count; |
381 uint32 range_checksum; | 382 uint32_t range_checksum; |
382 | 383 |
383 if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min, | 384 if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min, |
384 &declared_max, &bucket_count, &range_checksum)) { | 385 &declared_max, &bucket_count, &range_checksum)) { |
385 return NULL; | 386 return NULL; |
386 } | 387 } |
387 | 388 |
388 // Find or create the local version of the histogram in this process. | 389 // Find or create the local version of the histogram in this process. |
389 HistogramBase* histogram = Histogram::FactoryGet( | 390 HistogramBase* histogram = Histogram::FactoryGet( |
390 histogram_name, declared_min, declared_max, bucket_count, flags); | 391 histogram_name, declared_min, declared_max, bucket_count, flags); |
391 | 392 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 // Calculate largest print width needed for any of our bucket range displays. | 432 // Calculate largest print width needed for any of our bucket range displays. |
432 size_t print_width = 1; | 433 size_t print_width = 1; |
433 for (size_t i = 0; i < bucket_count(); ++i) { | 434 for (size_t i = 0; i < bucket_count(); ++i) { |
434 if (snapshot->GetCountAtIndex(i)) { | 435 if (snapshot->GetCountAtIndex(i)) { |
435 size_t width = GetAsciiBucketRange(i).size() + 1; | 436 size_t width = GetAsciiBucketRange(i).size() + 1; |
436 if (width > print_width) | 437 if (width > print_width) |
437 print_width = width; | 438 print_width = width; |
438 } | 439 } |
439 } | 440 } |
440 | 441 |
441 int64 remaining = sample_count; | 442 int64_t remaining = sample_count; |
442 int64 past = 0; | 443 int64_t past = 0; |
443 // Output the actual histogram graph. | 444 // Output the actual histogram graph. |
444 for (size_t i = 0; i < bucket_count(); ++i) { | 445 for (size_t i = 0; i < bucket_count(); ++i) { |
445 Count current = snapshot->GetCountAtIndex(i); | 446 Count current = snapshot->GetCountAtIndex(i); |
446 if (!current && !PrintEmptyBucket(i)) | 447 if (!current && !PrintEmptyBucket(i)) |
447 continue; | 448 continue; |
448 remaining -= current; | 449 remaining -= current; |
449 std::string range = GetAsciiBucketRange(i); | 450 std::string range = GetAsciiBucketRange(i); |
450 output->append(range); | 451 output->append(range); |
451 for (size_t j = 0; range.size() + j < print_width + 1; ++j) | 452 for (size_t j = 0; range.size() + j < print_width + 1; ++j) |
452 output->push_back(' '); | 453 output->push_back(' '); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 DCHECK_EQ(samples.sum(), 0); | 492 DCHECK_EQ(samples.sum(), 0); |
492 } else { | 493 } else { |
493 double average = static_cast<float>(samples.sum()) / sample_count; | 494 double average = static_cast<float>(samples.sum()) / sample_count; |
494 | 495 |
495 StringAppendF(output, ", average = %.1f", average); | 496 StringAppendF(output, ", average = %.1f", average); |
496 } | 497 } |
497 if (flags() & ~kHexRangePrintingFlag) | 498 if (flags() & ~kHexRangePrintingFlag) |
498 StringAppendF(output, " (flags = 0x%x)", flags() & ~kHexRangePrintingFlag); | 499 StringAppendF(output, " (flags = 0x%x)", flags() & ~kHexRangePrintingFlag); |
499 } | 500 } |
500 | 501 |
501 void Histogram::WriteAsciiBucketContext(const int64 past, | 502 void Histogram::WriteAsciiBucketContext(const int64_t past, |
502 const Count current, | 503 const Count current, |
503 const int64 remaining, | 504 const int64_t remaining, |
504 const size_t i, | 505 const size_t i, |
505 std::string* output) const { | 506 std::string* output) const { |
506 double scaled_sum = (past + current + remaining) / 100.0; | 507 double scaled_sum = (past + current + remaining) / 100.0; |
507 WriteAsciiBucketValue(current, scaled_sum, output); | 508 WriteAsciiBucketValue(current, scaled_sum, output); |
508 if (0 < i) { | 509 if (0 < i) { |
509 double percentage = past / scaled_sum; | 510 double percentage = past / scaled_sum; |
510 StringAppendF(output, " {%3.1f%%}", percentage); | 511 StringAppendF(output, " {%3.1f%%}", percentage); |
511 } | 512 } |
512 } | 513 } |
513 | 514 |
514 void Histogram::GetParameters(DictionaryValue* params) const { | 515 void Histogram::GetParameters(DictionaryValue* params) const { |
515 params->SetString("type", HistogramTypeToString(GetHistogramType())); | 516 params->SetString("type", HistogramTypeToString(GetHistogramType())); |
516 params->SetInteger("min", declared_min()); | 517 params->SetInteger("min", declared_min()); |
517 params->SetInteger("max", declared_max()); | 518 params->SetInteger("max", declared_max()); |
518 params->SetInteger("bucket_count", static_cast<int>(bucket_count())); | 519 params->SetInteger("bucket_count", static_cast<int>(bucket_count())); |
519 } | 520 } |
520 | 521 |
521 void Histogram::GetCountAndBucketData(Count* count, | 522 void Histogram::GetCountAndBucketData(Count* count, |
522 int64* sum, | 523 int64_t* sum, |
523 ListValue* buckets) const { | 524 ListValue* buckets) const { |
524 scoped_ptr<SampleVector> snapshot = SnapshotSampleVector(); | 525 scoped_ptr<SampleVector> snapshot = SnapshotSampleVector(); |
525 *count = snapshot->TotalCount(); | 526 *count = snapshot->TotalCount(); |
526 *sum = snapshot->sum(); | 527 *sum = snapshot->sum(); |
527 size_t index = 0; | 528 size_t index = 0; |
528 for (size_t i = 0; i < bucket_count(); ++i) { | 529 for (size_t i = 0; i < bucket_count(); ++i) { |
529 Sample count_at_index = snapshot->GetCountAtIndex(i); | 530 Sample count_at_index = snapshot->GetCountAtIndex(i); |
530 if (count_at_index > 0) { | 531 if (count_at_index > 0) { |
531 scoped_ptr<DictionaryValue> bucket_value(new DictionaryValue()); | 532 scoped_ptr<DictionaryValue> bucket_value(new DictionaryValue()); |
532 bucket_value->SetInteger("low", ranges(i)); | 533 bucket_value->SetInteger("low", ranges(i)); |
(...skipping 10 matching lines...) Expand all Loading... |
543 // LinearHistogram: This histogram uses a traditional set of evenly spaced | 544 // LinearHistogram: This histogram uses a traditional set of evenly spaced |
544 // buckets. | 545 // buckets. |
545 //------------------------------------------------------------------------------ | 546 //------------------------------------------------------------------------------ |
546 | 547 |
547 LinearHistogram::~LinearHistogram() {} | 548 LinearHistogram::~LinearHistogram() {} |
548 | 549 |
549 HistogramBase* LinearHistogram::FactoryGet(const std::string& name, | 550 HistogramBase* LinearHistogram::FactoryGet(const std::string& name, |
550 Sample minimum, | 551 Sample minimum, |
551 Sample maximum, | 552 Sample maximum, |
552 size_t bucket_count, | 553 size_t bucket_count, |
553 int32 flags) { | 554 int32_t flags) { |
554 return FactoryGetWithRangeDescription( | 555 return FactoryGetWithRangeDescription( |
555 name, minimum, maximum, bucket_count, flags, NULL); | 556 name, minimum, maximum, bucket_count, flags, NULL); |
556 } | 557 } |
557 | 558 |
558 HistogramBase* LinearHistogram::FactoryTimeGet(const std::string& name, | 559 HistogramBase* LinearHistogram::FactoryTimeGet(const std::string& name, |
559 TimeDelta minimum, | 560 TimeDelta minimum, |
560 TimeDelta maximum, | 561 TimeDelta maximum, |
561 size_t bucket_count, | 562 size_t bucket_count, |
562 int32 flags) { | 563 int32_t flags) { |
563 return FactoryGet(name, static_cast<Sample>(minimum.InMilliseconds()), | 564 return FactoryGet(name, static_cast<Sample>(minimum.InMilliseconds()), |
564 static_cast<Sample>(maximum.InMilliseconds()), bucket_count, | 565 static_cast<Sample>(maximum.InMilliseconds()), bucket_count, |
565 flags); | 566 flags); |
566 } | 567 } |
567 | 568 |
568 HistogramBase* LinearHistogram::FactoryGet(const char* name, | 569 HistogramBase* LinearHistogram::FactoryGet(const char* name, |
569 Sample minimum, | 570 Sample minimum, |
570 Sample maximum, | 571 Sample maximum, |
571 size_t bucket_count, | 572 size_t bucket_count, |
572 int32 flags) { | 573 int32_t flags) { |
573 return FactoryGet(std::string(name), minimum, maximum, bucket_count, flags); | 574 return FactoryGet(std::string(name), minimum, maximum, bucket_count, flags); |
574 } | 575 } |
575 | 576 |
576 HistogramBase* LinearHistogram::FactoryTimeGet(const char* name, | 577 HistogramBase* LinearHistogram::FactoryTimeGet(const char* name, |
577 TimeDelta minimum, | 578 TimeDelta minimum, |
578 TimeDelta maximum, | 579 TimeDelta maximum, |
579 size_t bucket_count, | 580 size_t bucket_count, |
580 int32 flags) { | 581 int32_t flags) { |
581 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count, | 582 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count, |
582 flags); | 583 flags); |
583 } | 584 } |
584 | 585 |
585 HistogramBase* LinearHistogram::FactoryGetWithRangeDescription( | 586 HistogramBase* LinearHistogram::FactoryGetWithRangeDescription( |
586 const std::string& name, | 587 const std::string& name, |
587 Sample minimum, | 588 Sample minimum, |
588 Sample maximum, | 589 Sample maximum, |
589 size_t bucket_count, | 590 size_t bucket_count, |
590 int32 flags, | 591 int32_t flags, |
591 const DescriptionPair descriptions[]) { | 592 const DescriptionPair descriptions[]) { |
592 bool valid_arguments = Histogram::InspectConstructionArguments( | 593 bool valid_arguments = Histogram::InspectConstructionArguments( |
593 name, &minimum, &maximum, &bucket_count); | 594 name, &minimum, &maximum, &bucket_count); |
594 DCHECK(valid_arguments); | 595 DCHECK(valid_arguments); |
595 | 596 |
596 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name); | 597 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name); |
597 if (!histogram) { | 598 if (!histogram) { |
598 // To avoid racy destruction at shutdown, the following will be leaked. | 599 // To avoid racy destruction at shutdown, the following will be leaked. |
599 BucketRanges* ranges = new BucketRanges(bucket_count + 1); | 600 BucketRanges* ranges = new BucketRanges(bucket_count + 1); |
600 InitializeBucketRanges(minimum, maximum, ranges); | 601 InitializeBucketRanges(minimum, maximum, ranges); |
601 const BucketRanges* registered_ranges = | 602 const BucketRanges* registered_ranges = |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 ranges->ResetChecksum(); | 679 ranges->ResetChecksum(); |
679 } | 680 } |
680 | 681 |
681 // static | 682 // static |
682 HistogramBase* LinearHistogram::DeserializeInfoImpl(PickleIterator* iter) { | 683 HistogramBase* LinearHistogram::DeserializeInfoImpl(PickleIterator* iter) { |
683 std::string histogram_name; | 684 std::string histogram_name; |
684 int flags; | 685 int flags; |
685 int declared_min; | 686 int declared_min; |
686 int declared_max; | 687 int declared_max; |
687 size_t bucket_count; | 688 size_t bucket_count; |
688 uint32 range_checksum; | 689 uint32_t range_checksum; |
689 | 690 |
690 if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min, | 691 if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min, |
691 &declared_max, &bucket_count, &range_checksum)) { | 692 &declared_max, &bucket_count, &range_checksum)) { |
692 return NULL; | 693 return NULL; |
693 } | 694 } |
694 | 695 |
695 HistogramBase* histogram = LinearHistogram::FactoryGet( | 696 HistogramBase* histogram = LinearHistogram::FactoryGet( |
696 histogram_name, declared_min, declared_max, bucket_count, flags); | 697 histogram_name, declared_min, declared_max, bucket_count, flags); |
697 if (!ValidateRangeChecksum(*histogram, range_checksum)) { | 698 if (!ValidateRangeChecksum(*histogram, range_checksum)) { |
698 // The serialized histogram might be corrupted. | 699 // The serialized histogram might be corrupted. |
699 return NULL; | 700 return NULL; |
700 } | 701 } |
701 return histogram; | 702 return histogram; |
702 } | 703 } |
703 | 704 |
704 //------------------------------------------------------------------------------ | 705 //------------------------------------------------------------------------------ |
705 // This section provides implementation for BooleanHistogram. | 706 // This section provides implementation for BooleanHistogram. |
706 //------------------------------------------------------------------------------ | 707 //------------------------------------------------------------------------------ |
707 | 708 |
708 HistogramBase* BooleanHistogram::FactoryGet(const std::string& name, | 709 HistogramBase* BooleanHistogram::FactoryGet(const std::string& name, |
709 int32 flags) { | 710 int32_t flags) { |
710 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name); | 711 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name); |
711 if (!histogram) { | 712 if (!histogram) { |
712 // To avoid racy destruction at shutdown, the following will be leaked. | 713 // To avoid racy destruction at shutdown, the following will be leaked. |
713 BucketRanges* ranges = new BucketRanges(4); | 714 BucketRanges* ranges = new BucketRanges(4); |
714 LinearHistogram::InitializeBucketRanges(1, 2, ranges); | 715 LinearHistogram::InitializeBucketRanges(1, 2, ranges); |
715 const BucketRanges* registered_ranges = | 716 const BucketRanges* registered_ranges = |
716 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); | 717 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); |
717 | 718 |
718 BooleanHistogram* tentative_histogram = | 719 BooleanHistogram* tentative_histogram = |
719 new BooleanHistogram(name, registered_ranges); | 720 new BooleanHistogram(name, registered_ranges); |
720 | 721 |
721 tentative_histogram->SetFlags(flags); | 722 tentative_histogram->SetFlags(flags); |
722 histogram = | 723 histogram = |
723 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); | 724 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); |
724 } | 725 } |
725 | 726 |
726 DCHECK_EQ(BOOLEAN_HISTOGRAM, histogram->GetHistogramType()); | 727 DCHECK_EQ(BOOLEAN_HISTOGRAM, histogram->GetHistogramType()); |
727 return histogram; | 728 return histogram; |
728 } | 729 } |
729 | 730 |
730 HistogramBase* BooleanHistogram::FactoryGet(const char* name, int32 flags) { | 731 HistogramBase* BooleanHistogram::FactoryGet(const char* name, int32_t flags) { |
731 return FactoryGet(std::string(name), flags); | 732 return FactoryGet(std::string(name), flags); |
732 } | 733 } |
733 | 734 |
734 HistogramType BooleanHistogram::GetHistogramType() const { | 735 HistogramType BooleanHistogram::GetHistogramType() const { |
735 return BOOLEAN_HISTOGRAM; | 736 return BOOLEAN_HISTOGRAM; |
736 } | 737 } |
737 | 738 |
738 BooleanHistogram::BooleanHistogram(const std::string& name, | 739 BooleanHistogram::BooleanHistogram(const std::string& name, |
739 const BucketRanges* ranges) | 740 const BucketRanges* ranges) |
740 : LinearHistogram(name, 1, 2, ranges) {} | 741 : LinearHistogram(name, 1, 2, ranges) {} |
741 | 742 |
742 HistogramBase* BooleanHistogram::DeserializeInfoImpl(PickleIterator* iter) { | 743 HistogramBase* BooleanHistogram::DeserializeInfoImpl(PickleIterator* iter) { |
743 std::string histogram_name; | 744 std::string histogram_name; |
744 int flags; | 745 int flags; |
745 int declared_min; | 746 int declared_min; |
746 int declared_max; | 747 int declared_max; |
747 size_t bucket_count; | 748 size_t bucket_count; |
748 uint32 range_checksum; | 749 uint32_t range_checksum; |
749 | 750 |
750 if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min, | 751 if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min, |
751 &declared_max, &bucket_count, &range_checksum)) { | 752 &declared_max, &bucket_count, &range_checksum)) { |
752 return NULL; | 753 return NULL; |
753 } | 754 } |
754 | 755 |
755 HistogramBase* histogram = BooleanHistogram::FactoryGet( | 756 HistogramBase* histogram = BooleanHistogram::FactoryGet( |
756 histogram_name, flags); | 757 histogram_name, flags); |
757 if (!ValidateRangeChecksum(*histogram, range_checksum)) { | 758 if (!ValidateRangeChecksum(*histogram, range_checksum)) { |
758 // The serialized histogram might be corrupted. | 759 // The serialized histogram might be corrupted. |
759 return NULL; | 760 return NULL; |
760 } | 761 } |
761 return histogram; | 762 return histogram; |
762 } | 763 } |
763 | 764 |
764 //------------------------------------------------------------------------------ | 765 //------------------------------------------------------------------------------ |
765 // CustomHistogram: | 766 // CustomHistogram: |
766 //------------------------------------------------------------------------------ | 767 //------------------------------------------------------------------------------ |
767 | 768 |
768 HistogramBase* CustomHistogram::FactoryGet( | 769 HistogramBase* CustomHistogram::FactoryGet( |
769 const std::string& name, | 770 const std::string& name, |
770 const std::vector<Sample>& custom_ranges, | 771 const std::vector<Sample>& custom_ranges, |
771 int32 flags) { | 772 int32_t flags) { |
772 CHECK(ValidateCustomRanges(custom_ranges)); | 773 CHECK(ValidateCustomRanges(custom_ranges)); |
773 | 774 |
774 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name); | 775 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name); |
775 if (!histogram) { | 776 if (!histogram) { |
776 BucketRanges* ranges = CreateBucketRangesFromCustomRanges(custom_ranges); | 777 BucketRanges* ranges = CreateBucketRangesFromCustomRanges(custom_ranges); |
777 const BucketRanges* registered_ranges = | 778 const BucketRanges* registered_ranges = |
778 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); | 779 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); |
779 | 780 |
780 // To avoid racy destruction at shutdown, the following will be leaked. | 781 // To avoid racy destruction at shutdown, the following will be leaked. |
781 CustomHistogram* tentative_histogram = | 782 CustomHistogram* tentative_histogram = |
782 new CustomHistogram(name, registered_ranges); | 783 new CustomHistogram(name, registered_ranges); |
783 | 784 |
784 tentative_histogram->SetFlags(flags); | 785 tentative_histogram->SetFlags(flags); |
785 | 786 |
786 histogram = | 787 histogram = |
787 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); | 788 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); |
788 } | 789 } |
789 | 790 |
790 DCHECK_EQ(histogram->GetHistogramType(), CUSTOM_HISTOGRAM); | 791 DCHECK_EQ(histogram->GetHistogramType(), CUSTOM_HISTOGRAM); |
791 return histogram; | 792 return histogram; |
792 } | 793 } |
793 | 794 |
794 HistogramBase* CustomHistogram::FactoryGet( | 795 HistogramBase* CustomHistogram::FactoryGet( |
795 const char* name, | 796 const char* name, |
796 const std::vector<Sample>& custom_ranges, | 797 const std::vector<Sample>& custom_ranges, |
797 int32 flags) { | 798 int32_t flags) { |
798 return FactoryGet(std::string(name), custom_ranges, flags); | 799 return FactoryGet(std::string(name), custom_ranges, flags); |
799 } | 800 } |
800 | 801 |
801 HistogramType CustomHistogram::GetHistogramType() const { | 802 HistogramType CustomHistogram::GetHistogramType() const { |
802 return CUSTOM_HISTOGRAM; | 803 return CUSTOM_HISTOGRAM; |
803 } | 804 } |
804 | 805 |
805 // static | 806 // static |
806 std::vector<Sample> CustomHistogram::ArrayToCustomRanges( | 807 std::vector<Sample> CustomHistogram::ArrayToCustomRanges( |
807 const Sample* values, size_t num_values) { | 808 const Sample* values, size_t num_values) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
841 return 1; | 842 return 1; |
842 } | 843 } |
843 | 844 |
844 // static | 845 // static |
845 HistogramBase* CustomHistogram::DeserializeInfoImpl(PickleIterator* iter) { | 846 HistogramBase* CustomHistogram::DeserializeInfoImpl(PickleIterator* iter) { |
846 std::string histogram_name; | 847 std::string histogram_name; |
847 int flags; | 848 int flags; |
848 int declared_min; | 849 int declared_min; |
849 int declared_max; | 850 int declared_max; |
850 size_t bucket_count; | 851 size_t bucket_count; |
851 uint32 range_checksum; | 852 uint32_t range_checksum; |
852 | 853 |
853 if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min, | 854 if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min, |
854 &declared_max, &bucket_count, &range_checksum)) { | 855 &declared_max, &bucket_count, &range_checksum)) { |
855 return NULL; | 856 return NULL; |
856 } | 857 } |
857 | 858 |
858 // First and last ranges are not serialized. | 859 // First and last ranges are not serialized. |
859 std::vector<Sample> sample_ranges(bucket_count - 1); | 860 std::vector<Sample> sample_ranges(bucket_count - 1); |
860 | 861 |
861 for (size_t i = 0; i < sample_ranges.size(); ++i) { | 862 for (size_t i = 0; i < sample_ranges.size(); ++i) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
898 | 899 |
899 BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); | 900 BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); |
900 for (size_t i = 0; i < ranges.size(); i++) { | 901 for (size_t i = 0; i < ranges.size(); i++) { |
901 bucket_ranges->set_range(i, ranges[i]); | 902 bucket_ranges->set_range(i, ranges[i]); |
902 } | 903 } |
903 bucket_ranges->ResetChecksum(); | 904 bucket_ranges->ResetChecksum(); |
904 return bucket_ranges; | 905 return bucket_ranges; |
905 } | 906 } |
906 | 907 |
907 } // namespace base | 908 } // namespace base |
OLD | NEW |