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 <limits.h> | 12 #include <limits.h> |
13 #include <math.h> | 13 #include <math.h> |
14 | 14 |
15 #include <algorithm> | 15 #include <algorithm> |
16 #include <string> | 16 #include <string> |
17 | 17 |
18 #include "base/compiler_specific.h" | 18 #include "base/compiler_specific.h" |
19 #include "base/debug/alias.h" | 19 #include "base/debug/alias.h" |
20 #include "base/logging.h" | 20 #include "base/logging.h" |
21 #include "base/metrics/histogram_macros.h" | 21 #include "base/metrics/histogram_macros.h" |
22 #include "base/metrics/histogram_persistence.h" | |
23 #include "base/metrics/metrics_hashes.h" | 22 #include "base/metrics/metrics_hashes.h" |
| 23 #include "base/metrics/persistent_histogram_allocator.h" |
24 #include "base/metrics/persistent_memory_allocator.h" | 24 #include "base/metrics/persistent_memory_allocator.h" |
25 #include "base/metrics/sample_vector.h" | 25 #include "base/metrics/sample_vector.h" |
26 #include "base/metrics/statistics_recorder.h" | 26 #include "base/metrics/statistics_recorder.h" |
27 #include "base/pickle.h" | 27 #include "base/pickle.h" |
28 #include "base/strings/string_util.h" | 28 #include "base/strings/string_util.h" |
29 #include "base/strings/stringprintf.h" | 29 #include "base/strings/stringprintf.h" |
30 #include "base/synchronization/lock.h" | 30 #include "base/synchronization/lock.h" |
31 #include "base/values.h" | 31 #include "base/values.h" |
32 | 32 |
33 namespace base { | 33 namespace base { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 | 115 |
116 // Create a BucketRanges structure appropriate for this histogram. | 116 // Create a BucketRanges structure appropriate for this histogram. |
117 virtual BucketRanges* CreateRanges() { | 117 virtual BucketRanges* CreateRanges() { |
118 BucketRanges* ranges = new BucketRanges(bucket_count_ + 1); | 118 BucketRanges* ranges = new BucketRanges(bucket_count_ + 1); |
119 Histogram::InitializeBucketRanges(minimum_, maximum_, ranges); | 119 Histogram::InitializeBucketRanges(minimum_, maximum_, ranges); |
120 return ranges; | 120 return ranges; |
121 } | 121 } |
122 | 122 |
123 // Allocate the correct Histogram object off the heap (in case persistent | 123 // Allocate the correct Histogram object off the heap (in case persistent |
124 // memory is not available). | 124 // memory is not available). |
125 virtual HistogramBase* HeapAlloc(const BucketRanges* ranges) { | 125 virtual scoped_ptr<HistogramBase> HeapAlloc(const BucketRanges* ranges) { |
126 return new Histogram(name_, minimum_, maximum_, ranges); | 126 return make_scoped_ptr(new Histogram(name_, minimum_, maximum_, ranges)); |
127 } | 127 } |
128 | 128 |
129 // Perform any required datafill on the just-created histogram. If | 129 // Perform any required datafill on the just-created histogram. If |
130 // overridden, be sure to call the "super" version. | 130 // overridden, be sure to call the "super" version. |
131 virtual void FillHistogram(HistogramBase* histogram) { | 131 virtual void FillHistogram(HistogramBase* histogram) { |
132 histogram->SetFlags(flags_); | 132 histogram->SetFlags(flags_); |
133 } | 133 } |
134 | 134 |
135 // These values are protected (instead of private) because they need to | 135 // These values are protected (instead of private) because they need to |
136 // be accessible to methods of sub-classes in order to avoid passing | 136 // be accessible to methods of sub-classes in order to avoid passing |
137 // unnecessary parameters everywhere. | 137 // unnecessary parameters everywhere. |
138 const std::string& name_; | 138 const std::string& name_; |
139 const HistogramType histogram_type_; | 139 const HistogramType histogram_type_; |
140 HistogramBase::Sample minimum_; | 140 HistogramBase::Sample minimum_; |
141 HistogramBase::Sample maximum_; | 141 HistogramBase::Sample maximum_; |
142 uint32_t bucket_count_; | 142 uint32_t bucket_count_; |
143 int32_t flags_; | 143 int32_t flags_; |
144 | 144 |
145 private: | 145 private: |
146 DISALLOW_COPY_AND_ASSIGN(Factory); | 146 DISALLOW_COPY_AND_ASSIGN(Factory); |
147 }; | 147 }; |
148 | 148 |
149 HistogramBase* Histogram::Factory::Build() { | 149 HistogramBase* Histogram::Factory::Build() { |
150 // Import histograms from known persistent storage. Histograms could have | 150 // Import histograms from known persistent storage. Histograms could have |
151 // been added by other processes and they must be fetched and recognized | 151 // been added by other processes and they must be fetched and recognized |
152 // locally in order to be found by FindHistograms() below. If the persistent | 152 // locally in order to be found by FindHistograms() below. If the persistent |
153 // memory segment is not shared between processes, this call does nothing. | 153 // memory segment is not shared between processes, this call does nothing. |
154 ImportPersistentHistograms(); | 154 PersistentHistogramAllocator::ImportGlobalHistograms(); |
155 | 155 |
156 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name_); | 156 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name_); |
157 if (!histogram) { | 157 if (!histogram) { |
158 // To avoid racy destruction at shutdown, the following will be leaked. | 158 // To avoid racy destruction at shutdown, the following will be leaked. |
159 const BucketRanges* created_ranges = CreateRanges(); | 159 const BucketRanges* created_ranges = CreateRanges(); |
160 const BucketRanges* registered_ranges = | 160 const BucketRanges* registered_ranges = |
161 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(created_ranges); | 161 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(created_ranges); |
162 | 162 |
163 // In most cases, the bucket-count, minimum, and maximum values are known | 163 // In most cases, the bucket-count, minimum, and maximum values are known |
164 // when the code is written and so are passed in explicitly. In other | 164 // when the code is written and so are passed in explicitly. In other |
165 // cases (such as with a CustomHistogram), they are calculated dynamically | 165 // cases (such as with a CustomHistogram), they are calculated dynamically |
166 // at run-time. In the latter case, those ctor parameters are zero and | 166 // at run-time. In the latter case, those ctor parameters are zero and |
167 // the results extracted from the result of CreateRanges(). | 167 // the results extracted from the result of CreateRanges(). |
168 if (bucket_count_ == 0) { | 168 if (bucket_count_ == 0) { |
169 bucket_count_ = static_cast<uint32_t>(registered_ranges->bucket_count()); | 169 bucket_count_ = static_cast<uint32_t>(registered_ranges->bucket_count()); |
170 minimum_ = registered_ranges->range(1); | 170 minimum_ = registered_ranges->range(1); |
171 maximum_ = registered_ranges->range(bucket_count_ - 1); | 171 maximum_ = registered_ranges->range(bucket_count_ - 1); |
172 } | 172 } |
173 | 173 |
174 // Try to create the histogram using a "persistent" allocator. As of | 174 // Try to create the histogram using a "persistent" allocator. As of |
175 // 2015-01-14, the availability of such is controlled by a base::Feature | 175 // 2015-01-14, the availability of such is controlled by a base::Feature |
176 // that is off by default. If the allocator doesn't exist or if | 176 // that is off by default. If the allocator doesn't exist or if |
177 // allocating from it fails, code below will allocate the histogram from | 177 // allocating from it fails, code below will allocate the histogram from |
178 // the process heap. | 178 // the process heap. |
179 PersistentMemoryAllocator::Reference histogram_ref = 0; | 179 PersistentHistogramAllocator::Reference histogram_ref = 0; |
180 HistogramBase* tentative_histogram = nullptr; | 180 scoped_ptr<HistogramBase> tentative_histogram; |
181 PersistentMemoryAllocator* allocator = | 181 PersistentHistogramAllocator* allocator = |
182 GetPersistentHistogramMemoryAllocator(); | 182 PersistentHistogramAllocator::GetGlobalAllocator(); |
183 if (allocator) { | 183 if (allocator) { |
184 flags_ |= HistogramBase::kIsPersistent; | 184 flags_ |= HistogramBase::kIsPersistent; |
185 tentative_histogram = AllocatePersistentHistogram( | 185 tentative_histogram = allocator->AllocateHistogram( |
186 allocator, | |
187 histogram_type_, | 186 histogram_type_, |
188 name_, | 187 name_, |
189 minimum_, | 188 minimum_, |
190 maximum_, | 189 maximum_, |
191 registered_ranges, | 190 registered_ranges, |
192 flags_, | 191 flags_, |
193 &histogram_ref); | 192 &histogram_ref); |
194 } | 193 } |
195 | 194 |
196 // Handle the case where no persistent allocator is present or the | 195 // Handle the case where no persistent allocator is present or the |
197 // persistent allocation fails (perhaps because it is full). | 196 // persistent allocation fails (perhaps because it is full). |
198 if (!tentative_histogram) { | 197 if (!tentative_histogram) { |
199 DCHECK(!histogram_ref); // Should never have been set. | 198 DCHECK(!histogram_ref); // Should never have been set. |
200 DCHECK(!allocator); // Shouldn't have failed. | 199 DCHECK(!allocator); // Shouldn't have failed. |
201 flags_ &= ~HistogramBase::kIsPersistent; | 200 flags_ &= ~HistogramBase::kIsPersistent; |
202 tentative_histogram = HeapAlloc(registered_ranges); | 201 tentative_histogram = HeapAlloc(registered_ranges); |
203 } | 202 } |
204 | 203 |
205 FillHistogram(tentative_histogram); | 204 FillHistogram(tentative_histogram.get()); |
206 histogram = | 205 |
207 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); | 206 // Register this histogram with the StatisticsRecorder. Keep a copy of |
| 207 // the pointer value to tell later whether the locally created histogram |
| 208 // was registered or deleted. The type is "void" because it could point |
| 209 // to released memory after the following line. |
| 210 const void* tentative_histogram_ptr = tentative_histogram.get(); |
| 211 histogram = StatisticsRecorder::RegisterOrDeleteDuplicate( |
| 212 tentative_histogram.release()); |
208 | 213 |
209 // Persistent histograms need some follow-up processing. | 214 // Persistent histograms need some follow-up processing. |
210 if (histogram_ref) { | 215 if (histogram_ref) { |
211 FinalizePersistentHistogram(histogram_ref, | 216 allocator->FinalizeHistogram(histogram_ref, |
212 histogram == tentative_histogram); | 217 histogram == tentative_histogram_ptr); |
213 } | 218 } |
214 } | 219 } |
215 | 220 |
216 DCHECK_EQ(histogram_type_, histogram->GetHistogramType()); | 221 DCHECK_EQ(histogram_type_, histogram->GetHistogramType()); |
217 if (bucket_count_ != 0 && | 222 if (bucket_count_ != 0 && |
218 !histogram->HasConstructionArguments(minimum_, maximum_, bucket_count_)) { | 223 !histogram->HasConstructionArguments(minimum_, maximum_, bucket_count_)) { |
219 // The construction arguments do not match the existing histogram. This can | 224 // The construction arguments do not match the existing histogram. This can |
220 // come about if an extension updates in the middle of a chrome run and has | 225 // come about if an extension updates in the middle of a chrome run and has |
221 // changed one of them, or simply by bad code within Chrome itself. We | 226 // changed one of them, or simply by bad code within Chrome itself. We |
222 // return NULL here with the expectation that bad code in Chrome will crash | 227 // return NULL here with the expectation that bad code in Chrome will crash |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 | 265 |
261 HistogramBase* Histogram::FactoryTimeGet(const char* name, | 266 HistogramBase* Histogram::FactoryTimeGet(const char* name, |
262 TimeDelta minimum, | 267 TimeDelta minimum, |
263 TimeDelta maximum, | 268 TimeDelta maximum, |
264 uint32_t bucket_count, | 269 uint32_t bucket_count, |
265 int32_t flags) { | 270 int32_t flags) { |
266 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count, | 271 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count, |
267 flags); | 272 flags); |
268 } | 273 } |
269 | 274 |
270 HistogramBase* Histogram::PersistentGet( | 275 scoped_ptr<HistogramBase> Histogram::PersistentCreate( |
271 const std::string& name, | 276 const std::string& name, |
272 Sample minimum, | 277 Sample minimum, |
273 Sample maximum, | 278 Sample maximum, |
274 const BucketRanges* ranges, | 279 const BucketRanges* ranges, |
275 HistogramBase::AtomicCount* counts, | 280 HistogramBase::AtomicCount* counts, |
276 HistogramBase::AtomicCount* logged_counts, | 281 HistogramBase::AtomicCount* logged_counts, |
277 uint32_t counts_size, | 282 uint32_t counts_size, |
278 HistogramSamples::Metadata* meta, | 283 HistogramSamples::Metadata* meta, |
279 HistogramSamples::Metadata* logged_meta) { | 284 HistogramSamples::Metadata* logged_meta) { |
280 return new Histogram(name, minimum, maximum, ranges, counts, logged_counts, | 285 return make_scoped_ptr(new Histogram( |
281 counts_size, meta, logged_meta); | 286 name, minimum, maximum, ranges, counts, logged_counts, counts_size, |
| 287 meta, logged_meta)); |
282 } | 288 } |
283 | 289 |
284 // Calculate what range of values are held in each bucket. | 290 // Calculate what range of values are held in each bucket. |
285 // We have to be careful that we don't pick a ratio between starting points in | 291 // We have to be careful that we don't pick a ratio between starting points in |
286 // consecutive buckets that is sooo small, that the integer bounds are the same | 292 // consecutive buckets that is sooo small, that the integer bounds are the same |
287 // (effectively making one bucket get no values). We need to avoid: | 293 // (effectively making one bucket get no values). We need to avoid: |
288 // ranges(i) == ranges(i + 1) | 294 // ranges(i) == ranges(i + 1) |
289 // To avoid that, we just do a fine-grained bucket width as far as we need to | 295 // To avoid that, we just do a fine-grained bucket width as far as we need to |
290 // until we get a ratio that moves us along at least 2 units at a time. From | 296 // until we get a ratio that moves us along at least 2 units at a time. From |
291 // that bucket onward we do use the exponential growth of buckets. | 297 // that bucket onward we do use the exponential growth of buckets. |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 descriptions_ = descriptions; | 731 descriptions_ = descriptions; |
726 } | 732 } |
727 | 733 |
728 protected: | 734 protected: |
729 BucketRanges* CreateRanges() override { | 735 BucketRanges* CreateRanges() override { |
730 BucketRanges* ranges = new BucketRanges(bucket_count_ + 1); | 736 BucketRanges* ranges = new BucketRanges(bucket_count_ + 1); |
731 LinearHistogram::InitializeBucketRanges(minimum_, maximum_, ranges); | 737 LinearHistogram::InitializeBucketRanges(minimum_, maximum_, ranges); |
732 return ranges; | 738 return ranges; |
733 } | 739 } |
734 | 740 |
735 HistogramBase* HeapAlloc(const BucketRanges* ranges) override { | 741 scoped_ptr<HistogramBase> HeapAlloc(const BucketRanges* ranges) override { |
736 return new LinearHistogram(name_, minimum_, maximum_, ranges); | 742 return make_scoped_ptr( |
| 743 new LinearHistogram(name_, minimum_, maximum_, ranges)); |
737 } | 744 } |
738 | 745 |
739 void FillHistogram(HistogramBase* base_histogram) override { | 746 void FillHistogram(HistogramBase* base_histogram) override { |
740 Histogram::Factory::FillHistogram(base_histogram); | 747 Histogram::Factory::FillHistogram(base_histogram); |
741 LinearHistogram* histogram = static_cast<LinearHistogram*>(base_histogram); | 748 LinearHistogram* histogram = static_cast<LinearHistogram*>(base_histogram); |
742 // Set range descriptions. | 749 // Set range descriptions. |
743 if (descriptions_) { | 750 if (descriptions_) { |
744 for (int i = 0; descriptions_[i].description; ++i) { | 751 for (int i = 0; descriptions_[i].description; ++i) { |
745 histogram->bucket_description_[descriptions_[i].sample] = | 752 histogram->bucket_description_[descriptions_[i].sample] = |
746 descriptions_[i].description; | 753 descriptions_[i].description; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 | 792 |
786 HistogramBase* LinearHistogram::FactoryTimeGet(const char* name, | 793 HistogramBase* LinearHistogram::FactoryTimeGet(const char* name, |
787 TimeDelta minimum, | 794 TimeDelta minimum, |
788 TimeDelta maximum, | 795 TimeDelta maximum, |
789 uint32_t bucket_count, | 796 uint32_t bucket_count, |
790 int32_t flags) { | 797 int32_t flags) { |
791 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count, | 798 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count, |
792 flags); | 799 flags); |
793 } | 800 } |
794 | 801 |
795 HistogramBase* LinearHistogram::PersistentGet( | 802 scoped_ptr<HistogramBase> LinearHistogram::PersistentCreate( |
796 const std::string& name, | 803 const std::string& name, |
797 Sample minimum, | 804 Sample minimum, |
798 Sample maximum, | 805 Sample maximum, |
799 const BucketRanges* ranges, | 806 const BucketRanges* ranges, |
800 HistogramBase::AtomicCount* counts, | 807 HistogramBase::AtomicCount* counts, |
801 HistogramBase::AtomicCount* logged_counts, | 808 HistogramBase::AtomicCount* logged_counts, |
802 uint32_t counts_size, | 809 uint32_t counts_size, |
803 HistogramSamples::Metadata* meta, | 810 HistogramSamples::Metadata* meta, |
804 HistogramSamples::Metadata* logged_meta) { | 811 HistogramSamples::Metadata* logged_meta) { |
805 return new LinearHistogram(name, minimum, maximum, ranges, counts, | 812 return make_scoped_ptr(new LinearHistogram( |
806 logged_counts, counts_size, meta, logged_meta); | 813 name, minimum, maximum, ranges, counts, logged_counts, counts_size, |
| 814 meta, logged_meta)); |
807 } | 815 } |
808 | 816 |
809 HistogramBase* LinearHistogram::FactoryGetWithRangeDescription( | 817 HistogramBase* LinearHistogram::FactoryGetWithRangeDescription( |
810 const std::string& name, | 818 const std::string& name, |
811 Sample minimum, | 819 Sample minimum, |
812 Sample maximum, | 820 Sample maximum, |
813 uint32_t bucket_count, | 821 uint32_t bucket_count, |
814 int32_t flags, | 822 int32_t flags, |
815 const DescriptionPair descriptions[]) { | 823 const DescriptionPair descriptions[]) { |
816 bool valid_arguments = Histogram::InspectConstructionArguments( | 824 bool valid_arguments = Histogram::InspectConstructionArguments( |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
914 Factory(const std::string& name, int32_t flags) | 922 Factory(const std::string& name, int32_t flags) |
915 : Histogram::Factory(name, BOOLEAN_HISTOGRAM, 1, 2, 3, flags) {} | 923 : Histogram::Factory(name, BOOLEAN_HISTOGRAM, 1, 2, 3, flags) {} |
916 | 924 |
917 protected: | 925 protected: |
918 BucketRanges* CreateRanges() override { | 926 BucketRanges* CreateRanges() override { |
919 BucketRanges* ranges = new BucketRanges(3 + 1); | 927 BucketRanges* ranges = new BucketRanges(3 + 1); |
920 LinearHistogram::InitializeBucketRanges(1, 2, ranges); | 928 LinearHistogram::InitializeBucketRanges(1, 2, ranges); |
921 return ranges; | 929 return ranges; |
922 } | 930 } |
923 | 931 |
924 HistogramBase* HeapAlloc(const BucketRanges* ranges) override { | 932 scoped_ptr<HistogramBase> HeapAlloc(const BucketRanges* ranges) override { |
925 return new BooleanHistogram(name_, ranges); | 933 return make_scoped_ptr(new BooleanHistogram(name_, ranges)); |
926 } | 934 } |
927 | 935 |
928 private: | 936 private: |
929 DISALLOW_COPY_AND_ASSIGN(Factory); | 937 DISALLOW_COPY_AND_ASSIGN(Factory); |
930 }; | 938 }; |
931 | 939 |
932 HistogramBase* BooleanHistogram::FactoryGet(const std::string& name, | 940 HistogramBase* BooleanHistogram::FactoryGet(const std::string& name, |
933 int32_t flags) { | 941 int32_t flags) { |
934 return Factory(name, flags).Build(); | 942 return Factory(name, flags).Build(); |
935 } | 943 } |
936 | 944 |
937 HistogramBase* BooleanHistogram::FactoryGet(const char* name, int32_t flags) { | 945 HistogramBase* BooleanHistogram::FactoryGet(const char* name, int32_t flags) { |
938 return FactoryGet(std::string(name), flags); | 946 return FactoryGet(std::string(name), flags); |
939 } | 947 } |
940 | 948 |
941 HistogramBase* BooleanHistogram::PersistentGet( | 949 scoped_ptr<HistogramBase> BooleanHistogram::PersistentCreate( |
942 const std::string& name, | 950 const std::string& name, |
943 const BucketRanges* ranges, | 951 const BucketRanges* ranges, |
944 HistogramBase::AtomicCount* counts, | 952 HistogramBase::AtomicCount* counts, |
945 HistogramBase::AtomicCount* logged_counts, | 953 HistogramBase::AtomicCount* logged_counts, |
946 HistogramSamples::Metadata* meta, | 954 HistogramSamples::Metadata* meta, |
947 HistogramSamples::Metadata* logged_meta) { | 955 HistogramSamples::Metadata* logged_meta) { |
948 return new BooleanHistogram(name, ranges, counts, logged_counts, meta, | 956 return make_scoped_ptr(new BooleanHistogram( |
949 logged_meta); | 957 name, ranges, counts, logged_counts, meta, logged_meta)); |
950 } | 958 } |
951 | 959 |
952 HistogramType BooleanHistogram::GetHistogramType() const { | 960 HistogramType BooleanHistogram::GetHistogramType() const { |
953 return BOOLEAN_HISTOGRAM; | 961 return BOOLEAN_HISTOGRAM; |
954 } | 962 } |
955 | 963 |
956 BooleanHistogram::BooleanHistogram(const std::string& name, | 964 BooleanHistogram::BooleanHistogram(const std::string& name, |
957 const BucketRanges* ranges) | 965 const BucketRanges* ranges) |
958 : LinearHistogram(name, 1, 2, ranges) {} | 966 : LinearHistogram(name, 1, 2, ranges) {} |
959 | 967 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1011 ranges.erase(std::unique(ranges.begin(), ranges.end()), ranges.end()); | 1019 ranges.erase(std::unique(ranges.begin(), ranges.end()), ranges.end()); |
1012 | 1020 |
1013 BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); | 1021 BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); |
1014 for (uint32_t i = 0; i < ranges.size(); i++) { | 1022 for (uint32_t i = 0; i < ranges.size(); i++) { |
1015 bucket_ranges->set_range(i, ranges[i]); | 1023 bucket_ranges->set_range(i, ranges[i]); |
1016 } | 1024 } |
1017 bucket_ranges->ResetChecksum(); | 1025 bucket_ranges->ResetChecksum(); |
1018 return bucket_ranges; | 1026 return bucket_ranges; |
1019 } | 1027 } |
1020 | 1028 |
1021 HistogramBase* HeapAlloc(const BucketRanges* ranges) override { | 1029 scoped_ptr<HistogramBase> HeapAlloc(const BucketRanges* ranges) override { |
1022 return new CustomHistogram(name_, ranges); | 1030 return make_scoped_ptr(new CustomHistogram(name_, ranges)); |
1023 } | 1031 } |
1024 | 1032 |
1025 private: | 1033 private: |
1026 const std::vector<Sample>* custom_ranges_; | 1034 const std::vector<Sample>* custom_ranges_; |
1027 | 1035 |
1028 DISALLOW_COPY_AND_ASSIGN(Factory); | 1036 DISALLOW_COPY_AND_ASSIGN(Factory); |
1029 }; | 1037 }; |
1030 | 1038 |
1031 HistogramBase* CustomHistogram::FactoryGet( | 1039 HistogramBase* CustomHistogram::FactoryGet( |
1032 const std::string& name, | 1040 const std::string& name, |
1033 const std::vector<Sample>& custom_ranges, | 1041 const std::vector<Sample>& custom_ranges, |
1034 int32_t flags) { | 1042 int32_t flags) { |
1035 CHECK(ValidateCustomRanges(custom_ranges)); | 1043 CHECK(ValidateCustomRanges(custom_ranges)); |
1036 | 1044 |
1037 return Factory(name, &custom_ranges, flags).Build(); | 1045 return Factory(name, &custom_ranges, flags).Build(); |
1038 } | 1046 } |
1039 | 1047 |
1040 HistogramBase* CustomHistogram::FactoryGet( | 1048 HistogramBase* CustomHistogram::FactoryGet( |
1041 const char* name, | 1049 const char* name, |
1042 const std::vector<Sample>& custom_ranges, | 1050 const std::vector<Sample>& custom_ranges, |
1043 int32_t flags) { | 1051 int32_t flags) { |
1044 return FactoryGet(std::string(name), custom_ranges, flags); | 1052 return FactoryGet(std::string(name), custom_ranges, flags); |
1045 } | 1053 } |
1046 | 1054 |
1047 HistogramBase* CustomHistogram::PersistentGet( | 1055 scoped_ptr<HistogramBase> CustomHistogram::PersistentCreate( |
1048 const std::string& name, | 1056 const std::string& name, |
1049 const BucketRanges* ranges, | 1057 const BucketRanges* ranges, |
1050 HistogramBase::AtomicCount* counts, | 1058 HistogramBase::AtomicCount* counts, |
1051 HistogramBase::AtomicCount* logged_counts, | 1059 HistogramBase::AtomicCount* logged_counts, |
1052 uint32_t counts_size, | 1060 uint32_t counts_size, |
1053 HistogramSamples::Metadata* meta, | 1061 HistogramSamples::Metadata* meta, |
1054 HistogramSamples::Metadata* logged_meta) { | 1062 HistogramSamples::Metadata* logged_meta) { |
1055 return new CustomHistogram(name, ranges, counts, logged_counts, counts_size, | 1063 return make_scoped_ptr(new CustomHistogram( |
1056 meta, logged_meta); | 1064 name, ranges, counts, logged_counts, counts_size, meta, logged_meta)); |
1057 } | 1065 } |
1058 | 1066 |
1059 HistogramType CustomHistogram::GetHistogramType() const { | 1067 HistogramType CustomHistogram::GetHistogramType() const { |
1060 return CUSTOM_HISTOGRAM; | 1068 return CUSTOM_HISTOGRAM; |
1061 } | 1069 } |
1062 | 1070 |
1063 // static | 1071 // static |
1064 std::vector<Sample> CustomHistogram::ArrayToCustomRanges( | 1072 std::vector<Sample> CustomHistogram::ArrayToCustomRanges( |
1065 const Sample* values, uint32_t num_values) { | 1073 const Sample* values, uint32_t num_values) { |
1066 std::vector<Sample> all_values; | 1074 std::vector<Sample> all_values; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 Sample sample = custom_ranges[i]; | 1163 Sample sample = custom_ranges[i]; |
1156 if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1) | 1164 if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1) |
1157 return false; | 1165 return false; |
1158 if (sample != 0) | 1166 if (sample != 0) |
1159 has_valid_range = true; | 1167 has_valid_range = true; |
1160 } | 1168 } |
1161 return has_valid_range; | 1169 return has_valid_range; |
1162 } | 1170 } |
1163 | 1171 |
1164 } // namespace base | 1172 } // namespace base |
OLD | NEW |