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 |