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

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

Issue 12207058: Connect SparseHistogram with the rest of stats system (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix and add tests Created 7 years, 10 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 | Annotate | Revision Log
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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 } 77 }
78 78
79 } // namespace 79 } // namespace
80 80
81 typedef HistogramBase::Count Count; 81 typedef HistogramBase::Count Count;
82 typedef HistogramBase::Sample Sample; 82 typedef HistogramBase::Sample Sample;
83 83
84 // static 84 // static
85 const size_t Histogram::kBucketCount_MAX = 16384u; 85 const size_t Histogram::kBucketCount_MAX = 16384u;
86 86
87 // TODO(rtenneti): delete this code after debugging.
88 void CheckCorruption(const Histogram& histogram, bool new_histogram) {
89 const std::string& histogram_name = histogram.histogram_name();
90 char histogram_name_buf[128];
91 base::strlcpy(histogram_name_buf,
92 histogram_name.c_str(),
93 arraysize(histogram_name_buf));
94 base::debug::Alias(histogram_name_buf);
95
96 bool debug_new_histogram[1];
97 debug_new_histogram[0] = new_histogram;
98 base::debug::Alias(debug_new_histogram);
99
100 Sample previous_range = -1; // Bottom range is always 0.
101 for (size_t index = 0; index < histogram.bucket_count(); ++index) {
102 int new_range = histogram.ranges(index);
103 CHECK_LT(previous_range, new_range);
104 previous_range = new_range;
105 }
106
107 CHECK(histogram.bucket_ranges()->HasValidChecksum());
108 }
Ilya Sherman 2013/02/21 05:36:06 Please check with Raman whether he's ok with remov
kaiwang 2013/02/27 04:39:42 emailed him
109
110 HistogramBase* Histogram::FactoryGet(const string& name, 87 HistogramBase* Histogram::FactoryGet(const string& name,
111 Sample minimum, 88 Sample minimum,
112 Sample maximum, 89 Sample maximum,
113 size_t bucket_count, 90 size_t bucket_count,
114 int32 flags) { 91 int32 flags) {
115 bool valid_arguments = 92 bool valid_arguments =
116 InspectConstructionArguments(name, &minimum, &maximum, &bucket_count); 93 InspectConstructionArguments(name, &minimum, &maximum, &bucket_count);
117 DCHECK(valid_arguments); 94 DCHECK(valid_arguments);
118 95
119 Histogram* histogram = StatisticsRecorder::FindHistogram(name); 96 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
120 if (!histogram) { 97 if (!histogram) {
121 // To avoid racy destruction at shutdown, the following will be leaked. 98 // To avoid racy destruction at shutdown, the following will be leaked.
122 BucketRanges* ranges = new BucketRanges(bucket_count + 1); 99 BucketRanges* ranges = new BucketRanges(bucket_count + 1);
123 InitializeBucketRanges(minimum, maximum, bucket_count, ranges); 100 InitializeBucketRanges(minimum, maximum, bucket_count, ranges);
124 const BucketRanges* registered_ranges = 101 const BucketRanges* registered_ranges =
125 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); 102 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
126 103
127 Histogram* tentative_histogram = 104 Histogram* tentative_histogram =
128 new Histogram(name, minimum, maximum, bucket_count, registered_ranges); 105 new Histogram(name, minimum, maximum, bucket_count, registered_ranges);
129 CheckCorruption(*tentative_histogram, true);
130 106
131 tentative_histogram->SetFlags(flags); 107 tentative_histogram->SetFlags(flags);
132 histogram = 108 histogram =
133 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); 109 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
134 } 110 }
135 // TODO(rtenneti): delete this code after debugging.
136 CheckCorruption(*histogram, false);
137 111
138 CHECK_EQ(HISTOGRAM, histogram->GetHistogramType()); 112 CHECK_EQ(HISTOGRAM, histogram->GetHistogramType());
139 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count)); 113 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count));
140 return histogram; 114 return histogram;
141 } 115 }
142 116
143 HistogramBase* Histogram::FactoryTimeGet(const string& name, 117 HistogramBase* Histogram::FactoryTimeGet(const string& name,
144 TimeDelta minimum, 118 TimeDelta minimum,
145 TimeDelta maximum, 119 TimeDelta maximum,
146 size_t bucket_count, 120 size_t bucket_count,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 ++current; // Just do a narrow bucket, and keep trying. 167 ++current; // Just do a narrow bucket, and keep trying.
194 ranges->set_range(bucket_index, current); 168 ranges->set_range(bucket_index, current);
195 } 169 }
196 ranges->set_range(ranges->size() - 1, HistogramBase::kSampleType_MAX); 170 ranges->set_range(ranges->size() - 1, HistogramBase::kSampleType_MAX);
197 ranges->ResetChecksum(); 171 ranges->ResetChecksum();
198 } 172 }
199 173
200 // static 174 // static
201 const int Histogram::kCommonRaceBasedCountMismatch = 5; 175 const int Histogram::kCommonRaceBasedCountMismatch = 5;
202 176
203 Histogram::Inconsistencies Histogram::FindCorruption( 177 int32 Histogram::FindCorruption(const HistogramSamples& samples) const {
204 const HistogramSamples& samples) const {
205 int inconsistencies = NO_INCONSISTENCIES; 178 int inconsistencies = NO_INCONSISTENCIES;
206 Sample previous_range = -1; // Bottom range is always 0. 179 Sample previous_range = -1; // Bottom range is always 0.
207 for (size_t index = 0; index < bucket_count(); ++index) { 180 for (size_t index = 0; index < bucket_count(); ++index) {
208 int new_range = ranges(index); 181 int new_range = ranges(index);
209 if (previous_range >= new_range) 182 if (previous_range >= new_range)
210 inconsistencies |= BUCKET_ORDER_ERROR; 183 inconsistencies |= BUCKET_ORDER_ERROR;
211 previous_range = new_range; 184 previous_range = new_range;
212 } 185 }
213 186
214 if (!bucket_ranges()->HasValidChecksum()) 187 if (!bucket_ranges()->HasValidChecksum())
215 inconsistencies |= RANGE_CHECKSUM_ERROR; 188 inconsistencies |= RANGE_CHECKSUM_ERROR;
216 189
217 int64 delta64 = samples.redundant_count() - samples.TotalCount(); 190 int64 delta64 = samples.redundant_count() - samples.TotalCount();
218 if (delta64 != 0) { 191 if (delta64 != 0) {
219 int delta = static_cast<int>(delta64); 192 int delta = static_cast<int>(delta64);
220 if (delta != delta64) 193 if (delta != delta64)
221 delta = INT_MAX; // Flag all giant errors as INT_MAX. 194 delta = INT_MAX; // Flag all giant errors as INT_MAX.
222 if (delta > 0) { 195 if (delta > 0) {
223 UMA_HISTOGRAM_COUNTS("Histogram.InconsistentCountHigh", delta); 196 UMA_HISTOGRAM_COUNTS("Histogram.InconsistentCountHigh", delta);
224 if (delta > kCommonRaceBasedCountMismatch) 197 if (delta > kCommonRaceBasedCountMismatch)
225 inconsistencies |= COUNT_HIGH_ERROR; 198 inconsistencies |= COUNT_HIGH_ERROR;
226 } else { 199 } else {
227 DCHECK_GT(0, delta); 200 DCHECK_GT(0, delta);
228 UMA_HISTOGRAM_COUNTS("Histogram.InconsistentCountLow", -delta); 201 UMA_HISTOGRAM_COUNTS("Histogram.InconsistentCountLow", -delta);
229 if (-delta > kCommonRaceBasedCountMismatch) 202 if (-delta > kCommonRaceBasedCountMismatch)
230 inconsistencies |= COUNT_LOW_ERROR; 203 inconsistencies |= COUNT_LOW_ERROR;
231 } 204 }
232 } 205 }
233 return static_cast<Inconsistencies>(inconsistencies); 206 return inconsistencies;
234 } 207 }
235 208
236 Sample Histogram::ranges(size_t i) const { 209 Sample Histogram::ranges(size_t i) const {
237 return bucket_ranges_->range(i); 210 return bucket_ranges_->range(i);
238 } 211 }
239 212
240 size_t Histogram::bucket_count() const { 213 size_t Histogram::bucket_count() const {
241 return bucket_count_; 214 return bucket_count_;
242 } 215 }
243 216
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 const std::string& name, 565 const std::string& name,
593 Sample minimum, 566 Sample minimum,
594 Sample maximum, 567 Sample maximum,
595 size_t bucket_count, 568 size_t bucket_count,
596 int32 flags, 569 int32 flags,
597 const DescriptionPair descriptions[]) { 570 const DescriptionPair descriptions[]) {
598 bool valid_arguments = Histogram::InspectConstructionArguments( 571 bool valid_arguments = Histogram::InspectConstructionArguments(
599 name, &minimum, &maximum, &bucket_count); 572 name, &minimum, &maximum, &bucket_count);
600 DCHECK(valid_arguments); 573 DCHECK(valid_arguments);
601 574
602 Histogram* histogram = StatisticsRecorder::FindHistogram(name); 575 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
603 if (!histogram) { 576 if (!histogram) {
604 // To avoid racy destruction at shutdown, the following will be leaked. 577 // To avoid racy destruction at shutdown, the following will be leaked.
605 BucketRanges* ranges = new BucketRanges(bucket_count + 1); 578 BucketRanges* ranges = new BucketRanges(bucket_count + 1);
606 InitializeBucketRanges(minimum, maximum, bucket_count, ranges); 579 InitializeBucketRanges(minimum, maximum, bucket_count, ranges);
607 const BucketRanges* registered_ranges = 580 const BucketRanges* registered_ranges =
608 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); 581 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
609 582
610 LinearHistogram* tentative_histogram = 583 LinearHistogram* tentative_histogram =
611 new LinearHistogram(name, minimum, maximum, bucket_count, 584 new LinearHistogram(name, minimum, maximum, bucket_count,
612 registered_ranges); 585 registered_ranges);
613 CheckCorruption(*tentative_histogram, true);
614 586
615 // Set range descriptions. 587 // Set range descriptions.
616 if (descriptions) { 588 if (descriptions) {
617 for (int i = 0; descriptions[i].description; ++i) { 589 for (int i = 0; descriptions[i].description; ++i) {
618 tentative_histogram->bucket_description_[descriptions[i].sample] = 590 tentative_histogram->bucket_description_[descriptions[i].sample] =
619 descriptions[i].description; 591 descriptions[i].description;
620 } 592 }
621 } 593 }
622 594
623 tentative_histogram->SetFlags(flags); 595 tentative_histogram->SetFlags(flags);
624 histogram = 596 histogram =
625 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); 597 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
626 } 598 }
627 // TODO(rtenneti): delete this code after debugging.
628 CheckCorruption(*histogram, false);
629 599
630 CHECK_EQ(LINEAR_HISTOGRAM, histogram->GetHistogramType()); 600 CHECK_EQ(LINEAR_HISTOGRAM, histogram->GetHistogramType());
631 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count)); 601 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count));
632 return histogram; 602 return histogram;
633 } 603 }
634 604
635 HistogramType LinearHistogram::GetHistogramType() const { 605 HistogramType LinearHistogram::GetHistogramType() const {
636 return LINEAR_HISTOGRAM; 606 return LINEAR_HISTOGRAM;
637 } 607 }
638 608
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 return NULL; 673 return NULL;
704 } 674 }
705 return histogram; 675 return histogram;
706 } 676 }
707 677
708 //------------------------------------------------------------------------------ 678 //------------------------------------------------------------------------------
709 // This section provides implementation for BooleanHistogram. 679 // This section provides implementation for BooleanHistogram.
710 //------------------------------------------------------------------------------ 680 //------------------------------------------------------------------------------
711 681
712 HistogramBase* BooleanHistogram::FactoryGet(const string& name, int32 flags) { 682 HistogramBase* BooleanHistogram::FactoryGet(const string& name, int32 flags) {
713 Histogram* histogram = StatisticsRecorder::FindHistogram(name); 683 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
714 if (!histogram) { 684 if (!histogram) {
715 // To avoid racy destruction at shutdown, the following will be leaked. 685 // To avoid racy destruction at shutdown, the following will be leaked.
716 BucketRanges* ranges = new BucketRanges(4); 686 BucketRanges* ranges = new BucketRanges(4);
717 LinearHistogram::InitializeBucketRanges(1, 2, 3, ranges); 687 LinearHistogram::InitializeBucketRanges(1, 2, 3, ranges);
718 const BucketRanges* registered_ranges = 688 const BucketRanges* registered_ranges =
719 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); 689 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
720 690
721 BooleanHistogram* tentative_histogram = 691 BooleanHistogram* tentative_histogram =
722 new BooleanHistogram(name, registered_ranges); 692 new BooleanHistogram(name, registered_ranges);
723 CheckCorruption(*tentative_histogram, true);
724 693
725 tentative_histogram->SetFlags(flags); 694 tentative_histogram->SetFlags(flags);
726 histogram = 695 histogram =
727 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); 696 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
728 } 697 }
729 // TODO(rtenneti): delete this code after debugging.
730 CheckCorruption(*histogram, false);
731 698
732 CHECK_EQ(BOOLEAN_HISTOGRAM, histogram->GetHistogramType()); 699 CHECK_EQ(BOOLEAN_HISTOGRAM, histogram->GetHistogramType());
733 return histogram; 700 return histogram;
734 } 701 }
735 702
736 HistogramType BooleanHistogram::GetHistogramType() const { 703 HistogramType BooleanHistogram::GetHistogramType() const {
737 return BOOLEAN_HISTOGRAM; 704 return BOOLEAN_HISTOGRAM;
738 } 705 }
739 706
740 BooleanHistogram::BooleanHistogram(const string& name, 707 BooleanHistogram::BooleanHistogram(const string& name,
(...skipping 24 matching lines...) Expand all
765 732
766 //------------------------------------------------------------------------------ 733 //------------------------------------------------------------------------------
767 // CustomHistogram: 734 // CustomHistogram:
768 //------------------------------------------------------------------------------ 735 //------------------------------------------------------------------------------
769 736
770 HistogramBase* CustomHistogram::FactoryGet(const string& name, 737 HistogramBase* CustomHistogram::FactoryGet(const string& name,
771 const vector<Sample>& custom_ranges, 738 const vector<Sample>& custom_ranges,
772 int32 flags) { 739 int32 flags) {
773 CHECK(ValidateCustomRanges(custom_ranges)); 740 CHECK(ValidateCustomRanges(custom_ranges));
774 741
775 Histogram* histogram = StatisticsRecorder::FindHistogram(name); 742 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
776 if (!histogram) { 743 if (!histogram) {
777 BucketRanges* ranges = CreateBucketRangesFromCustomRanges(custom_ranges); 744 BucketRanges* ranges = CreateBucketRangesFromCustomRanges(custom_ranges);
778 const BucketRanges* registered_ranges = 745 const BucketRanges* registered_ranges =
779 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); 746 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
780 747
781 // To avoid racy destruction at shutdown, the following will be leaked. 748 // To avoid racy destruction at shutdown, the following will be leaked.
782 CustomHistogram* tentative_histogram = 749 CustomHistogram* tentative_histogram =
783 new CustomHistogram(name, registered_ranges); 750 new CustomHistogram(name, registered_ranges);
784 CheckCorruption(*tentative_histogram, true);
785 751
786 tentative_histogram->SetFlags(flags); 752 tentative_histogram->SetFlags(flags);
787 753
788 histogram = 754 histogram =
789 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); 755 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
790 } 756 }
791 // TODO(rtenneti): delete this code after debugging.
792 CheckCorruption(*histogram, false);
793 757
794 CHECK_EQ(histogram->GetHistogramType(), CUSTOM_HISTOGRAM); 758 CHECK_EQ(histogram->GetHistogramType(), CUSTOM_HISTOGRAM);
795 return histogram; 759 return histogram;
796 } 760 }
797 761
798 HistogramType CustomHistogram::GetHistogramType() const { 762 HistogramType CustomHistogram::GetHistogramType() const {
799 return CUSTOM_HISTOGRAM; 763 return CUSTOM_HISTOGRAM;
800 } 764 }
801 765
802 // static 766 // static
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 860
897 BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); 861 BucketRanges* bucket_ranges = new BucketRanges(ranges.size());
898 for (size_t i = 0; i < ranges.size(); i++) { 862 for (size_t i = 0; i < ranges.size(); i++) {
899 bucket_ranges->set_range(i, ranges[i]); 863 bucket_ranges->set_range(i, ranges[i]);
900 } 864 }
901 bucket_ranges->ResetChecksum(); 865 bucket_ranges->ResetChecksum();
902 return bucket_ranges; 866 return bucket_ranges;
903 } 867 }
904 868
905 } // namespace base 869 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698