OLD | NEW |
1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2010 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/histogram.h" | 10 #include "base/histogram.h" |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 if (StatisticsRecorder::dump_on_exit()) { | 77 if (StatisticsRecorder::dump_on_exit()) { |
78 std::string output; | 78 std::string output; |
79 WriteAscii(true, "\n", &output); | 79 WriteAscii(true, "\n", &output); |
80 LOG(INFO) << output; | 80 LOG(INFO) << output; |
81 } | 81 } |
82 | 82 |
83 // Just to make sure most derived class did this properly... | 83 // Just to make sure most derived class did this properly... |
84 DCHECK(ValidateBucketRanges()); | 84 DCHECK(ValidateBucketRanges()); |
85 } | 85 } |
86 | 86 |
| 87 bool Histogram::PrintEmptyBucket(size_t index) const { |
| 88 return true; |
| 89 } |
| 90 |
87 void Histogram::Add(int value) { | 91 void Histogram::Add(int value) { |
88 if (value >= kSampleType_MAX) | 92 if (value >= kSampleType_MAX) |
89 value = kSampleType_MAX - 1; | 93 value = kSampleType_MAX - 1; |
90 if (value < 0) | 94 if (value < 0) |
91 value = 0; | 95 value = 0; |
92 size_t index = BucketIndex(value); | 96 size_t index = BucketIndex(value); |
93 DCHECK(value >= ranges(index)); | 97 DCHECK(value >= ranges(index)); |
94 DCHECK(value < ranges(index + 1)); | 98 DCHECK(value < ranges(index + 1)); |
95 Accumulate(value, 1, index); | 99 Accumulate(value, 1, index); |
96 } | 100 } |
97 | 101 |
| 102 void Histogram::AddBoolean(bool value) { |
| 103 DCHECK(false); |
| 104 } |
| 105 |
98 void Histogram::AddSampleSet(const SampleSet& sample) { | 106 void Histogram::AddSampleSet(const SampleSet& sample) { |
99 sample_.Add(sample); | 107 sample_.Add(sample); |
100 } | 108 } |
101 | 109 |
| 110 void Histogram::SetRangeDescriptions(const DescriptionPair descriptions[]) { |
| 111 DCHECK(false); |
| 112 } |
| 113 |
102 // The following methods provide a graphical histogram display. | 114 // The following methods provide a graphical histogram display. |
103 void Histogram::WriteHTMLGraph(std::string* output) const { | 115 void Histogram::WriteHTMLGraph(std::string* output) const { |
104 // TBD(jar) Write a nice HTML bar chart, with divs an mouse-overs etc. | 116 // TBD(jar) Write a nice HTML bar chart, with divs an mouse-overs etc. |
105 output->append("<PRE>"); | 117 output->append("<PRE>"); |
106 WriteAscii(true, "<br>", output); | 118 WriteAscii(true, "<br>", output); |
107 output->append("</PRE>"); | 119 output->append("</PRE>"); |
108 } | 120 } |
109 | 121 |
110 void Histogram::WriteAscii(bool graph_it, const std::string& newline, | 122 void Histogram::WriteAscii(bool graph_it, const std::string& newline, |
111 std::string* output) const { | 123 std::string* output) const { |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 sample_.Accumulate(value, count, index); | 295 sample_.Accumulate(value, count, index); |
284 } | 296 } |
285 | 297 |
286 // Do a safe atomic snapshot of sample data. | 298 // Do a safe atomic snapshot of sample data. |
287 // This implementation assumes we are on a safe single thread. | 299 // This implementation assumes we are on a safe single thread. |
288 void Histogram::SnapshotSample(SampleSet* sample) const { | 300 void Histogram::SnapshotSample(SampleSet* sample) const { |
289 // Note locking not done in this version!!! | 301 // Note locking not done in this version!!! |
290 *sample = sample_; | 302 *sample = sample_; |
291 } | 303 } |
292 | 304 |
| 305 bool Histogram::HasConstructorArguments(Sample minimum, Sample maximum, |
| 306 size_t bucket_count) { |
| 307 return ((minimum == declared_min_) && (maximum == declared_max_) && |
| 308 (bucket_count == bucket_count_)); |
| 309 } |
| 310 |
| 311 bool Histogram::HasConstructorTimeDeltaArguments(base::TimeDelta minimum, |
| 312 base::TimeDelta maximum, |
| 313 size_t bucket_count) { |
| 314 return ((minimum.InMilliseconds() == declared_min_) && |
| 315 (maximum.InMilliseconds() == declared_max_) && |
| 316 (bucket_count == bucket_count_)); |
| 317 } |
| 318 |
293 //------------------------------------------------------------------------------ | 319 //------------------------------------------------------------------------------ |
294 // Accessor methods | 320 // Accessor methods |
295 | 321 |
296 void Histogram::SetBucketRange(size_t i, Sample value) { | 322 void Histogram::SetBucketRange(size_t i, Sample value) { |
297 DCHECK(bucket_count_ > i); | 323 DCHECK(bucket_count_ > i); |
298 ranges_[i] = value; | 324 ranges_[i] = value; |
299 } | 325 } |
300 | 326 |
301 //------------------------------------------------------------------------------ | 327 //------------------------------------------------------------------------------ |
302 // Private methods | 328 // Private methods |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 LinearHistogram::LinearHistogram(const std::string& name, | 632 LinearHistogram::LinearHistogram(const std::string& name, |
607 TimeDelta minimum, TimeDelta maximum, size_t bucket_count) | 633 TimeDelta minimum, TimeDelta maximum, size_t bucket_count) |
608 : Histogram(name, minimum >= TimeDelta::FromMilliseconds(1) ? | 634 : Histogram(name, minimum >= TimeDelta::FromMilliseconds(1) ? |
609 minimum : TimeDelta::FromMilliseconds(1), | 635 minimum : TimeDelta::FromMilliseconds(1), |
610 maximum, bucket_count) { | 636 maximum, bucket_count) { |
611 // Do a "better" (different) job at init than a base classes did... | 637 // Do a "better" (different) job at init than a base classes did... |
612 InitializeBucketRange(); | 638 InitializeBucketRange(); |
613 DCHECK(ValidateBucketRanges()); | 639 DCHECK(ValidateBucketRanges()); |
614 } | 640 } |
615 | 641 |
| 642 Histogram::ClassType LinearHistogram::histogram_type() const { |
| 643 return LINEAR_HISTOGRAM; |
| 644 } |
| 645 |
616 void LinearHistogram::SetRangeDescriptions( | 646 void LinearHistogram::SetRangeDescriptions( |
617 const DescriptionPair descriptions[]) { | 647 const DescriptionPair descriptions[]) { |
618 for (int i =0; descriptions[i].description; ++i) { | 648 for (int i =0; descriptions[i].description; ++i) { |
619 bucket_description_[descriptions[i].sample] = descriptions[i].description; | 649 bucket_description_[descriptions[i].sample] = descriptions[i].description; |
620 } | 650 } |
621 } | 651 } |
622 | 652 |
623 const std::string LinearHistogram::GetAsciiBucketRange(size_t i) const { | 653 const std::string LinearHistogram::GetAsciiBucketRange(size_t i) const { |
624 int range = ranges(i); | 654 int range = ranges(i); |
625 BucketDescriptionMap::const_iterator it = bucket_description_.find(range); | 655 BucketDescriptionMap::const_iterator it = bucket_description_.find(range); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 if (!StatisticsRecorder::FindHistogram(name, &histogram)) { | 694 if (!StatisticsRecorder::FindHistogram(name, &histogram)) { |
665 histogram = new BooleanHistogram(name); | 695 histogram = new BooleanHistogram(name); |
666 StatisticsRecorder::FindHistogram(name, &histogram); | 696 StatisticsRecorder::FindHistogram(name, &histogram); |
667 } | 697 } |
668 | 698 |
669 DCHECK(BOOLEAN_HISTOGRAM == histogram->histogram_type()); | 699 DCHECK(BOOLEAN_HISTOGRAM == histogram->histogram_type()); |
670 histogram->SetFlags(flags); | 700 histogram->SetFlags(flags); |
671 return histogram; | 701 return histogram; |
672 } | 702 } |
673 | 703 |
| 704 Histogram::ClassType BooleanHistogram::histogram_type() const { |
| 705 return BOOLEAN_HISTOGRAM; |
| 706 } |
| 707 |
| 708 void BooleanHistogram::AddBoolean(bool value) { |
| 709 Add(value ? 1 : 0); |
| 710 } |
| 711 |
| 712 BooleanHistogram::BooleanHistogram(const std::string& name) |
| 713 : LinearHistogram(name, 1, 2, 3) { |
| 714 } |
674 | 715 |
675 //------------------------------------------------------------------------------ | 716 //------------------------------------------------------------------------------ |
676 // CustomHistogram: | 717 // CustomHistogram: |
677 //------------------------------------------------------------------------------ | 718 //------------------------------------------------------------------------------ |
678 | 719 |
679 scoped_refptr<Histogram> CustomHistogram::FactoryGet( | 720 scoped_refptr<Histogram> CustomHistogram::FactoryGet( |
680 const std::string& name, const std::vector<int>& custom_ranges, | 721 const std::string& name, const std::vector<int>& custom_ranges, |
681 Flags flags) { | 722 Flags flags) { |
682 scoped_refptr<Histogram> histogram(NULL); | 723 scoped_refptr<Histogram> histogram(NULL); |
683 | 724 |
(...skipping 15 matching lines...) Expand all Loading... |
699 StatisticsRecorder::FindHistogram(name, &histogram); | 740 StatisticsRecorder::FindHistogram(name, &histogram); |
700 } | 741 } |
701 | 742 |
702 DCHECK_EQ(histogram->histogram_type(), CUSTOM_HISTOGRAM); | 743 DCHECK_EQ(histogram->histogram_type(), CUSTOM_HISTOGRAM); |
703 DCHECK(histogram->HasConstructorArguments(ranges[1], ranges.back(), | 744 DCHECK(histogram->HasConstructorArguments(ranges[1], ranges.back(), |
704 ranges.size())); | 745 ranges.size())); |
705 histogram->SetFlags(flags); | 746 histogram->SetFlags(flags); |
706 return histogram; | 747 return histogram; |
707 } | 748 } |
708 | 749 |
| 750 Histogram::ClassType CustomHistogram::histogram_type() const { |
| 751 return CUSTOM_HISTOGRAM; |
| 752 } |
| 753 |
709 CustomHistogram::CustomHistogram(const std::string& name, | 754 CustomHistogram::CustomHistogram(const std::string& name, |
710 const std::vector<int>& custom_ranges) | 755 const std::vector<int>& custom_ranges) |
711 : Histogram(name, custom_ranges[1], custom_ranges.back(), | 756 : Histogram(name, custom_ranges[1], custom_ranges.back(), |
712 custom_ranges.size()) { | 757 custom_ranges.size()) { |
713 DCHECK_GT(custom_ranges.size(), 1u); | 758 DCHECK_GT(custom_ranges.size(), 1u); |
714 DCHECK_EQ(custom_ranges[0], 0); | 759 DCHECK_EQ(custom_ranges[0], 0); |
715 ranges_vector_ = &custom_ranges; | 760 ranges_vector_ = &custom_ranges; |
716 InitializeBucketRange(); | 761 InitializeBucketRange(); |
717 ranges_vector_ = NULL; | 762 ranges_vector_ = NULL; |
718 DCHECK(ValidateBucketRanges()); | 763 DCHECK(ValidateBucketRanges()); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
860 snapshot->push_back(it->second); | 905 snapshot->push_back(it->second); |
861 } | 906 } |
862 } | 907 } |
863 | 908 |
864 // static | 909 // static |
865 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; | 910 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; |
866 // static | 911 // static |
867 Lock* StatisticsRecorder::lock_ = NULL; | 912 Lock* StatisticsRecorder::lock_ = NULL; |
868 // static | 913 // static |
869 bool StatisticsRecorder::dump_on_exit_ = false; | 914 bool StatisticsRecorder::dump_on_exit_ = false; |
OLD | NEW |