Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Side by Side Diff: base/metrics/histogram.cc

Issue 2811713003: Embed a single sample in histogram metadata. (Closed)
Patch Set: rebased Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/metrics/histogram.h ('k') | base/metrics/histogram_samples.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 int32_t flags) { 268 int32_t flags) {
269 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count, 269 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count,
270 flags); 270 flags);
271 } 271 }
272 272
273 std::unique_ptr<HistogramBase> Histogram::PersistentCreate( 273 std::unique_ptr<HistogramBase> Histogram::PersistentCreate(
274 const std::string& name, 274 const std::string& name,
275 Sample minimum, 275 Sample minimum,
276 Sample maximum, 276 Sample maximum,
277 const BucketRanges* ranges, 277 const BucketRanges* ranges,
278 HistogramBase::AtomicCount* counts, 278 const DelayedPersistentAllocation& counts,
279 HistogramBase::AtomicCount* logged_counts, 279 const DelayedPersistentAllocation& logged_counts,
280 uint32_t counts_size,
281 HistogramSamples::Metadata* meta, 280 HistogramSamples::Metadata* meta,
282 HistogramSamples::Metadata* logged_meta) { 281 HistogramSamples::Metadata* logged_meta) {
283 return WrapUnique(new Histogram(name, minimum, maximum, ranges, counts, 282 return WrapUnique(new Histogram(name, minimum, maximum, ranges, counts,
284 logged_counts, counts_size, meta, 283 logged_counts, meta, logged_meta));
285 logged_meta));
286 } 284 }
287 285
288 // Calculate what range of values are held in each bucket. 286 // Calculate what range of values are held in each bucket.
289 // We have to be careful that we don't pick a ratio between starting points in 287 // We have to be careful that we don't pick a ratio between starting points in
290 // consecutive buckets that is sooo small, that the integer bounds are the same 288 // consecutive buckets that is sooo small, that the integer bounds are the same
291 // (effectively making one bucket get no values). We need to avoid: 289 // (effectively making one bucket get no values). We need to avoid:
292 // ranges(i) == ranges(i + 1) 290 // ranges(i) == ranges(i + 1)
293 // To avoid that, we just do a fine-grained bucket width as far as we need to 291 // To avoid that, we just do a fine-grained bucket width as far as we need to
294 // until we get a ratio that moves us along at least 2 units at a time. From 292 // until we get a ratio that moves us along at least 2 units at a time. From
295 // that bucket onward we do use the exponential growth of buckets. 293 // that bucket onward we do use the exponential growth of buckets.
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 declared_min_(minimum), 503 declared_min_(minimum),
506 declared_max_(maximum) { 504 declared_max_(maximum) {
507 if (ranges) 505 if (ranges)
508 samples_.reset(new SampleVector(HashMetricName(name), ranges)); 506 samples_.reset(new SampleVector(HashMetricName(name), ranges));
509 } 507 }
510 508
511 Histogram::Histogram(const std::string& name, 509 Histogram::Histogram(const std::string& name,
512 Sample minimum, 510 Sample minimum,
513 Sample maximum, 511 Sample maximum,
514 const BucketRanges* ranges, 512 const BucketRanges* ranges,
515 HistogramBase::AtomicCount* counts, 513 const DelayedPersistentAllocation& counts,
516 HistogramBase::AtomicCount* logged_counts, 514 const DelayedPersistentAllocation& logged_counts,
517 uint32_t counts_size,
518 HistogramSamples::Metadata* meta, 515 HistogramSamples::Metadata* meta,
519 HistogramSamples::Metadata* logged_meta) 516 HistogramSamples::Metadata* logged_meta)
520 : HistogramBase(name), 517 : HistogramBase(name),
521 bucket_ranges_(ranges), 518 bucket_ranges_(ranges),
522 declared_min_(minimum), 519 declared_min_(minimum),
523 declared_max_(maximum) { 520 declared_max_(maximum) {
524 if (ranges) { 521 if (ranges) {
525 samples_.reset(new SampleVector(HashMetricName(name), 522 samples_.reset(
526 counts, counts_size, meta, ranges)); 523 new PersistentSampleVector(HashMetricName(name), ranges, meta, counts));
527 logged_samples_.reset(new SampleVector(samples_->id(), logged_counts, 524 logged_samples_.reset(new PersistentSampleVector(
528 counts_size, logged_meta, ranges)); 525 samples_->id(), ranges, logged_meta, logged_counts));
529 } 526 }
530 } 527 }
531 528
532 Histogram::~Histogram() { 529 Histogram::~Histogram() {
533 } 530 }
534 531
535 bool Histogram::PrintEmptyBucket(uint32_t index) const { 532 bool Histogram::PrintEmptyBucket(uint32_t index) const {
536 return true; 533 return true;
537 } 534 }
538 535
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 double current_size = GetBucketSize(current, i); 646 double current_size = GetBucketSize(current, i);
650 if (graph_it) 647 if (graph_it)
651 WriteAsciiBucketGraph(current_size, max_size, output); 648 WriteAsciiBucketGraph(current_size, max_size, output);
652 WriteAsciiBucketContext(past, current, remaining, i, output); 649 WriteAsciiBucketContext(past, current, remaining, i, output);
653 output->append(newline); 650 output->append(newline);
654 past += current; 651 past += current;
655 } 652 }
656 DCHECK_EQ(sample_count, past); 653 DCHECK_EQ(sample_count, past);
657 } 654 }
658 655
659 double Histogram::GetPeakBucketSize(const SampleVector& samples) const { 656 double Histogram::GetPeakBucketSize(const SampleVectorBase& samples) const {
660 double max = 0; 657 double max = 0;
661 for (uint32_t i = 0; i < bucket_count() ; ++i) { 658 for (uint32_t i = 0; i < bucket_count() ; ++i) {
662 double current_size = GetBucketSize(samples.GetCountAtIndex(i), i); 659 double current_size = GetBucketSize(samples.GetCountAtIndex(i), i);
663 if (current_size > max) 660 if (current_size > max)
664 max = current_size; 661 max = current_size;
665 } 662 }
666 return max; 663 return max;
667 } 664 }
668 665
669 void Histogram::WriteAsciiHeader(const SampleVector& samples, 666 void Histogram::WriteAsciiHeader(const SampleVectorBase& samples,
670 Count sample_count, 667 Count sample_count,
671 std::string* output) const { 668 std::string* output) const {
672 StringAppendF(output, 669 StringAppendF(output,
673 "Histogram: %s recorded %d samples", 670 "Histogram: %s recorded %d samples",
674 histogram_name().c_str(), 671 histogram_name().c_str(),
675 sample_count); 672 sample_count);
676 if (sample_count == 0) { 673 if (sample_count == 0) {
677 DCHECK_EQ(samples.sum(), 0); 674 DCHECK_EQ(samples.sum(), 0);
678 } else { 675 } else {
679 double mean = static_cast<float>(samples.sum()) / sample_count; 676 double mean = static_cast<float>(samples.sum()) / sample_count;
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 int32_t flags) { 805 int32_t flags) {
809 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count, 806 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count,
810 flags); 807 flags);
811 } 808 }
812 809
813 std::unique_ptr<HistogramBase> LinearHistogram::PersistentCreate( 810 std::unique_ptr<HistogramBase> LinearHistogram::PersistentCreate(
814 const std::string& name, 811 const std::string& name,
815 Sample minimum, 812 Sample minimum,
816 Sample maximum, 813 Sample maximum,
817 const BucketRanges* ranges, 814 const BucketRanges* ranges,
818 HistogramBase::AtomicCount* counts, 815 const DelayedPersistentAllocation& counts,
819 HistogramBase::AtomicCount* logged_counts, 816 const DelayedPersistentAllocation& logged_counts,
820 uint32_t counts_size,
821 HistogramSamples::Metadata* meta, 817 HistogramSamples::Metadata* meta,
822 HistogramSamples::Metadata* logged_meta) { 818 HistogramSamples::Metadata* logged_meta) {
823 return WrapUnique(new LinearHistogram(name, minimum, maximum, ranges, 819 return WrapUnique(new LinearHistogram(name, minimum, maximum, ranges, counts,
824 counts, logged_counts, 820 logged_counts, meta, logged_meta));
825 counts_size, meta, logged_meta));
826 } 821 }
827 822
828 HistogramBase* LinearHistogram::FactoryGetWithRangeDescription( 823 HistogramBase* LinearHistogram::FactoryGetWithRangeDescription(
829 const std::string& name, 824 const std::string& name,
830 Sample minimum, 825 Sample minimum,
831 Sample maximum, 826 Sample maximum,
832 uint32_t bucket_count, 827 uint32_t bucket_count,
833 int32_t flags, 828 int32_t flags,
834 const DescriptionPair descriptions[]) { 829 const DescriptionPair descriptions[]) {
835 bool valid_arguments = Histogram::InspectConstructionArguments( 830 bool valid_arguments = Histogram::InspectConstructionArguments(
836 name, &minimum, &maximum, &bucket_count); 831 name, &minimum, &maximum, &bucket_count);
837 DCHECK(valid_arguments); 832 DCHECK(valid_arguments);
838 833
839 return Factory(name, minimum, maximum, bucket_count, flags, descriptions) 834 return Factory(name, minimum, maximum, bucket_count, flags, descriptions)
840 .Build(); 835 .Build();
841 } 836 }
842 837
843 HistogramType LinearHistogram::GetHistogramType() const { 838 HistogramType LinearHistogram::GetHistogramType() const {
844 return LINEAR_HISTOGRAM; 839 return LINEAR_HISTOGRAM;
845 } 840 }
846 841
847 LinearHistogram::LinearHistogram(const std::string& name, 842 LinearHistogram::LinearHistogram(const std::string& name,
848 Sample minimum, 843 Sample minimum,
849 Sample maximum, 844 Sample maximum,
850 const BucketRanges* ranges) 845 const BucketRanges* ranges)
851 : Histogram(name, minimum, maximum, ranges) { 846 : Histogram(name, minimum, maximum, ranges) {
852 } 847 }
853 848
854 LinearHistogram::LinearHistogram(const std::string& name, 849 LinearHistogram::LinearHistogram(
855 Sample minimum, 850 const std::string& name,
856 Sample maximum, 851 Sample minimum,
857 const BucketRanges* ranges, 852 Sample maximum,
858 HistogramBase::AtomicCount* counts, 853 const BucketRanges* ranges,
859 HistogramBase::AtomicCount* logged_counts, 854 const DelayedPersistentAllocation& counts,
860 uint32_t counts_size, 855 const DelayedPersistentAllocation& logged_counts,
861 HistogramSamples::Metadata* meta, 856 HistogramSamples::Metadata* meta,
862 HistogramSamples::Metadata* logged_meta) 857 HistogramSamples::Metadata* logged_meta)
863 : Histogram(name, minimum, maximum, ranges, counts, logged_counts, 858 : Histogram(name,
864 counts_size, meta, logged_meta) {} 859 minimum,
860 maximum,
861 ranges,
862 counts,
863 logged_counts,
864 meta,
865 logged_meta) {}
865 866
866 double LinearHistogram::GetBucketSize(Count current, uint32_t i) const { 867 double LinearHistogram::GetBucketSize(Count current, uint32_t i) const {
867 DCHECK_GT(ranges(i + 1), ranges(i)); 868 DCHECK_GT(ranges(i + 1), ranges(i));
868 // Adjacent buckets with different widths would have "surprisingly" many (few) 869 // Adjacent buckets with different widths would have "surprisingly" many (few)
869 // samples in a histogram if we didn't normalize this way. 870 // samples in a histogram if we didn't normalize this way.
870 double denominator = ranges(i + 1) - ranges(i); 871 double denominator = ranges(i + 1) - ranges(i);
871 return current/denominator; 872 return current/denominator;
872 } 873 }
873 874
874 const std::string LinearHistogram::GetAsciiBucketRange(uint32_t i) const { 875 const std::string LinearHistogram::GetAsciiBucketRange(uint32_t i) const {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
954 return Factory(name, flags).Build(); 955 return Factory(name, flags).Build();
955 } 956 }
956 957
957 HistogramBase* BooleanHistogram::FactoryGet(const char* name, int32_t flags) { 958 HistogramBase* BooleanHistogram::FactoryGet(const char* name, int32_t flags) {
958 return FactoryGet(std::string(name), flags); 959 return FactoryGet(std::string(name), flags);
959 } 960 }
960 961
961 std::unique_ptr<HistogramBase> BooleanHistogram::PersistentCreate( 962 std::unique_ptr<HistogramBase> BooleanHistogram::PersistentCreate(
962 const std::string& name, 963 const std::string& name,
963 const BucketRanges* ranges, 964 const BucketRanges* ranges,
964 HistogramBase::AtomicCount* counts, 965 const DelayedPersistentAllocation& counts,
965 HistogramBase::AtomicCount* logged_counts, 966 const DelayedPersistentAllocation& logged_counts,
966 HistogramSamples::Metadata* meta, 967 HistogramSamples::Metadata* meta,
967 HistogramSamples::Metadata* logged_meta) { 968 HistogramSamples::Metadata* logged_meta) {
968 return WrapUnique(new BooleanHistogram( 969 return WrapUnique(new BooleanHistogram(name, ranges, counts, logged_counts,
969 name, ranges, counts, logged_counts, meta, logged_meta)); 970 meta, logged_meta));
970 } 971 }
971 972
972 HistogramType BooleanHistogram::GetHistogramType() const { 973 HistogramType BooleanHistogram::GetHistogramType() const {
973 return BOOLEAN_HISTOGRAM; 974 return BOOLEAN_HISTOGRAM;
974 } 975 }
975 976
976 BooleanHistogram::BooleanHistogram(const std::string& name, 977 BooleanHistogram::BooleanHistogram(const std::string& name,
977 const BucketRanges* ranges) 978 const BucketRanges* ranges)
978 : LinearHistogram(name, 1, 2, ranges) {} 979 : LinearHistogram(name, 1, 2, ranges) {}
979 980
980 BooleanHistogram::BooleanHistogram(const std::string& name, 981 BooleanHistogram::BooleanHistogram(
981 const BucketRanges* ranges, 982 const std::string& name,
982 HistogramBase::AtomicCount* counts, 983 const BucketRanges* ranges,
983 HistogramBase::AtomicCount* logged_counts, 984 const DelayedPersistentAllocation& counts,
984 HistogramSamples::Metadata* meta, 985 const DelayedPersistentAllocation& logged_counts,
985 HistogramSamples::Metadata* logged_meta) 986 HistogramSamples::Metadata* meta,
986 : LinearHistogram(name, 1, 2, ranges, counts, logged_counts, 2, meta, 987 HistogramSamples::Metadata* logged_meta)
988 : LinearHistogram(name,
989 1,
990 2,
991 ranges,
992 counts,
993 logged_counts,
994 meta,
987 logged_meta) {} 995 logged_meta) {}
988 996
989 HistogramBase* BooleanHistogram::DeserializeInfoImpl(PickleIterator* iter) { 997 HistogramBase* BooleanHistogram::DeserializeInfoImpl(PickleIterator* iter) {
990 std::string histogram_name; 998 std::string histogram_name;
991 int flags; 999 int flags;
992 int declared_min; 1000 int declared_min;
993 int declared_max; 1001 int declared_max;
994 uint32_t bucket_count; 1002 uint32_t bucket_count;
995 uint32_t range_checksum; 1003 uint32_t range_checksum;
996 1004
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1061 HistogramBase* CustomHistogram::FactoryGet( 1069 HistogramBase* CustomHistogram::FactoryGet(
1062 const char* name, 1070 const char* name,
1063 const std::vector<Sample>& custom_ranges, 1071 const std::vector<Sample>& custom_ranges,
1064 int32_t flags) { 1072 int32_t flags) {
1065 return FactoryGet(std::string(name), custom_ranges, flags); 1073 return FactoryGet(std::string(name), custom_ranges, flags);
1066 } 1074 }
1067 1075
1068 std::unique_ptr<HistogramBase> CustomHistogram::PersistentCreate( 1076 std::unique_ptr<HistogramBase> CustomHistogram::PersistentCreate(
1069 const std::string& name, 1077 const std::string& name,
1070 const BucketRanges* ranges, 1078 const BucketRanges* ranges,
1071 HistogramBase::AtomicCount* counts, 1079 const DelayedPersistentAllocation& counts,
1072 HistogramBase::AtomicCount* logged_counts, 1080 const DelayedPersistentAllocation& logged_counts,
1073 uint32_t counts_size,
1074 HistogramSamples::Metadata* meta, 1081 HistogramSamples::Metadata* meta,
1075 HistogramSamples::Metadata* logged_meta) { 1082 HistogramSamples::Metadata* logged_meta) {
1076 return WrapUnique(new CustomHistogram( 1083 return WrapUnique(new CustomHistogram(name, ranges, counts, logged_counts,
1077 name, ranges, counts, logged_counts, counts_size, meta, logged_meta)); 1084 meta, logged_meta));
1078 } 1085 }
1079 1086
1080 HistogramType CustomHistogram::GetHistogramType() const { 1087 HistogramType CustomHistogram::GetHistogramType() const {
1081 return CUSTOM_HISTOGRAM; 1088 return CUSTOM_HISTOGRAM;
1082 } 1089 }
1083 1090
1084 // static 1091 // static
1085 std::vector<Sample> CustomHistogram::ArrayToCustomRanges( 1092 std::vector<Sample> CustomHistogram::ArrayToCustomRanges(
1086 const Sample* values, uint32_t num_values) { 1093 const Sample* values, uint32_t num_values) {
1087 std::vector<Sample> all_values; 1094 std::vector<Sample> all_values;
1088 for (uint32_t i = 0; i < num_values; ++i) { 1095 for (uint32_t i = 0; i < num_values; ++i) {
1089 Sample value = values[i]; 1096 Sample value = values[i];
1090 all_values.push_back(value); 1097 all_values.push_back(value);
1091 1098
1092 // Ensure that a guard bucket is added. If we end up with duplicate 1099 // Ensure that a guard bucket is added. If we end up with duplicate
1093 // values, FactoryGet will take care of removing them. 1100 // values, FactoryGet will take care of removing them.
1094 all_values.push_back(value + 1); 1101 all_values.push_back(value + 1);
1095 } 1102 }
1096 return all_values; 1103 return all_values;
1097 } 1104 }
1098 1105
1099 CustomHistogram::CustomHistogram(const std::string& name, 1106 CustomHistogram::CustomHistogram(const std::string& name,
1100 const BucketRanges* ranges) 1107 const BucketRanges* ranges)
1101 : Histogram(name, 1108 : Histogram(name,
1102 ranges->range(1), 1109 ranges->range(1),
1103 ranges->range(ranges->bucket_count() - 1), 1110 ranges->range(ranges->bucket_count() - 1),
1104 ranges) {} 1111 ranges) {}
1105 1112
1106 CustomHistogram::CustomHistogram(const std::string& name, 1113 CustomHistogram::CustomHistogram(
1107 const BucketRanges* ranges, 1114 const std::string& name,
1108 HistogramBase::AtomicCount* counts, 1115 const BucketRanges* ranges,
1109 HistogramBase::AtomicCount* logged_counts, 1116 const DelayedPersistentAllocation& counts,
1110 uint32_t counts_size, 1117 const DelayedPersistentAllocation& logged_counts,
1111 HistogramSamples::Metadata* meta, 1118 HistogramSamples::Metadata* meta,
1112 HistogramSamples::Metadata* logged_meta) 1119 HistogramSamples::Metadata* logged_meta)
1113 : Histogram(name, 1120 : Histogram(name,
1114 ranges->range(1), 1121 ranges->range(1),
1115 ranges->range(ranges->bucket_count() - 1), 1122 ranges->range(ranges->bucket_count() - 1),
1116 ranges, 1123 ranges,
1117 counts, 1124 counts,
1118 logged_counts, 1125 logged_counts,
1119 counts_size,
1120 meta, 1126 meta,
1121 logged_meta) {} 1127 logged_meta) {}
1122 1128
1123 bool CustomHistogram::SerializeInfoImpl(Pickle* pickle) const { 1129 bool CustomHistogram::SerializeInfoImpl(Pickle* pickle) const {
1124 if (!Histogram::SerializeInfoImpl(pickle)) 1130 if (!Histogram::SerializeInfoImpl(pickle))
1125 return false; 1131 return false;
1126 1132
1127 // Serialize ranges. First and last ranges are alwasy 0 and INT_MAX, so don't 1133 // Serialize ranges. First and last ranges are alwasy 0 and INT_MAX, so don't
1128 // write them. 1134 // write them.
1129 for (uint32_t i = 1; i < bucket_ranges()->bucket_count(); ++i) { 1135 for (uint32_t i = 1; i < bucket_ranges()->bucket_count(); ++i) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1178 Sample sample = custom_ranges[i]; 1184 Sample sample = custom_ranges[i];
1179 if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1) 1185 if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1)
1180 return false; 1186 return false;
1181 if (sample != 0) 1187 if (sample != 0)
1182 has_valid_range = true; 1188 has_valid_range = true;
1183 } 1189 }
1184 return has_valid_range; 1190 return has_valid_range;
1185 } 1191 }
1186 1192
1187 } // namespace base 1193 } // namespace base
OLDNEW
« no previous file with comments | « base/metrics/histogram.h ('k') | base/metrics/histogram_samples.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698