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" | 17 #include "base/compiler_specific.h" |
18 #include "base/debug/alias.h" | 18 #include "base/debug/alias.h" |
19 #include "base/logging.h" | 19 #include "base/logging.h" |
| 20 #include "base/metrics/histogram_macros.h" |
20 #include "base/metrics/sample_vector.h" | 21 #include "base/metrics/sample_vector.h" |
21 #include "base/metrics/statistics_recorder.h" | 22 #include "base/metrics/statistics_recorder.h" |
22 #include "base/pickle.h" | 23 #include "base/pickle.h" |
23 #include "base/strings/string_util.h" | 24 #include "base/strings/string_util.h" |
24 #include "base/strings/stringprintf.h" | 25 #include "base/strings/stringprintf.h" |
25 #include "base/synchronization/lock.h" | 26 #include "base/synchronization/lock.h" |
26 #include "base/values.h" | 27 #include "base/values.h" |
27 | 28 |
28 namespace base { | 29 namespace base { |
29 | 30 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 HistogramBase* Histogram::FactoryTimeGet(const std::string& name, | 124 HistogramBase* Histogram::FactoryTimeGet(const std::string& name, |
124 TimeDelta minimum, | 125 TimeDelta minimum, |
125 TimeDelta maximum, | 126 TimeDelta maximum, |
126 size_t bucket_count, | 127 size_t bucket_count, |
127 int32 flags) { | 128 int32 flags) { |
128 return FactoryGet(name, static_cast<Sample>(minimum.InMilliseconds()), | 129 return FactoryGet(name, static_cast<Sample>(minimum.InMilliseconds()), |
129 static_cast<Sample>(maximum.InMilliseconds()), bucket_count, | 130 static_cast<Sample>(maximum.InMilliseconds()), bucket_count, |
130 flags); | 131 flags); |
131 } | 132 } |
132 | 133 |
| 134 HistogramBase* Histogram::FactoryGet(const char* name, |
| 135 Sample minimum, |
| 136 Sample maximum, |
| 137 size_t bucket_count, |
| 138 int32 flags) { |
| 139 return FactoryGet(std::string(name), minimum, maximum, bucket_count, flags); |
| 140 } |
| 141 |
| 142 HistogramBase* Histogram::FactoryTimeGet(const char* name, |
| 143 TimeDelta minimum, |
| 144 TimeDelta maximum, |
| 145 size_t bucket_count, |
| 146 int32 flags) { |
| 147 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count, |
| 148 flags); |
| 149 } |
| 150 |
133 // Calculate what range of values are held in each bucket. | 151 // Calculate what range of values are held in each bucket. |
134 // We have to be careful that we don't pick a ratio between starting points in | 152 // We have to be careful that we don't pick a ratio between starting points in |
135 // consecutive buckets that is sooo small, that the integer bounds are the same | 153 // consecutive buckets that is sooo small, that the integer bounds are the same |
136 // (effectively making one bucket get no values). We need to avoid: | 154 // (effectively making one bucket get no values). We need to avoid: |
137 // ranges(i) == ranges(i + 1) | 155 // ranges(i) == ranges(i + 1) |
138 // To avoid that, we just do a fine-grained bucket width as far as we need to | 156 // To avoid that, we just do a fine-grained bucket width as far as we need to |
139 // until we get a ratio that moves us along at least 2 units at a time. From | 157 // until we get a ratio that moves us along at least 2 units at a time. From |
140 // that bucket onward we do use the exponential growth of buckets. | 158 // that bucket onward we do use the exponential growth of buckets. |
141 // | 159 // |
142 // static | 160 // static |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 | 273 |
256 void Histogram::Add(int value) { | 274 void Histogram::Add(int value) { |
257 DCHECK_EQ(0, ranges(0)); | 275 DCHECK_EQ(0, ranges(0)); |
258 DCHECK_EQ(kSampleType_MAX, ranges(bucket_count())); | 276 DCHECK_EQ(kSampleType_MAX, ranges(bucket_count())); |
259 | 277 |
260 if (value > kSampleType_MAX - 1) | 278 if (value > kSampleType_MAX - 1) |
261 value = kSampleType_MAX - 1; | 279 value = kSampleType_MAX - 1; |
262 if (value < 0) | 280 if (value < 0) |
263 value = 0; | 281 value = 0; |
264 samples_->Accumulate(value, 1); | 282 samples_->Accumulate(value, 1); |
| 283 |
| 284 FindAndRunCallback(value); |
265 } | 285 } |
266 | 286 |
267 scoped_ptr<HistogramSamples> Histogram::SnapshotSamples() const { | 287 scoped_ptr<HistogramSamples> Histogram::SnapshotSamples() const { |
268 return SnapshotSampleVector().Pass(); | 288 return SnapshotSampleVector().Pass(); |
269 } | 289 } |
270 | 290 |
271 void Histogram::AddSamples(const HistogramSamples& samples) { | 291 void Histogram::AddSamples(const HistogramSamples& samples) { |
272 samples_->Add(samples); | 292 samples_->Add(samples); |
273 } | 293 } |
274 | 294 |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 HistogramBase* LinearHistogram::FactoryTimeGet(const std::string& name, | 544 HistogramBase* LinearHistogram::FactoryTimeGet(const std::string& name, |
525 TimeDelta minimum, | 545 TimeDelta minimum, |
526 TimeDelta maximum, | 546 TimeDelta maximum, |
527 size_t bucket_count, | 547 size_t bucket_count, |
528 int32 flags) { | 548 int32 flags) { |
529 return FactoryGet(name, static_cast<Sample>(minimum.InMilliseconds()), | 549 return FactoryGet(name, static_cast<Sample>(minimum.InMilliseconds()), |
530 static_cast<Sample>(maximum.InMilliseconds()), bucket_count, | 550 static_cast<Sample>(maximum.InMilliseconds()), bucket_count, |
531 flags); | 551 flags); |
532 } | 552 } |
533 | 553 |
| 554 HistogramBase* LinearHistogram::FactoryGet(const char* name, |
| 555 Sample minimum, |
| 556 Sample maximum, |
| 557 size_t bucket_count, |
| 558 int32 flags) { |
| 559 return FactoryGet(std::string(name), minimum, maximum, bucket_count, flags); |
| 560 } |
| 561 |
| 562 HistogramBase* LinearHistogram::FactoryTimeGet(const char* name, |
| 563 TimeDelta minimum, |
| 564 TimeDelta maximum, |
| 565 size_t bucket_count, |
| 566 int32 flags) { |
| 567 return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count, |
| 568 flags); |
| 569 } |
| 570 |
534 HistogramBase* LinearHistogram::FactoryGetWithRangeDescription( | 571 HistogramBase* LinearHistogram::FactoryGetWithRangeDescription( |
535 const std::string& name, | 572 const std::string& name, |
536 Sample minimum, | 573 Sample minimum, |
537 Sample maximum, | 574 Sample maximum, |
538 size_t bucket_count, | 575 size_t bucket_count, |
539 int32 flags, | 576 int32 flags, |
540 const DescriptionPair descriptions[]) { | 577 const DescriptionPair descriptions[]) { |
541 bool valid_arguments = Histogram::InspectConstructionArguments( | 578 bool valid_arguments = Histogram::InspectConstructionArguments( |
542 name, &minimum, &maximum, &bucket_count); | 579 name, &minimum, &maximum, &bucket_count); |
543 DCHECK(valid_arguments); | 580 DCHECK(valid_arguments); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 | 706 |
670 tentative_histogram->SetFlags(flags); | 707 tentative_histogram->SetFlags(flags); |
671 histogram = | 708 histogram = |
672 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); | 709 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); |
673 } | 710 } |
674 | 711 |
675 DCHECK_EQ(BOOLEAN_HISTOGRAM, histogram->GetHistogramType()); | 712 DCHECK_EQ(BOOLEAN_HISTOGRAM, histogram->GetHistogramType()); |
676 return histogram; | 713 return histogram; |
677 } | 714 } |
678 | 715 |
| 716 HistogramBase* BooleanHistogram::FactoryGet(const char* name, int32 flags) { |
| 717 return FactoryGet(std::string(name), flags); |
| 718 } |
| 719 |
679 HistogramType BooleanHistogram::GetHistogramType() const { | 720 HistogramType BooleanHistogram::GetHistogramType() const { |
680 return BOOLEAN_HISTOGRAM; | 721 return BOOLEAN_HISTOGRAM; |
681 } | 722 } |
682 | 723 |
683 BooleanHistogram::BooleanHistogram(const std::string& name, | 724 BooleanHistogram::BooleanHistogram(const std::string& name, |
684 const BucketRanges* ranges) | 725 const BucketRanges* ranges) |
685 : LinearHistogram(name, 1, 2, ranges) {} | 726 : LinearHistogram(name, 1, 2, ranges) {} |
686 | 727 |
687 HistogramBase* BooleanHistogram::DeserializeInfoImpl(PickleIterator* iter) { | 728 HistogramBase* BooleanHistogram::DeserializeInfoImpl(PickleIterator* iter) { |
688 std::string histogram_name; | 729 std::string histogram_name; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
729 tentative_histogram->SetFlags(flags); | 770 tentative_histogram->SetFlags(flags); |
730 | 771 |
731 histogram = | 772 histogram = |
732 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); | 773 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); |
733 } | 774 } |
734 | 775 |
735 DCHECK_EQ(histogram->GetHistogramType(), CUSTOM_HISTOGRAM); | 776 DCHECK_EQ(histogram->GetHistogramType(), CUSTOM_HISTOGRAM); |
736 return histogram; | 777 return histogram; |
737 } | 778 } |
738 | 779 |
| 780 HistogramBase* CustomHistogram::FactoryGet( |
| 781 const char* name, |
| 782 const std::vector<Sample>& custom_ranges, |
| 783 int32 flags) { |
| 784 return FactoryGet(std::string(name), custom_ranges, flags); |
| 785 } |
| 786 |
739 HistogramType CustomHistogram::GetHistogramType() const { | 787 HistogramType CustomHistogram::GetHistogramType() const { |
740 return CUSTOM_HISTOGRAM; | 788 return CUSTOM_HISTOGRAM; |
741 } | 789 } |
742 | 790 |
743 // static | 791 // static |
744 std::vector<Sample> CustomHistogram::ArrayToCustomRanges( | 792 std::vector<Sample> CustomHistogram::ArrayToCustomRanges( |
745 const Sample* values, size_t num_values) { | 793 const Sample* values, size_t num_values) { |
746 std::vector<Sample> all_values; | 794 std::vector<Sample> all_values; |
747 for (size_t i = 0; i < num_values; ++i) { | 795 for (size_t i = 0; i < num_values; ++i) { |
748 Sample value = values[i]; | 796 Sample value = values[i]; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
836 | 884 |
837 BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); | 885 BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); |
838 for (size_t i = 0; i < ranges.size(); i++) { | 886 for (size_t i = 0; i < ranges.size(); i++) { |
839 bucket_ranges->set_range(i, ranges[i]); | 887 bucket_ranges->set_range(i, ranges[i]); |
840 } | 888 } |
841 bucket_ranges->ResetChecksum(); | 889 bucket_ranges->ResetChecksum(); |
842 return bucket_ranges; | 890 return bucket_ranges; |
843 } | 891 } |
844 | 892 |
845 } // namespace base | 893 } // namespace base |
OLD | NEW |