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" |
11 | 11 |
12 #include <math.h> | 12 #include <math.h> |
13 | 13 |
14 #include <algorithm> | 14 #include <algorithm> |
15 #include <string> | 15 #include <string> |
16 | 16 |
| 17 #include "base/compiler_specific.h" |
| 18 #include "base/debug/alias.h" |
17 #include "base/logging.h" | 19 #include "base/logging.h" |
18 #include "base/metrics/statistics_recorder.h" | 20 #include "base/metrics/statistics_recorder.h" |
19 #include "base/pickle.h" | 21 #include "base/pickle.h" |
| 22 #include "base/string_util.h" |
20 #include "base/stringprintf.h" | 23 #include "base/stringprintf.h" |
21 #include "base/synchronization/lock.h" | 24 #include "base/synchronization/lock.h" |
22 | 25 |
23 using std::string; | 26 using std::string; |
24 using std::vector; | 27 using std::vector; |
25 | 28 |
26 namespace base { | 29 namespace base { |
27 | 30 |
28 typedef HistogramBase::Count Count; | 31 typedef HistogramBase::Count Count; |
29 typedef HistogramBase::Sample Sample; | 32 typedef HistogramBase::Sample Sample; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 int i; | 125 int i; |
123 if (!iter->ReadInt(&i)) | 126 if (!iter->ReadInt(&i)) |
124 return false; | 127 return false; |
125 counts_.push_back(i); | 128 counts_.push_back(i); |
126 count += i; | 129 count += i; |
127 } | 130 } |
128 DCHECK_EQ(count, redundant_count_); | 131 DCHECK_EQ(count, redundant_count_); |
129 return count == redundant_count_; | 132 return count == redundant_count_; |
130 } | 133 } |
131 | 134 |
| 135 // TODO(rtenneti): delete this code after debugging. |
| 136 void CheckCorruption(const Histogram& histogram) { |
| 137 const std::string& histogram_name = histogram.histogram_name(); |
| 138 char histogram_name_buf[128]; |
| 139 base::strlcpy(histogram_name_buf, |
| 140 histogram_name.c_str(), |
| 141 arraysize(histogram_name_buf)); |
| 142 base::debug::Alias(histogram_name_buf); |
| 143 |
| 144 Sample previous_range = -1; // Bottom range is always 0. |
| 145 for (size_t index = 0; index < histogram.bucket_count(); ++index) { |
| 146 int new_range = histogram.ranges(index); |
| 147 if (previous_range >= new_range) { |
| 148 CHECK(false); // Crash for the bucket order corruption. |
| 149 } |
| 150 previous_range = new_range; |
| 151 } |
| 152 |
| 153 if (!histogram.bucket_ranges()->HasValidChecksum()) { |
| 154 CHECK(false); // Crash for the checksum corruption. |
| 155 } |
| 156 } |
| 157 |
132 Histogram* Histogram::FactoryGet(const string& name, | 158 Histogram* Histogram::FactoryGet(const string& name, |
133 Sample minimum, | 159 Sample minimum, |
134 Sample maximum, | 160 Sample maximum, |
135 size_t bucket_count, | 161 size_t bucket_count, |
136 int32 flags) { | 162 int32 flags) { |
137 bool valid_arguments = | 163 bool valid_arguments = |
138 InspectConstructionArguments(name, &minimum, &maximum, &bucket_count); | 164 InspectConstructionArguments(name, &minimum, &maximum, &bucket_count); |
139 DCHECK(valid_arguments); | 165 DCHECK(valid_arguments); |
140 | 166 |
141 Histogram* histogram = StatisticsRecorder::FindHistogram(name); | 167 Histogram* histogram = StatisticsRecorder::FindHistogram(name); |
142 if (!histogram) { | 168 if (!histogram) { |
143 // To avoid racy destruction at shutdown, the following will be leaked. | 169 // To avoid racy destruction at shutdown, the following will be leaked. |
144 BucketRanges* ranges = new BucketRanges(bucket_count + 1); | 170 BucketRanges* ranges = new BucketRanges(bucket_count + 1); |
145 InitializeBucketRanges(minimum, maximum, bucket_count, ranges); | 171 InitializeBucketRanges(minimum, maximum, bucket_count, ranges); |
146 const BucketRanges* registered_ranges = | 172 const BucketRanges* registered_ranges = |
147 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); | 173 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); |
148 | 174 |
149 Histogram* tentative_histogram = | 175 Histogram* tentative_histogram = |
150 new Histogram(name, minimum, maximum, bucket_count, registered_ranges); | 176 new Histogram(name, minimum, maximum, bucket_count, registered_ranges); |
151 tentative_histogram->SetFlags(flags); | 177 tentative_histogram->SetFlags(flags); |
152 histogram = | 178 histogram = |
153 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); | 179 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); |
154 } | 180 } |
| 181 // TODO(rtenneti): delete this code after debugging. |
| 182 CheckCorruption(*histogram); |
155 | 183 |
156 CHECK_EQ(HISTOGRAM, histogram->histogram_type()); | 184 CHECK_EQ(HISTOGRAM, histogram->histogram_type()); |
157 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count)); | 185 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count)); |
158 return histogram; | 186 return histogram; |
159 } | 187 } |
160 | 188 |
161 Histogram* Histogram::FactoryTimeGet(const string& name, | 189 Histogram* Histogram::FactoryTimeGet(const string& name, |
162 TimeDelta minimum, | 190 TimeDelta minimum, |
163 TimeDelta maximum, | 191 TimeDelta maximum, |
164 size_t bucket_count, | 192 size_t bucket_count, |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 const BucketRanges* registered_ranges = | 725 const BucketRanges* registered_ranges = |
698 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); | 726 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); |
699 | 727 |
700 LinearHistogram* tentative_histogram = | 728 LinearHistogram* tentative_histogram = |
701 new LinearHistogram(name, minimum, maximum, bucket_count, | 729 new LinearHistogram(name, minimum, maximum, bucket_count, |
702 registered_ranges); | 730 registered_ranges); |
703 tentative_histogram->SetFlags(flags); | 731 tentative_histogram->SetFlags(flags); |
704 histogram = | 732 histogram = |
705 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); | 733 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); |
706 } | 734 } |
| 735 // TODO(rtenneti): delete this code after debugging. |
| 736 CheckCorruption(*histogram); |
707 | 737 |
708 CHECK_EQ(LINEAR_HISTOGRAM, histogram->histogram_type()); | 738 CHECK_EQ(LINEAR_HISTOGRAM, histogram->histogram_type()); |
709 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count)); | 739 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count)); |
710 return histogram; | 740 return histogram; |
711 } | 741 } |
712 | 742 |
713 Histogram* LinearHistogram::FactoryTimeGet(const string& name, | 743 Histogram* LinearHistogram::FactoryTimeGet(const string& name, |
714 TimeDelta minimum, | 744 TimeDelta minimum, |
715 TimeDelta maximum, | 745 TimeDelta maximum, |
716 size_t bucket_count, | 746 size_t bucket_count, |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 LinearHistogram::InitializeBucketRanges(1, 2, 3, ranges); | 818 LinearHistogram::InitializeBucketRanges(1, 2, 3, ranges); |
789 const BucketRanges* registered_ranges = | 819 const BucketRanges* registered_ranges = |
790 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); | 820 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); |
791 | 821 |
792 BooleanHistogram* tentative_histogram = | 822 BooleanHistogram* tentative_histogram = |
793 new BooleanHistogram(name, registered_ranges); | 823 new BooleanHistogram(name, registered_ranges); |
794 tentative_histogram->SetFlags(flags); | 824 tentative_histogram->SetFlags(flags); |
795 histogram = | 825 histogram = |
796 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); | 826 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); |
797 } | 827 } |
| 828 // TODO(rtenneti): delete this code after debugging. |
| 829 CheckCorruption(*histogram); |
798 | 830 |
799 CHECK_EQ(BOOLEAN_HISTOGRAM, histogram->histogram_type()); | 831 CHECK_EQ(BOOLEAN_HISTOGRAM, histogram->histogram_type()); |
800 return histogram; | 832 return histogram; |
801 } | 833 } |
802 | 834 |
803 Histogram::ClassType BooleanHistogram::histogram_type() const { | 835 Histogram::ClassType BooleanHistogram::histogram_type() const { |
804 return BOOLEAN_HISTOGRAM; | 836 return BOOLEAN_HISTOGRAM; |
805 } | 837 } |
806 | 838 |
807 void BooleanHistogram::AddBoolean(bool value) { | 839 void BooleanHistogram::AddBoolean(bool value) { |
(...skipping 20 matching lines...) Expand all Loading... |
828 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); | 860 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); |
829 | 861 |
830 // To avoid racy destruction at shutdown, the following will be leaked. | 862 // To avoid racy destruction at shutdown, the following will be leaked. |
831 CustomHistogram* tentative_histogram = | 863 CustomHistogram* tentative_histogram = |
832 new CustomHistogram(name, registered_ranges); | 864 new CustomHistogram(name, registered_ranges); |
833 tentative_histogram->SetFlags(flags); | 865 tentative_histogram->SetFlags(flags); |
834 | 866 |
835 histogram = | 867 histogram = |
836 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); | 868 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); |
837 } | 869 } |
| 870 // TODO(rtenneti): delete this code after debugging. |
| 871 CheckCorruption(*histogram); |
838 | 872 |
839 CHECK_EQ(histogram->histogram_type(), CUSTOM_HISTOGRAM); | 873 CHECK_EQ(histogram->histogram_type(), CUSTOM_HISTOGRAM); |
840 return histogram; | 874 return histogram; |
841 } | 875 } |
842 | 876 |
843 Histogram::ClassType CustomHistogram::histogram_type() const { | 877 Histogram::ClassType CustomHistogram::histogram_type() const { |
844 return CUSTOM_HISTOGRAM; | 878 return CUSTOM_HISTOGRAM; |
845 } | 879 } |
846 | 880 |
847 // static | 881 // static |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
915 | 949 |
916 BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); | 950 BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); |
917 for (size_t i = 0; i < ranges.size(); i++) { | 951 for (size_t i = 0; i < ranges.size(); i++) { |
918 bucket_ranges->set_range(i, ranges[i]); | 952 bucket_ranges->set_range(i, ranges[i]); |
919 } | 953 } |
920 bucket_ranges->ResetChecksum(); | 954 bucket_ranges->ResetChecksum(); |
921 return bucket_ranges; | 955 return bucket_ranges; |
922 } | 956 } |
923 | 957 |
924 } // namespace base | 958 } // namespace base |
OLD | NEW |