| 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" |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 count += i; | 126 count += i; |
| 127 } | 127 } |
| 128 DCHECK_EQ(count, redundant_count_); | 128 DCHECK_EQ(count, redundant_count_); |
| 129 return count == redundant_count_; | 129 return count == redundant_count_; |
| 130 } | 130 } |
| 131 | 131 |
| 132 Histogram* Histogram::FactoryGet(const string& name, | 132 Histogram* Histogram::FactoryGet(const string& name, |
| 133 Sample minimum, | 133 Sample minimum, |
| 134 Sample maximum, | 134 Sample maximum, |
| 135 size_t bucket_count, | 135 size_t bucket_count, |
| 136 Flags flags) { | 136 int32 flags) { |
| 137 bool valid_arguments = | 137 bool valid_arguments = |
| 138 InspectConstructionArguments(name, &minimum, &maximum, &bucket_count); | 138 InspectConstructionArguments(name, &minimum, &maximum, &bucket_count); |
| 139 DCHECK(valid_arguments); | 139 DCHECK(valid_arguments); |
| 140 | 140 |
| 141 Histogram* histogram = StatisticsRecorder::FindHistogram(name); | 141 Histogram* histogram = StatisticsRecorder::FindHistogram(name); |
| 142 if (!histogram) { | 142 if (!histogram) { |
| 143 // To avoid racy destruction at shutdown, the following will be leaked. | 143 // To avoid racy destruction at shutdown, the following will be leaked. |
| 144 BucketRanges* ranges = new BucketRanges(bucket_count + 1); | 144 BucketRanges* ranges = new BucketRanges(bucket_count + 1); |
| 145 InitializeBucketRanges(minimum, maximum, bucket_count, ranges); | 145 InitializeBucketRanges(minimum, maximum, bucket_count, ranges); |
| 146 const BucketRanges* registered_ranges = | 146 const BucketRanges* registered_ranges = |
| 147 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); | 147 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); |
| 148 | 148 |
| 149 Histogram* tentative_histogram = | 149 Histogram* tentative_histogram = |
| 150 new Histogram(name, minimum, maximum, bucket_count, registered_ranges); | 150 new Histogram(name, minimum, maximum, bucket_count, registered_ranges); |
| 151 tentative_histogram->SetFlags(flags); | 151 tentative_histogram->SetFlags(flags); |
| 152 histogram = | 152 histogram = |
| 153 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); | 153 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); |
| 154 } | 154 } |
| 155 | 155 |
| 156 CHECK_EQ(HISTOGRAM, histogram->histogram_type()); | 156 CHECK_EQ(HISTOGRAM, histogram->histogram_type()); |
| 157 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count)); | 157 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count)); |
| 158 return histogram; | 158 return histogram; |
| 159 } | 159 } |
| 160 | 160 |
| 161 Histogram* Histogram::FactoryTimeGet(const string& name, | 161 Histogram* Histogram::FactoryTimeGet(const string& name, |
| 162 TimeDelta minimum, | 162 TimeDelta minimum, |
| 163 TimeDelta maximum, | 163 TimeDelta maximum, |
| 164 size_t bucket_count, | 164 size_t bucket_count, |
| 165 Flags flags) { | 165 int32 flags) { |
| 166 return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(), | 166 return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(), |
| 167 bucket_count, flags); | 167 bucket_count, flags); |
| 168 } | 168 } |
| 169 | 169 |
| 170 TimeTicks Histogram::DebugNow() { | 170 TimeTicks Histogram::DebugNow() { |
| 171 #ifndef NDEBUG | 171 #ifndef NDEBUG |
| 172 return TimeTicks::Now(); | 172 return TimeTicks::Now(); |
| 173 #else | 173 #else |
| 174 return TimeTicks(); | 174 return TimeTicks(); |
| 175 #endif | 175 #endif |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 Histogram::Histogram(const string& name, | 435 Histogram::Histogram(const string& name, |
| 436 Sample minimum, | 436 Sample minimum, |
| 437 Sample maximum, | 437 Sample maximum, |
| 438 size_t bucket_count, | 438 size_t bucket_count, |
| 439 const BucketRanges* ranges) | 439 const BucketRanges* ranges) |
| 440 : HistogramBase(name), | 440 : HistogramBase(name), |
| 441 bucket_ranges_(ranges), | 441 bucket_ranges_(ranges), |
| 442 declared_min_(minimum), | 442 declared_min_(minimum), |
| 443 declared_max_(maximum), | 443 declared_max_(maximum), |
| 444 bucket_count_(bucket_count), | 444 bucket_count_(bucket_count), |
| 445 flags_(kNoFlags), | |
| 446 sample_(bucket_count) {} | 445 sample_(bucket_count) {} |
| 447 | 446 |
| 448 Histogram::~Histogram() { | 447 Histogram::~Histogram() { |
| 449 if (StatisticsRecorder::dump_on_exit()) { | 448 if (StatisticsRecorder::dump_on_exit()) { |
| 450 string output; | 449 string output; |
| 451 WriteAsciiImpl(true, "\n", &output); | 450 WriteAsciiImpl(true, "\n", &output); |
| 452 DLOG(INFO) << output; | 451 DLOG(INFO) << output; |
| 453 } | 452 } |
| 454 } | 453 } |
| 455 | 454 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 DCHECK_GT(ranges(i + 1), ranges(i)); | 523 DCHECK_GT(ranges(i + 1), ranges(i)); |
| 525 static const double kTransitionWidth = 5; | 524 static const double kTransitionWidth = 5; |
| 526 double denominator = ranges(i + 1) - ranges(i); | 525 double denominator = ranges(i + 1) - ranges(i); |
| 527 if (denominator > kTransitionWidth) | 526 if (denominator > kTransitionWidth) |
| 528 denominator = kTransitionWidth; // Stop trying to normalize. | 527 denominator = kTransitionWidth; // Stop trying to normalize. |
| 529 return current/denominator; | 528 return current/denominator; |
| 530 } | 529 } |
| 531 | 530 |
| 532 const string Histogram::GetAsciiBucketRange(size_t i) const { | 531 const string Histogram::GetAsciiBucketRange(size_t i) const { |
| 533 string result; | 532 string result; |
| 534 if (kHexRangePrintingFlag & flags_) | 533 if (kHexRangePrintingFlag & flags()) |
| 535 StringAppendF(&result, "%#x", ranges(i)); | 534 StringAppendF(&result, "%#x", ranges(i)); |
| 536 else | 535 else |
| 537 StringAppendF(&result, "%d", ranges(i)); | 536 StringAppendF(&result, "%d", ranges(i)); |
| 538 return result; | 537 return result; |
| 539 } | 538 } |
| 540 | 539 |
| 541 // Update histogram data with new sample. | 540 // Update histogram data with new sample. |
| 542 void Histogram::Accumulate(Sample value, Count count, size_t index) { | 541 void Histogram::Accumulate(Sample value, Count count, size_t index) { |
| 543 // Note locking not done in this version!!! | 542 // Note locking not done in this version!!! |
| 544 sample_.Accumulate(value, count, index); | 543 sample_.Accumulate(value, count, index); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 "Histogram: %s recorded %d samples", | 628 "Histogram: %s recorded %d samples", |
| 630 histogram_name().c_str(), | 629 histogram_name().c_str(), |
| 631 sample_count); | 630 sample_count); |
| 632 if (0 == sample_count) { | 631 if (0 == sample_count) { |
| 633 DCHECK_EQ(snapshot.sum(), 0); | 632 DCHECK_EQ(snapshot.sum(), 0); |
| 634 } else { | 633 } else { |
| 635 double average = static_cast<float>(snapshot.sum()) / sample_count; | 634 double average = static_cast<float>(snapshot.sum()) / sample_count; |
| 636 | 635 |
| 637 StringAppendF(output, ", average = %.1f", average); | 636 StringAppendF(output, ", average = %.1f", average); |
| 638 } | 637 } |
| 639 if (flags_ & ~kHexRangePrintingFlag) | 638 if (flags() & ~kHexRangePrintingFlag) |
| 640 StringAppendF(output, " (flags = 0x%x)", flags_ & ~kHexRangePrintingFlag); | 639 StringAppendF(output, " (flags = 0x%x)", flags() & ~kHexRangePrintingFlag); |
| 641 } | 640 } |
| 642 | 641 |
| 643 void Histogram::WriteAsciiBucketContext(const int64 past, | 642 void Histogram::WriteAsciiBucketContext(const int64 past, |
| 644 const Count current, | 643 const Count current, |
| 645 const int64 remaining, | 644 const int64 remaining, |
| 646 const size_t i, | 645 const size_t i, |
| 647 string* output) const { | 646 string* output) const { |
| 648 double scaled_sum = (past + current + remaining) / 100.0; | 647 double scaled_sum = (past + current + remaining) / 100.0; |
| 649 WriteAsciiBucketValue(current, scaled_sum, output); | 648 WriteAsciiBucketValue(current, scaled_sum, output); |
| 650 if (0 < i) { | 649 if (0 < i) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 678 // LinearHistogram: This histogram uses a traditional set of evenly spaced | 677 // LinearHistogram: This histogram uses a traditional set of evenly spaced |
| 679 // buckets. | 678 // buckets. |
| 680 //------------------------------------------------------------------------------ | 679 //------------------------------------------------------------------------------ |
| 681 | 680 |
| 682 LinearHistogram::~LinearHistogram() {} | 681 LinearHistogram::~LinearHistogram() {} |
| 683 | 682 |
| 684 Histogram* LinearHistogram::FactoryGet(const string& name, | 683 Histogram* LinearHistogram::FactoryGet(const string& name, |
| 685 Sample minimum, | 684 Sample minimum, |
| 686 Sample maximum, | 685 Sample maximum, |
| 687 size_t bucket_count, | 686 size_t bucket_count, |
| 688 Flags flags) { | 687 int32 flags) { |
| 689 bool valid_arguments = Histogram::InspectConstructionArguments( | 688 bool valid_arguments = Histogram::InspectConstructionArguments( |
| 690 name, &minimum, &maximum, &bucket_count); | 689 name, &minimum, &maximum, &bucket_count); |
| 691 DCHECK(valid_arguments); | 690 DCHECK(valid_arguments); |
| 692 | 691 |
| 693 Histogram* histogram = StatisticsRecorder::FindHistogram(name); | 692 Histogram* histogram = StatisticsRecorder::FindHistogram(name); |
| 694 if (!histogram) { | 693 if (!histogram) { |
| 695 // To avoid racy destruction at shutdown, the following will be leaked. | 694 // To avoid racy destruction at shutdown, the following will be leaked. |
| 696 BucketRanges* ranges = new BucketRanges(bucket_count + 1); | 695 BucketRanges* ranges = new BucketRanges(bucket_count + 1); |
| 697 InitializeBucketRanges(minimum, maximum, bucket_count, ranges); | 696 InitializeBucketRanges(minimum, maximum, bucket_count, ranges); |
| 698 const BucketRanges* registered_ranges = | 697 const BucketRanges* registered_ranges = |
| 699 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); | 698 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); |
| 700 | 699 |
| 701 LinearHistogram* tentative_histogram = | 700 LinearHistogram* tentative_histogram = |
| 702 new LinearHistogram(name, minimum, maximum, bucket_count, | 701 new LinearHistogram(name, minimum, maximum, bucket_count, |
| 703 registered_ranges); | 702 registered_ranges); |
| 704 tentative_histogram->SetFlags(flags); | 703 tentative_histogram->SetFlags(flags); |
| 705 histogram = | 704 histogram = |
| 706 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); | 705 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); |
| 707 } | 706 } |
| 708 | 707 |
| 709 CHECK_EQ(LINEAR_HISTOGRAM, histogram->histogram_type()); | 708 CHECK_EQ(LINEAR_HISTOGRAM, histogram->histogram_type()); |
| 710 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count)); | 709 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count)); |
| 711 return histogram; | 710 return histogram; |
| 712 } | 711 } |
| 713 | 712 |
| 714 Histogram* LinearHistogram::FactoryTimeGet(const string& name, | 713 Histogram* LinearHistogram::FactoryTimeGet(const string& name, |
| 715 TimeDelta minimum, | 714 TimeDelta minimum, |
| 716 TimeDelta maximum, | 715 TimeDelta maximum, |
| 717 size_t bucket_count, | 716 size_t bucket_count, |
| 718 Flags flags) { | 717 int32 flags) { |
| 719 return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(), | 718 return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(), |
| 720 bucket_count, flags); | 719 bucket_count, flags); |
| 721 } | 720 } |
| 722 | 721 |
| 723 Histogram::ClassType LinearHistogram::histogram_type() const { | 722 Histogram::ClassType LinearHistogram::histogram_type() const { |
| 724 return LINEAR_HISTOGRAM; | 723 return LINEAR_HISTOGRAM; |
| 725 } | 724 } |
| 726 | 725 |
| 727 void LinearHistogram::SetRangeDescriptions( | 726 void LinearHistogram::SetRangeDescriptions( |
| 728 const DescriptionPair descriptions[]) { | 727 const DescriptionPair descriptions[]) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 774 ranges->set_range(i, static_cast<Sample>(linear_range + 0.5)); | 773 ranges->set_range(i, static_cast<Sample>(linear_range + 0.5)); |
| 775 } | 774 } |
| 776 ranges->set_range(ranges->size() - 1, HistogramBase::kSampleType_MAX); | 775 ranges->set_range(ranges->size() - 1, HistogramBase::kSampleType_MAX); |
| 777 ranges->ResetChecksum(); | 776 ranges->ResetChecksum(); |
| 778 } | 777 } |
| 779 | 778 |
| 780 //------------------------------------------------------------------------------ | 779 //------------------------------------------------------------------------------ |
| 781 // This section provides implementation for BooleanHistogram. | 780 // This section provides implementation for BooleanHistogram. |
| 782 //------------------------------------------------------------------------------ | 781 //------------------------------------------------------------------------------ |
| 783 | 782 |
| 784 Histogram* BooleanHistogram::FactoryGet(const string& name, Flags flags) { | 783 Histogram* BooleanHistogram::FactoryGet(const string& name, int32 flags) { |
| 785 Histogram* histogram = StatisticsRecorder::FindHistogram(name); | 784 Histogram* histogram = StatisticsRecorder::FindHistogram(name); |
| 786 if (!histogram) { | 785 if (!histogram) { |
| 787 // To avoid racy destruction at shutdown, the following will be leaked. | 786 // To avoid racy destruction at shutdown, the following will be leaked. |
| 788 BucketRanges* ranges = new BucketRanges(4); | 787 BucketRanges* ranges = new BucketRanges(4); |
| 789 LinearHistogram::InitializeBucketRanges(1, 2, 3, ranges); | 788 LinearHistogram::InitializeBucketRanges(1, 2, 3, ranges); |
| 790 const BucketRanges* registered_ranges = | 789 const BucketRanges* registered_ranges = |
| 791 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); | 790 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); |
| 792 | 791 |
| 793 BooleanHistogram* tentative_histogram = | 792 BooleanHistogram* tentative_histogram = |
| 794 new BooleanHistogram(name, registered_ranges); | 793 new BooleanHistogram(name, registered_ranges); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 812 BooleanHistogram::BooleanHistogram(const string& name, | 811 BooleanHistogram::BooleanHistogram(const string& name, |
| 813 const BucketRanges* ranges) | 812 const BucketRanges* ranges) |
| 814 : LinearHistogram(name, 1, 2, 3, ranges) {} | 813 : LinearHistogram(name, 1, 2, 3, ranges) {} |
| 815 | 814 |
| 816 //------------------------------------------------------------------------------ | 815 //------------------------------------------------------------------------------ |
| 817 // CustomHistogram: | 816 // CustomHistogram: |
| 818 //------------------------------------------------------------------------------ | 817 //------------------------------------------------------------------------------ |
| 819 | 818 |
| 820 Histogram* CustomHistogram::FactoryGet(const string& name, | 819 Histogram* CustomHistogram::FactoryGet(const string& name, |
| 821 const vector<Sample>& custom_ranges, | 820 const vector<Sample>& custom_ranges, |
| 822 Flags flags) { | 821 int32 flags) { |
| 823 CHECK(ValidateCustomRanges(custom_ranges)); | 822 CHECK(ValidateCustomRanges(custom_ranges)); |
| 824 | 823 |
| 825 Histogram* histogram = StatisticsRecorder::FindHistogram(name); | 824 Histogram* histogram = StatisticsRecorder::FindHistogram(name); |
| 826 if (!histogram) { | 825 if (!histogram) { |
| 827 BucketRanges* ranges = CreateBucketRangesFromCustomRanges(custom_ranges); | 826 BucketRanges* ranges = CreateBucketRangesFromCustomRanges(custom_ranges); |
| 828 const BucketRanges* registered_ranges = | 827 const BucketRanges* registered_ranges = |
| 829 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); | 828 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); |
| 830 | 829 |
| 831 // To avoid racy destruction at shutdown, the following will be leaked. | 830 // To avoid racy destruction at shutdown, the following will be leaked. |
| 832 CustomHistogram* tentative_histogram = | 831 CustomHistogram* tentative_histogram = |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 916 | 915 |
| 917 BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); | 916 BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); |
| 918 for (size_t i = 0; i < ranges.size(); i++) { | 917 for (size_t i = 0; i < ranges.size(); i++) { |
| 919 bucket_ranges->set_range(i, ranges[i]); | 918 bucket_ranges->set_range(i, ranges[i]); |
| 920 } | 919 } |
| 921 bucket_ranges->ResetChecksum(); | 920 bucket_ranges->ResetChecksum(); |
| 922 return bucket_ranges; | 921 return bucket_ranges; |
| 923 } | 922 } |
| 924 | 923 |
| 925 } // namespace base | 924 } // namespace base |
| OLD | NEW |