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" |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
265 int32_t flags) { | 265 int32_t flags) { |
266 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count, | 266 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count, |
267 flags); | 267 flags); |
268 } | 268 } |
269 | 269 |
270 HistogramBase* Histogram::PersistentGet(const std::string& name, | 270 HistogramBase* Histogram::PersistentGet(const std::string& name, |
271 Sample minimum, | 271 Sample minimum, |
272 Sample maximum, | 272 Sample maximum, |
273 const BucketRanges* ranges, | 273 const BucketRanges* ranges, |
274 HistogramBase::AtomicCount* counts, | 274 HistogramBase::AtomicCount* counts, |
275 HistogramBase::AtomicCount* logged, | |
275 uint32_t counts_size, | 276 uint32_t counts_size, |
276 HistogramSamples::Metadata* meta) { | 277 HistogramSamples::Metadata* meta) { |
277 return new Histogram(name, minimum, maximum, ranges, counts, counts_size, | 278 return new Histogram(name, minimum, maximum, ranges, counts, logged, |
278 meta); | 279 counts_size, meta); |
279 } | 280 } |
280 | 281 |
281 // Calculate what range of values are held in each bucket. | 282 // Calculate what range of values are held in each bucket. |
282 // We have to be careful that we don't pick a ratio between starting points in | 283 // We have to be careful that we don't pick a ratio between starting points in |
283 // consecutive buckets that is sooo small, that the integer bounds are the same | 284 // consecutive buckets that is sooo small, that the integer bounds are the same |
284 // (effectively making one bucket get no values). We need to avoid: | 285 // (effectively making one bucket get no values). We need to avoid: |
285 // ranges(i) == ranges(i + 1) | 286 // ranges(i) == ranges(i + 1) |
286 // To avoid that, we just do a fine-grained bucket width as far as we need to | 287 // To avoid that, we just do a fine-grained bucket width as far as we need to |
287 // until we get a ratio that moves us along at least 2 units at a time. From | 288 // until we get a ratio that moves us along at least 2 units at a time. From |
288 // that bucket onward we do use the exponential growth of buckets. | 289 // that bucket onward we do use the exponential growth of buckets. |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
423 } | 424 } |
424 samples_->Accumulate(value, count); | 425 samples_->Accumulate(value, count); |
425 | 426 |
426 FindAndRunCallback(value); | 427 FindAndRunCallback(value); |
427 } | 428 } |
428 | 429 |
429 scoped_ptr<HistogramSamples> Histogram::SnapshotSamples() const { | 430 scoped_ptr<HistogramSamples> Histogram::SnapshotSamples() const { |
430 return SnapshotSampleVector(); | 431 return SnapshotSampleVector(); |
431 } | 432 } |
432 | 433 |
434 scoped_ptr<HistogramSamples> Histogram::SnapshotDelta() { | |
435 scoped_ptr<HistogramSamples> snapshot = SnapshotSampleVector(); | |
436 if (!logged_) { | |
437 // If nothing has been previously logged, save this one as logged and | |
Alexei Svitkine (slow)
2016/02/09 19:46:51
Nit: save this one as |logged_counts_| and
bcwhite
2016/02/11 16:42:38
Done.
| |
438 // gather another snapshot to return. | |
439 logged_.swap(snapshot); | |
440 return SnapshotSampleVector(); | |
441 } | |
442 | |
443 // Subtract what was previously logged and update that information. | |
444 snapshot->Subtract(*logged_); | |
445 logged_->Add(*snapshot); | |
446 return snapshot; | |
447 } | |
448 | |
433 void Histogram::AddSamples(const HistogramSamples& samples) { | 449 void Histogram::AddSamples(const HistogramSamples& samples) { |
434 samples_->Add(samples); | 450 samples_->Add(samples); |
435 } | 451 } |
436 | 452 |
437 bool Histogram::AddSamplesFromPickle(PickleIterator* iter) { | 453 bool Histogram::AddSamplesFromPickle(PickleIterator* iter) { |
438 return samples_->AddFromPickle(iter); | 454 return samples_->AddFromPickle(iter); |
439 } | 455 } |
440 | 456 |
441 // The following methods provide a graphical histogram display. | 457 // The following methods provide a graphical histogram display. |
442 void Histogram::WriteHTMLGraph(std::string* output) const { | 458 void Histogram::WriteHTMLGraph(std::string* output) const { |
(...skipping 27 matching lines...) Expand all Loading... | |
470 declared_max_(maximum) { | 486 declared_max_(maximum) { |
471 if (ranges) | 487 if (ranges) |
472 samples_.reset(new SampleVector(HashMetricName(name), ranges)); | 488 samples_.reset(new SampleVector(HashMetricName(name), ranges)); |
473 } | 489 } |
474 | 490 |
475 Histogram::Histogram(const std::string& name, | 491 Histogram::Histogram(const std::string& name, |
476 Sample minimum, | 492 Sample minimum, |
477 Sample maximum, | 493 Sample maximum, |
478 const BucketRanges* ranges, | 494 const BucketRanges* ranges, |
479 HistogramBase::AtomicCount* counts, | 495 HistogramBase::AtomicCount* counts, |
496 HistogramBase::AtomicCount* logged, | |
480 uint32_t counts_size, | 497 uint32_t counts_size, |
481 HistogramSamples::Metadata* meta) | 498 HistogramSamples::Metadata* meta) |
482 : HistogramBase(name), | 499 : HistogramBase(name), |
483 bucket_ranges_(ranges), | 500 bucket_ranges_(ranges), |
484 declared_min_(minimum), | 501 declared_min_(minimum), |
485 declared_max_(maximum) { | 502 declared_max_(maximum) { |
486 if (ranges) { | 503 if (ranges) { |
487 samples_.reset(new SampleVector(HashMetricName(name), | 504 samples_.reset(new SampleVector(HashMetricName(name), |
488 counts, counts_size, meta, ranges)); | 505 counts, counts_size, meta, ranges)); |
506 logged_.reset(new SampleVector(samples_->id(), | |
507 logged, counts_size, meta, ranges)); | |
489 } | 508 } |
490 } | 509 } |
491 | 510 |
492 Histogram::~Histogram() { | 511 Histogram::~Histogram() { |
493 } | 512 } |
494 | 513 |
495 bool Histogram::PrintEmptyBucket(uint32_t index) const { | 514 bool Histogram::PrintEmptyBucket(uint32_t index) const { |
496 return true; | 515 return true; |
497 } | 516 } |
498 | 517 |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
769 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count, | 788 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count, |
770 flags); | 789 flags); |
771 } | 790 } |
772 | 791 |
773 HistogramBase* LinearHistogram::PersistentGet( | 792 HistogramBase* LinearHistogram::PersistentGet( |
774 const std::string& name, | 793 const std::string& name, |
775 Sample minimum, | 794 Sample minimum, |
776 Sample maximum, | 795 Sample maximum, |
777 const BucketRanges* ranges, | 796 const BucketRanges* ranges, |
778 HistogramBase::AtomicCount* counts, | 797 HistogramBase::AtomicCount* counts, |
798 HistogramBase::AtomicCount* logged, | |
779 uint32_t counts_size, | 799 uint32_t counts_size, |
780 HistogramSamples::Metadata* meta) { | 800 HistogramSamples::Metadata* meta) { |
781 return new LinearHistogram(name, minimum, maximum, ranges, counts, | 801 return new LinearHistogram(name, minimum, maximum, ranges, counts, logged, |
782 counts_size, meta); | 802 counts_size, meta); |
783 } | 803 } |
784 | 804 |
785 HistogramBase* LinearHistogram::FactoryGetWithRangeDescription( | 805 HistogramBase* LinearHistogram::FactoryGetWithRangeDescription( |
786 const std::string& name, | 806 const std::string& name, |
787 Sample minimum, | 807 Sample minimum, |
788 Sample maximum, | 808 Sample maximum, |
789 uint32_t bucket_count, | 809 uint32_t bucket_count, |
790 int32_t flags, | 810 int32_t flags, |
791 const DescriptionPair descriptions[]) { | 811 const DescriptionPair descriptions[]) { |
(...skipping 14 matching lines...) Expand all Loading... | |
806 Sample maximum, | 826 Sample maximum, |
807 const BucketRanges* ranges) | 827 const BucketRanges* ranges) |
808 : Histogram(name, minimum, maximum, ranges) { | 828 : Histogram(name, minimum, maximum, ranges) { |
809 } | 829 } |
810 | 830 |
811 LinearHistogram::LinearHistogram(const std::string& name, | 831 LinearHistogram::LinearHistogram(const std::string& name, |
812 Sample minimum, | 832 Sample minimum, |
813 Sample maximum, | 833 Sample maximum, |
814 const BucketRanges* ranges, | 834 const BucketRanges* ranges, |
815 HistogramBase::AtomicCount* counts, | 835 HistogramBase::AtomicCount* counts, |
836 HistogramBase::AtomicCount* logged, | |
816 uint32_t counts_size, | 837 uint32_t counts_size, |
817 HistogramSamples::Metadata* meta) | 838 HistogramSamples::Metadata* meta) |
818 : Histogram(name, | 839 : Histogram(name, |
819 minimum, | 840 minimum, |
820 maximum, | 841 maximum, |
821 ranges, | 842 ranges, |
822 counts, | 843 counts, |
844 logged, | |
823 counts_size, | 845 counts_size, |
824 meta) {} | 846 meta) {} |
825 | 847 |
826 double LinearHistogram::GetBucketSize(Count current, uint32_t i) const { | 848 double LinearHistogram::GetBucketSize(Count current, uint32_t i) const { |
827 DCHECK_GT(ranges(i + 1), ranges(i)); | 849 DCHECK_GT(ranges(i + 1), ranges(i)); |
828 // Adjacent buckets with different widths would have "surprisingly" many (few) | 850 // Adjacent buckets with different widths would have "surprisingly" many (few) |
829 // samples in a histogram if we didn't normalize this way. | 851 // samples in a histogram if we didn't normalize this way. |
830 double denominator = ranges(i + 1) - ranges(i); | 852 double denominator = ranges(i + 1) - ranges(i); |
831 return current/denominator; | 853 return current/denominator; |
832 } | 854 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
912 } | 934 } |
913 | 935 |
914 HistogramBase* BooleanHistogram::FactoryGet(const char* name, int32_t flags) { | 936 HistogramBase* BooleanHistogram::FactoryGet(const char* name, int32_t flags) { |
915 return FactoryGet(std::string(name), flags); | 937 return FactoryGet(std::string(name), flags); |
916 } | 938 } |
917 | 939 |
918 HistogramBase* BooleanHistogram::PersistentGet( | 940 HistogramBase* BooleanHistogram::PersistentGet( |
919 const std::string& name, | 941 const std::string& name, |
920 const BucketRanges* ranges, | 942 const BucketRanges* ranges, |
921 HistogramBase::AtomicCount* counts, | 943 HistogramBase::AtomicCount* counts, |
944 HistogramBase::AtomicCount* logged, | |
922 HistogramSamples::Metadata* meta) { | 945 HistogramSamples::Metadata* meta) { |
923 return new BooleanHistogram(name, ranges, counts, meta); | 946 return new BooleanHistogram(name, ranges, counts, logged, meta); |
924 } | 947 } |
925 | 948 |
926 HistogramType BooleanHistogram::GetHistogramType() const { | 949 HistogramType BooleanHistogram::GetHistogramType() const { |
927 return BOOLEAN_HISTOGRAM; | 950 return BOOLEAN_HISTOGRAM; |
928 } | 951 } |
929 | 952 |
930 BooleanHistogram::BooleanHistogram(const std::string& name, | 953 BooleanHistogram::BooleanHistogram(const std::string& name, |
931 const BucketRanges* ranges) | 954 const BucketRanges* ranges) |
932 : LinearHistogram(name, 1, 2, ranges) {} | 955 : LinearHistogram(name, 1, 2, ranges) {} |
933 | 956 |
934 BooleanHistogram::BooleanHistogram(const std::string& name, | 957 BooleanHistogram::BooleanHistogram(const std::string& name, |
935 const BucketRanges* ranges, | 958 const BucketRanges* ranges, |
936 HistogramBase::AtomicCount* counts, | 959 HistogramBase::AtomicCount* counts, |
960 HistogramBase::AtomicCount* logged, | |
937 HistogramSamples::Metadata* meta) | 961 HistogramSamples::Metadata* meta) |
938 : LinearHistogram(name, 1, 2, ranges, counts, 2, meta) {} | 962 : LinearHistogram(name, 1, 2, ranges, counts, logged, 2, meta) {} |
939 | 963 |
940 HistogramBase* BooleanHistogram::DeserializeInfoImpl(PickleIterator* iter) { | 964 HistogramBase* BooleanHistogram::DeserializeInfoImpl(PickleIterator* iter) { |
941 std::string histogram_name; | 965 std::string histogram_name; |
942 int flags; | 966 int flags; |
943 int declared_min; | 967 int declared_min; |
944 int declared_max; | 968 int declared_max; |
945 uint32_t bucket_count; | 969 uint32_t bucket_count; |
946 uint32_t range_checksum; | 970 uint32_t range_checksum; |
947 | 971 |
948 if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min, | 972 if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min, |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1012 const char* name, | 1036 const char* name, |
1013 const std::vector<Sample>& custom_ranges, | 1037 const std::vector<Sample>& custom_ranges, |
1014 int32_t flags) { | 1038 int32_t flags) { |
1015 return FactoryGet(std::string(name), custom_ranges, flags); | 1039 return FactoryGet(std::string(name), custom_ranges, flags); |
1016 } | 1040 } |
1017 | 1041 |
1018 HistogramBase* CustomHistogram::PersistentGet( | 1042 HistogramBase* CustomHistogram::PersistentGet( |
1019 const std::string& name, | 1043 const std::string& name, |
1020 const BucketRanges* ranges, | 1044 const BucketRanges* ranges, |
1021 HistogramBase::AtomicCount* counts, | 1045 HistogramBase::AtomicCount* counts, |
1046 HistogramBase::AtomicCount* logged, | |
1022 uint32_t counts_size, | 1047 uint32_t counts_size, |
1023 HistogramSamples::Metadata* meta) { | 1048 HistogramSamples::Metadata* meta) { |
1024 return new CustomHistogram(name, ranges, counts, counts_size, meta); | 1049 return new CustomHistogram(name, ranges, counts, logged, counts_size, meta); |
1025 } | 1050 } |
1026 | 1051 |
1027 HistogramType CustomHistogram::GetHistogramType() const { | 1052 HistogramType CustomHistogram::GetHistogramType() const { |
1028 return CUSTOM_HISTOGRAM; | 1053 return CUSTOM_HISTOGRAM; |
1029 } | 1054 } |
1030 | 1055 |
1031 // static | 1056 // static |
1032 std::vector<Sample> CustomHistogram::ArrayToCustomRanges( | 1057 std::vector<Sample> CustomHistogram::ArrayToCustomRanges( |
1033 const Sample* values, uint32_t num_values) { | 1058 const Sample* values, uint32_t num_values) { |
1034 std::vector<Sample> all_values; | 1059 std::vector<Sample> all_values; |
(...skipping 11 matching lines...) Expand all Loading... | |
1046 CustomHistogram::CustomHistogram(const std::string& name, | 1071 CustomHistogram::CustomHistogram(const std::string& name, |
1047 const BucketRanges* ranges) | 1072 const BucketRanges* ranges) |
1048 : Histogram(name, | 1073 : Histogram(name, |
1049 ranges->range(1), | 1074 ranges->range(1), |
1050 ranges->range(ranges->bucket_count() - 1), | 1075 ranges->range(ranges->bucket_count() - 1), |
1051 ranges) {} | 1076 ranges) {} |
1052 | 1077 |
1053 CustomHistogram::CustomHistogram(const std::string& name, | 1078 CustomHistogram::CustomHistogram(const std::string& name, |
1054 const BucketRanges* ranges, | 1079 const BucketRanges* ranges, |
1055 HistogramBase::AtomicCount* counts, | 1080 HistogramBase::AtomicCount* counts, |
1081 HistogramBase::AtomicCount* logged, | |
1056 uint32_t counts_size, | 1082 uint32_t counts_size, |
1057 HistogramSamples::Metadata* meta) | 1083 HistogramSamples::Metadata* meta) |
1058 : Histogram(name, | 1084 : Histogram(name, |
1059 ranges->range(1), | 1085 ranges->range(1), |
1060 ranges->range(ranges->bucket_count() - 1), | 1086 ranges->range(ranges->bucket_count() - 1), |
1061 ranges, | 1087 ranges, |
1062 counts, | 1088 counts, |
1089 logged, | |
1063 counts_size, | 1090 counts_size, |
1064 meta) {} | 1091 meta) {} |
1065 | 1092 |
1066 bool CustomHistogram::SerializeInfoImpl(Pickle* pickle) const { | 1093 bool CustomHistogram::SerializeInfoImpl(Pickle* pickle) const { |
1067 if (!Histogram::SerializeInfoImpl(pickle)) | 1094 if (!Histogram::SerializeInfoImpl(pickle)) |
1068 return false; | 1095 return false; |
1069 | 1096 |
1070 // Serialize ranges. First and last ranges are alwasy 0 and INT_MAX, so don't | 1097 // Serialize ranges. First and last ranges are alwasy 0 and INT_MAX, so don't |
1071 // write them. | 1098 // write them. |
1072 for (uint32_t i = 1; i < bucket_ranges()->bucket_count(); ++i) { | 1099 for (uint32_t i = 1; i < bucket_ranges()->bucket_count(); ++i) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1119 Sample sample = custom_ranges[i]; | 1146 Sample sample = custom_ranges[i]; |
1120 if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1) | 1147 if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1) |
1121 return false; | 1148 return false; |
1122 if (sample != 0) | 1149 if (sample != 0) |
1123 has_valid_range = true; | 1150 has_valid_range = true; |
1124 } | 1151 } |
1125 return has_valid_range; | 1152 return has_valid_range; |
1126 } | 1153 } |
1127 | 1154 |
1128 } // namespace base | 1155 } // namespace base |
OLD | NEW |