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

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

Issue 2811713003: Embed a single sample in histogram metadata. (Closed)
Patch Set: rebased Created 3 years, 7 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 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 int32_t flags) { 269 int32_t flags) {
270 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count, 270 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count,
271 flags); 271 flags);
272 } 272 }
273 273
274 std::unique_ptr<HistogramBase> Histogram::PersistentCreate( 274 std::unique_ptr<HistogramBase> Histogram::PersistentCreate(
275 const std::string& name, 275 const std::string& name,
276 Sample minimum, 276 Sample minimum,
277 Sample maximum, 277 Sample maximum,
278 const BucketRanges* ranges, 278 const BucketRanges* ranges,
279 HistogramBase::AtomicCount* counts, 279 const DelayedPersistentAllocation& counts,
280 HistogramBase::AtomicCount* logged_counts, 280 const DelayedPersistentAllocation& logged_counts,
281 uint32_t counts_size,
282 HistogramSamples::Metadata* meta, 281 HistogramSamples::Metadata* meta,
283 HistogramSamples::Metadata* logged_meta) { 282 HistogramSamples::Metadata* logged_meta) {
284 return WrapUnique(new Histogram(name, minimum, maximum, ranges, counts, 283 return WrapUnique(new Histogram(name, minimum, maximum, ranges, counts,
285 logged_counts, counts_size, meta, 284 logged_counts, meta, logged_meta));
286 logged_meta));
287 } 285 }
288 286
289 // Calculate what range of values are held in each bucket. 287 // Calculate what range of values are held in each bucket.
290 // We have to be careful that we don't pick a ratio between starting points in 288 // We have to be careful that we don't pick a ratio between starting points in
291 // consecutive buckets that is sooo small, that the integer bounds are the same 289 // consecutive buckets that is sooo small, that the integer bounds are the same
292 // (effectively making one bucket get no values). We need to avoid: 290 // (effectively making one bucket get no values). We need to avoid:
293 // ranges(i) == ranges(i + 1) 291 // ranges(i) == ranges(i + 1)
294 // To avoid that, we just do a fine-grained bucket width as far as we need to 292 // To avoid that, we just do a fine-grained bucket width as far as we need to
295 // until we get a ratio that moves us along at least 2 units at a time. From 293 // until we get a ratio that moves us along at least 2 units at a time. From
296 // that bucket onward we do use the exponential growth of buckets. 294 // that bucket onward we do use the exponential growth of buckets.
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 declared_min_(minimum), 522 declared_min_(minimum),
525 declared_max_(maximum) { 523 declared_max_(maximum) {
526 if (ranges) 524 if (ranges)
527 samples_.reset(new SampleVector(HashMetricName(name), ranges)); 525 samples_.reset(new SampleVector(HashMetricName(name), ranges));
528 } 526 }
529 527
530 Histogram::Histogram(const std::string& name, 528 Histogram::Histogram(const std::string& name,
531 Sample minimum, 529 Sample minimum,
532 Sample maximum, 530 Sample maximum,
533 const BucketRanges* ranges, 531 const BucketRanges* ranges,
534 HistogramBase::AtomicCount* counts, 532 const DelayedPersistentAllocation& counts,
535 HistogramBase::AtomicCount* logged_counts, 533 const DelayedPersistentAllocation& logged_counts,
536 uint32_t counts_size,
537 HistogramSamples::Metadata* meta, 534 HistogramSamples::Metadata* meta,
538 HistogramSamples::Metadata* logged_meta) 535 HistogramSamples::Metadata* logged_meta)
539 : HistogramBase(name), 536 : HistogramBase(name),
540 bucket_ranges_(ranges), 537 bucket_ranges_(ranges),
541 declared_min_(minimum), 538 declared_min_(minimum),
542 declared_max_(maximum) { 539 declared_max_(maximum) {
543 if (ranges) { 540 if (ranges) {
544 samples_.reset(new SampleVector(HashMetricName(name), 541 samples_.reset(
545 counts, counts_size, meta, ranges)); 542 new PersistentSampleVector(HashMetricName(name), ranges, meta, counts));
546 logged_samples_.reset(new SampleVector(samples_->id(), logged_counts, 543 logged_samples_.reset(new PersistentSampleVector(
547 counts_size, logged_meta, ranges)); 544 samples_->id(), ranges, logged_meta, logged_counts));
548 } 545 }
549 } 546 }
550 547
551 Histogram::~Histogram() { 548 Histogram::~Histogram() {
552 } 549 }
553 550
554 bool Histogram::PrintEmptyBucket(uint32_t index) const { 551 bool Histogram::PrintEmptyBucket(uint32_t index) const {
555 return true; 552 return true;
556 } 553 }
557 554
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 double current_size = GetBucketSize(current, i); 665 double current_size = GetBucketSize(current, i);
669 if (graph_it) 666 if (graph_it)
670 WriteAsciiBucketGraph(current_size, max_size, output); 667 WriteAsciiBucketGraph(current_size, max_size, output);
671 WriteAsciiBucketContext(past, current, remaining, i, output); 668 WriteAsciiBucketContext(past, current, remaining, i, output);
672 output->append(newline); 669 output->append(newline);
673 past += current; 670 past += current;
674 } 671 }
675 DCHECK_EQ(sample_count, past); 672 DCHECK_EQ(sample_count, past);
676 } 673 }
677 674
678 double Histogram::GetPeakBucketSize(const SampleVector& samples) const { 675 double Histogram::GetPeakBucketSize(const SampleVectorBase& samples) const {
679 double max = 0; 676 double max = 0;
680 for (uint32_t i = 0; i < bucket_count() ; ++i) { 677 for (uint32_t i = 0; i < bucket_count() ; ++i) {
681 double current_size = GetBucketSize(samples.GetCountAtIndex(i), i); 678 double current_size = GetBucketSize(samples.GetCountAtIndex(i), i);
682 if (current_size > max) 679 if (current_size > max)
683 max = current_size; 680 max = current_size;
684 } 681 }
685 return max; 682 return max;
686 } 683 }
687 684
688 void Histogram::WriteAsciiHeader(const SampleVector& samples, 685 void Histogram::WriteAsciiHeader(const SampleVectorBase& samples,
689 Count sample_count, 686 Count sample_count,
690 std::string* output) const { 687 std::string* output) const {
691 StringAppendF(output, 688 StringAppendF(output,
692 "Histogram: %s recorded %d samples", 689 "Histogram: %s recorded %d samples",
693 histogram_name().c_str(), 690 histogram_name().c_str(),
694 sample_count); 691 sample_count);
695 if (sample_count == 0) { 692 if (sample_count == 0) {
696 DCHECK_EQ(samples.sum(), 0); 693 DCHECK_EQ(samples.sum(), 0);
697 } else { 694 } else {
698 double mean = static_cast<float>(samples.sum()) / sample_count; 695 double mean = static_cast<float>(samples.sum()) / sample_count;
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 int32_t flags) { 824 int32_t flags) {
828 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count, 825 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count,
829 flags); 826 flags);
830 } 827 }
831 828
832 std::unique_ptr<HistogramBase> LinearHistogram::PersistentCreate( 829 std::unique_ptr<HistogramBase> LinearHistogram::PersistentCreate(
833 const std::string& name, 830 const std::string& name,
834 Sample minimum, 831 Sample minimum,
835 Sample maximum, 832 Sample maximum,
836 const BucketRanges* ranges, 833 const BucketRanges* ranges,
837 HistogramBase::AtomicCount* counts, 834 const DelayedPersistentAllocation& counts,
838 HistogramBase::AtomicCount* logged_counts, 835 const DelayedPersistentAllocation& logged_counts,
839 uint32_t counts_size,
840 HistogramSamples::Metadata* meta, 836 HistogramSamples::Metadata* meta,
841 HistogramSamples::Metadata* logged_meta) { 837 HistogramSamples::Metadata* logged_meta) {
842 return WrapUnique(new LinearHistogram(name, minimum, maximum, ranges, 838 return WrapUnique(new LinearHistogram(name, minimum, maximum, ranges, counts,
843 counts, logged_counts, 839 logged_counts, meta, logged_meta));
844 counts_size, meta, logged_meta));
845 } 840 }
846 841
847 HistogramBase* LinearHistogram::FactoryGetWithRangeDescription( 842 HistogramBase* LinearHistogram::FactoryGetWithRangeDescription(
848 const std::string& name, 843 const std::string& name,
849 Sample minimum, 844 Sample minimum,
850 Sample maximum, 845 Sample maximum,
851 uint32_t bucket_count, 846 uint32_t bucket_count,
852 int32_t flags, 847 int32_t flags,
853 const DescriptionPair descriptions[]) { 848 const DescriptionPair descriptions[]) {
854 bool valid_arguments = Histogram::InspectConstructionArguments( 849 bool valid_arguments = Histogram::InspectConstructionArguments(
855 name, &minimum, &maximum, &bucket_count); 850 name, &minimum, &maximum, &bucket_count);
856 DCHECK(valid_arguments); 851 DCHECK(valid_arguments);
857 852
858 return Factory(name, minimum, maximum, bucket_count, flags, descriptions) 853 return Factory(name, minimum, maximum, bucket_count, flags, descriptions)
859 .Build(); 854 .Build();
860 } 855 }
861 856
862 HistogramType LinearHistogram::GetHistogramType() const { 857 HistogramType LinearHistogram::GetHistogramType() const {
863 return LINEAR_HISTOGRAM; 858 return LINEAR_HISTOGRAM;
864 } 859 }
865 860
866 LinearHistogram::LinearHistogram(const std::string& name, 861 LinearHistogram::LinearHistogram(const std::string& name,
867 Sample minimum, 862 Sample minimum,
868 Sample maximum, 863 Sample maximum,
869 const BucketRanges* ranges) 864 const BucketRanges* ranges)
870 : Histogram(name, minimum, maximum, ranges) { 865 : Histogram(name, minimum, maximum, ranges) {
871 } 866 }
872 867
873 LinearHistogram::LinearHistogram(const std::string& name, 868 LinearHistogram::LinearHistogram(
874 Sample minimum, 869 const std::string& name,
875 Sample maximum, 870 Sample minimum,
876 const BucketRanges* ranges, 871 Sample maximum,
877 HistogramBase::AtomicCount* counts, 872 const BucketRanges* ranges,
878 HistogramBase::AtomicCount* logged_counts, 873 const DelayedPersistentAllocation& counts,
879 uint32_t counts_size, 874 const DelayedPersistentAllocation& logged_counts,
880 HistogramSamples::Metadata* meta, 875 HistogramSamples::Metadata* meta,
881 HistogramSamples::Metadata* logged_meta) 876 HistogramSamples::Metadata* logged_meta)
882 : Histogram(name, minimum, maximum, ranges, counts, logged_counts, 877 : Histogram(name,
883 counts_size, meta, logged_meta) {} 878 minimum,
879 maximum,
880 ranges,
881 counts,
882 logged_counts,
883 meta,
884 logged_meta) {}
884 885
885 double LinearHistogram::GetBucketSize(Count current, uint32_t i) const { 886 double LinearHistogram::GetBucketSize(Count current, uint32_t i) const {
886 DCHECK_GT(ranges(i + 1), ranges(i)); 887 DCHECK_GT(ranges(i + 1), ranges(i));
887 // Adjacent buckets with different widths would have "surprisingly" many (few) 888 // Adjacent buckets with different widths would have "surprisingly" many (few)
888 // samples in a histogram if we didn't normalize this way. 889 // samples in a histogram if we didn't normalize this way.
889 double denominator = ranges(i + 1) - ranges(i); 890 double denominator = ranges(i + 1) - ranges(i);
890 return current/denominator; 891 return current/denominator;
891 } 892 }
892 893
893 const std::string LinearHistogram::GetAsciiBucketRange(uint32_t i) const { 894 const std::string LinearHistogram::GetAsciiBucketRange(uint32_t i) const {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
973 return Factory(name, flags).Build(); 974 return Factory(name, flags).Build();
974 } 975 }
975 976
976 HistogramBase* BooleanHistogram::FactoryGet(const char* name, int32_t flags) { 977 HistogramBase* BooleanHistogram::FactoryGet(const char* name, int32_t flags) {
977 return FactoryGet(std::string(name), flags); 978 return FactoryGet(std::string(name), flags);
978 } 979 }
979 980
980 std::unique_ptr<HistogramBase> BooleanHistogram::PersistentCreate( 981 std::unique_ptr<HistogramBase> BooleanHistogram::PersistentCreate(
981 const std::string& name, 982 const std::string& name,
982 const BucketRanges* ranges, 983 const BucketRanges* ranges,
983 HistogramBase::AtomicCount* counts, 984 const DelayedPersistentAllocation& counts,
984 HistogramBase::AtomicCount* logged_counts, 985 const DelayedPersistentAllocation& logged_counts,
985 HistogramSamples::Metadata* meta, 986 HistogramSamples::Metadata* meta,
986 HistogramSamples::Metadata* logged_meta) { 987 HistogramSamples::Metadata* logged_meta) {
987 return WrapUnique(new BooleanHistogram( 988 return WrapUnique(new BooleanHistogram(name, ranges, counts, logged_counts,
988 name, ranges, counts, logged_counts, meta, logged_meta)); 989 meta, logged_meta));
989 } 990 }
990 991
991 HistogramType BooleanHistogram::GetHistogramType() const { 992 HistogramType BooleanHistogram::GetHistogramType() const {
992 return BOOLEAN_HISTOGRAM; 993 return BOOLEAN_HISTOGRAM;
993 } 994 }
994 995
995 BooleanHistogram::BooleanHistogram(const std::string& name, 996 BooleanHistogram::BooleanHistogram(const std::string& name,
996 const BucketRanges* ranges) 997 const BucketRanges* ranges)
997 : LinearHistogram(name, 1, 2, ranges) {} 998 : LinearHistogram(name, 1, 2, ranges) {}
998 999
999 BooleanHistogram::BooleanHistogram(const std::string& name, 1000 BooleanHistogram::BooleanHistogram(
1000 const BucketRanges* ranges, 1001 const std::string& name,
1001 HistogramBase::AtomicCount* counts, 1002 const BucketRanges* ranges,
1002 HistogramBase::AtomicCount* logged_counts, 1003 const DelayedPersistentAllocation& counts,
1003 HistogramSamples::Metadata* meta, 1004 const DelayedPersistentAllocation& logged_counts,
1004 HistogramSamples::Metadata* logged_meta) 1005 HistogramSamples::Metadata* meta,
1005 : LinearHistogram(name, 1, 2, ranges, counts, logged_counts, 2, meta, 1006 HistogramSamples::Metadata* logged_meta)
1007 : LinearHistogram(name,
1008 1,
1009 2,
1010 ranges,
1011 counts,
1012 logged_counts,
1013 meta,
1006 logged_meta) {} 1014 logged_meta) {}
1007 1015
1008 HistogramBase* BooleanHistogram::DeserializeInfoImpl(PickleIterator* iter) { 1016 HistogramBase* BooleanHistogram::DeserializeInfoImpl(PickleIterator* iter) {
1009 std::string histogram_name; 1017 std::string histogram_name;
1010 int flags; 1018 int flags;
1011 int declared_min; 1019 int declared_min;
1012 int declared_max; 1020 int declared_max;
1013 uint32_t bucket_count; 1021 uint32_t bucket_count;
1014 uint32_t range_checksum; 1022 uint32_t range_checksum;
1015 1023
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 HistogramBase* CustomHistogram::FactoryGet( 1088 HistogramBase* CustomHistogram::FactoryGet(
1081 const char* name, 1089 const char* name,
1082 const std::vector<Sample>& custom_ranges, 1090 const std::vector<Sample>& custom_ranges,
1083 int32_t flags) { 1091 int32_t flags) {
1084 return FactoryGet(std::string(name), custom_ranges, flags); 1092 return FactoryGet(std::string(name), custom_ranges, flags);
1085 } 1093 }
1086 1094
1087 std::unique_ptr<HistogramBase> CustomHistogram::PersistentCreate( 1095 std::unique_ptr<HistogramBase> CustomHistogram::PersistentCreate(
1088 const std::string& name, 1096 const std::string& name,
1089 const BucketRanges* ranges, 1097 const BucketRanges* ranges,
1090 HistogramBase::AtomicCount* counts, 1098 const DelayedPersistentAllocation& counts,
1091 HistogramBase::AtomicCount* logged_counts, 1099 const DelayedPersistentAllocation& logged_counts,
1092 uint32_t counts_size,
1093 HistogramSamples::Metadata* meta, 1100 HistogramSamples::Metadata* meta,
1094 HistogramSamples::Metadata* logged_meta) { 1101 HistogramSamples::Metadata* logged_meta) {
1095 return WrapUnique(new CustomHistogram( 1102 return WrapUnique(new CustomHistogram(name, ranges, counts, logged_counts,
1096 name, ranges, counts, logged_counts, counts_size, meta, logged_meta)); 1103 meta, logged_meta));
1097 } 1104 }
1098 1105
1099 HistogramType CustomHistogram::GetHistogramType() const { 1106 HistogramType CustomHistogram::GetHistogramType() const {
1100 return CUSTOM_HISTOGRAM; 1107 return CUSTOM_HISTOGRAM;
1101 } 1108 }
1102 1109
1103 // static 1110 // static
1104 std::vector<Sample> CustomHistogram::ArrayToCustomRanges( 1111 std::vector<Sample> CustomHistogram::ArrayToCustomRanges(
1105 const Sample* values, uint32_t num_values) { 1112 const Sample* values, uint32_t num_values) {
1106 std::vector<Sample> all_values; 1113 std::vector<Sample> all_values;
1107 for (uint32_t i = 0; i < num_values; ++i) { 1114 for (uint32_t i = 0; i < num_values; ++i) {
1108 Sample value = values[i]; 1115 Sample value = values[i];
1109 all_values.push_back(value); 1116 all_values.push_back(value);
1110 1117
1111 // Ensure that a guard bucket is added. If we end up with duplicate 1118 // Ensure that a guard bucket is added. If we end up with duplicate
1112 // values, FactoryGet will take care of removing them. 1119 // values, FactoryGet will take care of removing them.
1113 all_values.push_back(value + 1); 1120 all_values.push_back(value + 1);
1114 } 1121 }
1115 return all_values; 1122 return all_values;
1116 } 1123 }
1117 1124
1118 CustomHistogram::CustomHistogram(const std::string& name, 1125 CustomHistogram::CustomHistogram(const std::string& name,
1119 const BucketRanges* ranges) 1126 const BucketRanges* ranges)
1120 : Histogram(name, 1127 : Histogram(name,
1121 ranges->range(1), 1128 ranges->range(1),
1122 ranges->range(ranges->bucket_count() - 1), 1129 ranges->range(ranges->bucket_count() - 1),
1123 ranges) {} 1130 ranges) {}
1124 1131
1125 CustomHistogram::CustomHistogram(const std::string& name, 1132 CustomHistogram::CustomHistogram(
1126 const BucketRanges* ranges, 1133 const std::string& name,
1127 HistogramBase::AtomicCount* counts, 1134 const BucketRanges* ranges,
1128 HistogramBase::AtomicCount* logged_counts, 1135 const DelayedPersistentAllocation& counts,
1129 uint32_t counts_size, 1136 const DelayedPersistentAllocation& logged_counts,
1130 HistogramSamples::Metadata* meta, 1137 HistogramSamples::Metadata* meta,
1131 HistogramSamples::Metadata* logged_meta) 1138 HistogramSamples::Metadata* logged_meta)
1132 : Histogram(name, 1139 : Histogram(name,
1133 ranges->range(1), 1140 ranges->range(1),
1134 ranges->range(ranges->bucket_count() - 1), 1141 ranges->range(ranges->bucket_count() - 1),
1135 ranges, 1142 ranges,
1136 counts, 1143 counts,
1137 logged_counts, 1144 logged_counts,
1138 counts_size,
1139 meta, 1145 meta,
1140 logged_meta) {} 1146 logged_meta) {}
1141 1147
1142 bool CustomHistogram::SerializeInfoImpl(Pickle* pickle) const { 1148 bool CustomHistogram::SerializeInfoImpl(Pickle* pickle) const {
1143 if (!Histogram::SerializeInfoImpl(pickle)) 1149 if (!Histogram::SerializeInfoImpl(pickle))
1144 return false; 1150 return false;
1145 1151
1146 // Serialize ranges. First and last ranges are alwasy 0 and INT_MAX, so don't 1152 // Serialize ranges. First and last ranges are alwasy 0 and INT_MAX, so don't
1147 // write them. 1153 // write them.
1148 for (uint32_t i = 1; i < bucket_ranges()->bucket_count(); ++i) { 1154 for (uint32_t i = 1; i < bucket_ranges()->bucket_count(); ++i) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 Sample sample = custom_ranges[i]; 1203 Sample sample = custom_ranges[i];
1198 if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1) 1204 if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1)
1199 return false; 1205 return false;
1200 if (sample != 0) 1206 if (sample != 0)
1201 has_valid_range = true; 1207 has_valid_range = true;
1202 } 1208 }
1203 return has_valid_range; 1209 return has_valid_range;
1204 } 1210 }
1205 1211
1206 } // namespace base 1212 } // 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