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