Chromium Code Reviews| 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 |