Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(286)

Side by Side Diff: base/metrics/histogram.cc

Issue 10830156: Skeleton code of SparseHistogram (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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 CHECK(InspectConstructionArguments(name, &minimum, &maximum, &bucket_count)); 137 CHECK(InspectConstructionArguments(name, &minimum, &maximum, &bucket_count));
138 138
139 Histogram* histogram = StatisticsRecorder::FindHistogram(name); 139 Histogram* histogram = StatisticsRecorder::FindHistogram(name);
140 if (!histogram) { 140 if (!histogram) {
141 // To avoid racy destruction at shutdown, the following will be leaked. 141 // To avoid racy destruction at shutdown, the following will be leaked.
142 BucketRanges* ranges = new BucketRanges(bucket_count + 1); 142 BucketRanges* ranges = new BucketRanges(bucket_count + 1);
143 InitializeBucketRanges(minimum, maximum, bucket_count, ranges); 143 InitializeBucketRanges(minimum, maximum, bucket_count, ranges);
144 const BucketRanges* registered_ranges = 144 const BucketRanges* registered_ranges =
145 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); 145 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
146 146
147 Histogram* tentative_histogram = 147 Histogram* tentative_histogram =
148 new Histogram(name, minimum, maximum, bucket_count, registered_ranges); 148 new Histogram(name, minimum, maximum, bucket_count, registered_ranges);
149 tentative_histogram->SetFlags(flags); 149 tentative_histogram->SetFlags(flags);
150 histogram = 150 histogram =
151 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); 151 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
152 } 152 }
153 153
154 CHECK_EQ(HISTOGRAM, histogram->histogram_type()); 154 CHECK_EQ(HISTOGRAM, histogram->histogram_type());
155 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count)); 155 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count));
156 return histogram; 156 return histogram;
157 } 157 }
158 158
159 Histogram* Histogram::FactoryTimeGet(const string& name, 159 Histogram* Histogram::FactoryTimeGet(const string& name,
160 TimeDelta minimum, 160 TimeDelta minimum,
161 TimeDelta maximum, 161 TimeDelta maximum,
162 size_t bucket_count, 162 size_t bucket_count,
163 Flags flags) { 163 int32 flags) {
164 return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(), 164 return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(),
165 bucket_count, flags); 165 bucket_count, flags);
166 } 166 }
167 167
168 TimeTicks Histogram::DebugNow() { 168 TimeTicks Histogram::DebugNow() {
169 #ifndef NDEBUG 169 #ifndef NDEBUG
170 return TimeTicks::Now(); 170 return TimeTicks::Now();
171 #else 171 #else
172 return TimeTicks(); 172 return TimeTicks();
173 #endif 173 #endif
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 Histogram::Histogram(const string& name, 433 Histogram::Histogram(const string& name,
434 Sample minimum, 434 Sample minimum,
435 Sample maximum, 435 Sample maximum,
436 size_t bucket_count, 436 size_t bucket_count,
437 const BucketRanges* ranges) 437 const BucketRanges* ranges)
438 : HistogramBase(name), 438 : HistogramBase(name),
439 bucket_ranges_(ranges), 439 bucket_ranges_(ranges),
440 declared_min_(minimum), 440 declared_min_(minimum),
441 declared_max_(maximum), 441 declared_max_(maximum),
442 bucket_count_(bucket_count), 442 bucket_count_(bucket_count),
443 flags_(kNoFlags),
444 sample_(bucket_count) {} 443 sample_(bucket_count) {}
445 444
446 Histogram::~Histogram() { 445 Histogram::~Histogram() {
447 if (StatisticsRecorder::dump_on_exit()) { 446 if (StatisticsRecorder::dump_on_exit()) {
448 string output; 447 string output;
449 WriteAsciiImpl(true, "\n", &output); 448 WriteAsciiImpl(true, "\n", &output);
450 DLOG(INFO) << output; 449 DLOG(INFO) << output;
451 } 450 }
452 } 451 }
453 452
454 // static 453 // static
455 bool Histogram::InspectConstructionArguments(const string& name, 454 bool Histogram::InspectConstructionArguments(const string& name,
456 Sample* minimum, 455 Sample* minimum,
457 Sample* maximum, 456 Sample* maximum,
458 size_t* bucket_count) { 457 size_t* bucket_count) {
459 // Defensive code for backward compatibility. 458 // Defensive code for backward compatibility.
460 if (*minimum < 1) { 459 if (*minimum < 1) {
461 DVLOG(1) << "Histogram: " << name << " has bad minimum: " << *minimum; 460 DVLOG(1) << "Histogram: " << name << " has bad minimum: " << *minimum;
462 *minimum = 1; 461 *minimum = 1;
463 } 462 }
464 if (*maximum >= kSampleType_MAX) { 463 if (*maximum >= kSampleType_MAX) {
465 DVLOG(1) << "Histogram: " << name << " has bad maximum: " << *maximum; 464 DVLOG(1) << "Histogram: " << name << " has bad maximum: " << *maximum;
466 *maximum = kSampleType_MAX - 1; 465 *maximum = kSampleType_MAX;
Ilya Sherman 2012/08/04 01:18:35 This doesn't seem right -- kSampleType_MAX fails t
kaiwang 2012/08/08 03:59:33 Good catch! It's fixed in another CL
Ilya Sherman 2012/08/08 05:00:29 Ok. In that case, can you move this change into t
kaiwang 2012/08/08 22:17:08 That's already submitted
Ilya Sherman 2012/08/08 22:49:40 Could you rebase this CL, then? It's still showin
kaiwang 2012/08/08 23:03:37 See patch set 4
467 } 466 }
468 467
469 if (*bucket_count < 3 || *bucket_count >= kBucketCount_MAX) 468 if (*bucket_count < 3 || *bucket_count >= kBucketCount_MAX)
470 return false; 469 return false;
471 if (*bucket_count > static_cast<size_t>(*maximum - *minimum + 2)) 470 if (*bucket_count > static_cast<size_t>(*maximum - *minimum + 2))
472 return false; 471 return false;
473 return true; 472 return true;
474 } 473 }
475 474
476 bool Histogram::SerializeRanges(Pickle* pickle) const { 475 bool Histogram::SerializeRanges(Pickle* pickle) const {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 DCHECK_GT(ranges(i + 1), ranges(i)); 514 DCHECK_GT(ranges(i + 1), ranges(i));
516 static const double kTransitionWidth = 5; 515 static const double kTransitionWidth = 5;
517 double denominator = ranges(i + 1) - ranges(i); 516 double denominator = ranges(i + 1) - ranges(i);
518 if (denominator > kTransitionWidth) 517 if (denominator > kTransitionWidth)
519 denominator = kTransitionWidth; // Stop trying to normalize. 518 denominator = kTransitionWidth; // Stop trying to normalize.
520 return current/denominator; 519 return current/denominator;
521 } 520 }
522 521
523 const string Histogram::GetAsciiBucketRange(size_t i) const { 522 const string Histogram::GetAsciiBucketRange(size_t i) const {
524 string result; 523 string result;
525 if (kHexRangePrintingFlag & flags_) 524 if (kHexRangePrintingFlag & flags())
526 StringAppendF(&result, "%#x", ranges(i)); 525 StringAppendF(&result, "%#x", ranges(i));
527 else 526 else
528 StringAppendF(&result, "%d", ranges(i)); 527 StringAppendF(&result, "%d", ranges(i));
529 return result; 528 return result;
530 } 529 }
531 530
532 // Update histogram data with new sample. 531 // Update histogram data with new sample.
533 void Histogram::Accumulate(Sample value, Count count, size_t index) { 532 void Histogram::Accumulate(Sample value, Count count, size_t index) {
534 // Note locking not done in this version!!! 533 // Note locking not done in this version!!!
535 sample_.Accumulate(value, count, index); 534 sample_.Accumulate(value, count, index);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 "Histogram: %s recorded %d samples", 619 "Histogram: %s recorded %d samples",
621 histogram_name().c_str(), 620 histogram_name().c_str(),
622 sample_count); 621 sample_count);
623 if (0 == sample_count) { 622 if (0 == sample_count) {
624 DCHECK_EQ(snapshot.sum(), 0); 623 DCHECK_EQ(snapshot.sum(), 0);
625 } else { 624 } else {
626 double average = static_cast<float>(snapshot.sum()) / sample_count; 625 double average = static_cast<float>(snapshot.sum()) / sample_count;
627 626
628 StringAppendF(output, ", average = %.1f", average); 627 StringAppendF(output, ", average = %.1f", average);
629 } 628 }
630 if (flags_ & ~kHexRangePrintingFlag) 629 if (flags() & ~kHexRangePrintingFlag)
631 StringAppendF(output, " (flags = 0x%x)", flags_ & ~kHexRangePrintingFlag); 630 StringAppendF(output, " (flags = 0x%x)", flags() & ~kHexRangePrintingFlag);
632 } 631 }
633 632
634 void Histogram::WriteAsciiBucketContext(const int64 past, 633 void Histogram::WriteAsciiBucketContext(const int64 past,
635 const Count current, 634 const Count current,
636 const int64 remaining, 635 const int64 remaining,
637 const size_t i, 636 const size_t i,
638 string* output) const { 637 string* output) const {
639 double scaled_sum = (past + current + remaining) / 100.0; 638 double scaled_sum = (past + current + remaining) / 100.0;
640 WriteAsciiBucketValue(current, scaled_sum, output); 639 WriteAsciiBucketValue(current, scaled_sum, output);
641 if (0 < i) { 640 if (0 < i) {
(...skipping 27 matching lines...) Expand all
669 // LinearHistogram: This histogram uses a traditional set of evenly spaced 668 // LinearHistogram: This histogram uses a traditional set of evenly spaced
670 // buckets. 669 // buckets.
671 //------------------------------------------------------------------------------ 670 //------------------------------------------------------------------------------
672 671
673 LinearHistogram::~LinearHistogram() {} 672 LinearHistogram::~LinearHistogram() {}
674 673
675 Histogram* LinearHistogram::FactoryGet(const string& name, 674 Histogram* LinearHistogram::FactoryGet(const string& name,
676 Sample minimum, 675 Sample minimum,
677 Sample maximum, 676 Sample maximum,
678 size_t bucket_count, 677 size_t bucket_count,
679 Flags flags) { 678 int32 flags) {
680 CHECK(Histogram::InspectConstructionArguments(name, &minimum, &maximum, 679 CHECK(Histogram::InspectConstructionArguments(name, &minimum, &maximum,
681 &bucket_count)); 680 &bucket_count));
682 681
683 Histogram* histogram = StatisticsRecorder::FindHistogram(name); 682 Histogram* histogram = StatisticsRecorder::FindHistogram(name);
684 if (!histogram) { 683 if (!histogram) {
685 // To avoid racy destruction at shutdown, the following will be leaked. 684 // To avoid racy destruction at shutdown, the following will be leaked.
686 BucketRanges* ranges = new BucketRanges(bucket_count + 1); 685 BucketRanges* ranges = new BucketRanges(bucket_count + 1);
687 InitializeBucketRanges(minimum, maximum, bucket_count, ranges); 686 InitializeBucketRanges(minimum, maximum, bucket_count, ranges);
688 const BucketRanges* registered_ranges = 687 const BucketRanges* registered_ranges =
689 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); 688 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
690 689
691 LinearHistogram* tentative_histogram = 690 LinearHistogram* tentative_histogram =
692 new LinearHistogram(name, minimum, maximum, bucket_count, 691 new LinearHistogram(name, minimum, maximum, bucket_count,
693 registered_ranges); 692 registered_ranges);
694 tentative_histogram->SetFlags(flags); 693 tentative_histogram->SetFlags(flags);
695 histogram = 694 histogram =
696 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); 695 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
697 } 696 }
698 697
699 CHECK_EQ(LINEAR_HISTOGRAM, histogram->histogram_type()); 698 CHECK_EQ(LINEAR_HISTOGRAM, histogram->histogram_type());
700 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count)); 699 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count));
701 return histogram; 700 return histogram;
702 } 701 }
703 702
704 Histogram* LinearHistogram::FactoryTimeGet(const string& name, 703 Histogram* LinearHistogram::FactoryTimeGet(const string& name,
705 TimeDelta minimum, 704 TimeDelta minimum,
706 TimeDelta maximum, 705 TimeDelta maximum,
707 size_t bucket_count, 706 size_t bucket_count,
708 Flags flags) { 707 int32 flags) {
709 return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(), 708 return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(),
710 bucket_count, flags); 709 bucket_count, flags);
711 } 710 }
712 711
713 Histogram::ClassType LinearHistogram::histogram_type() const { 712 Histogram::ClassType LinearHistogram::histogram_type() const {
714 return LINEAR_HISTOGRAM; 713 return LINEAR_HISTOGRAM;
715 } 714 }
716 715
717 void LinearHistogram::SetRangeDescriptions( 716 void LinearHistogram::SetRangeDescriptions(
718 const DescriptionPair descriptions[]) { 717 const DescriptionPair descriptions[]) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 ranges->set_range(i, static_cast<Sample>(linear_range + 0.5)); 763 ranges->set_range(i, static_cast<Sample>(linear_range + 0.5));
765 } 764 }
766 ranges->set_range(ranges->size() - 1, HistogramBase::kSampleType_MAX); 765 ranges->set_range(ranges->size() - 1, HistogramBase::kSampleType_MAX);
767 ranges->ResetChecksum(); 766 ranges->ResetChecksum();
768 } 767 }
769 768
770 //------------------------------------------------------------------------------ 769 //------------------------------------------------------------------------------
771 // This section provides implementation for BooleanHistogram. 770 // This section provides implementation for BooleanHistogram.
772 //------------------------------------------------------------------------------ 771 //------------------------------------------------------------------------------
773 772
774 Histogram* BooleanHistogram::FactoryGet(const string& name, Flags flags) { 773 Histogram* BooleanHistogram::FactoryGet(const string& name, int32 flags) {
775 Histogram* histogram = StatisticsRecorder::FindHistogram(name); 774 Histogram* histogram = StatisticsRecorder::FindHistogram(name);
776 if (!histogram) { 775 if (!histogram) {
777 // To avoid racy destruction at shutdown, the following will be leaked. 776 // To avoid racy destruction at shutdown, the following will be leaked.
778 BucketRanges* ranges = new BucketRanges(4); 777 BucketRanges* ranges = new BucketRanges(4);
779 LinearHistogram::InitializeBucketRanges(1, 2, 3, ranges); 778 LinearHistogram::InitializeBucketRanges(1, 2, 3, ranges);
780 const BucketRanges* registered_ranges = 779 const BucketRanges* registered_ranges =
781 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); 780 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
782 781
783 BooleanHistogram* tentative_histogram = 782 BooleanHistogram* tentative_histogram =
784 new BooleanHistogram(name, registered_ranges); 783 new BooleanHistogram(name, registered_ranges);
(...skipping 17 matching lines...) Expand all
802 BooleanHistogram::BooleanHistogram(const string& name, 801 BooleanHistogram::BooleanHistogram(const string& name,
803 const BucketRanges* ranges) 802 const BucketRanges* ranges)
804 : LinearHistogram(name, 1, 2, 3, ranges) {} 803 : LinearHistogram(name, 1, 2, 3, ranges) {}
805 804
806 //------------------------------------------------------------------------------ 805 //------------------------------------------------------------------------------
807 // CustomHistogram: 806 // CustomHistogram:
808 //------------------------------------------------------------------------------ 807 //------------------------------------------------------------------------------
809 808
810 Histogram* CustomHistogram::FactoryGet(const string& name, 809 Histogram* CustomHistogram::FactoryGet(const string& name,
811 const vector<Sample>& custom_ranges, 810 const vector<Sample>& custom_ranges,
812 Flags flags) { 811 int32 flags) {
813 CHECK(ValidateCustomRanges(custom_ranges)); 812 CHECK(ValidateCustomRanges(custom_ranges));
814 813
815 Histogram* histogram = StatisticsRecorder::FindHistogram(name); 814 Histogram* histogram = StatisticsRecorder::FindHistogram(name);
816 if (!histogram) { 815 if (!histogram) {
817 BucketRanges* ranges = CreateBucketRangesFromCustomRanges(custom_ranges); 816 BucketRanges* ranges = CreateBucketRangesFromCustomRanges(custom_ranges);
818 const BucketRanges* registered_ranges = 817 const BucketRanges* registered_ranges =
819 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); 818 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
820 819
821 // To avoid racy destruction at shutdown, the following will be leaked. 820 // To avoid racy destruction at shutdown, the following will be leaked.
822 CustomHistogram* tentative_histogram = 821 CustomHistogram* tentative_histogram =
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 904
906 BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); 905 BucketRanges* bucket_ranges = new BucketRanges(ranges.size());
907 for (size_t i = 0; i < ranges.size(); i++) { 906 for (size_t i = 0; i < ranges.size(); i++) {
908 bucket_ranges->set_range(i, ranges[i]); 907 bucket_ranges->set_range(i, ranges[i]);
909 } 908 }
910 bucket_ranges->ResetChecksum(); 909 bucket_ranges->ResetChecksum();
911 return bucket_ranges; 910 return bucket_ranges;
912 } 911 }
913 912
914 } // namespace base 913 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698