| 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 |