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

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

Issue 10809076: Move CachedRanges out and add support for checksum. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 5 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
« no previous file with comments | « base/metrics/histogram.h ('k') | base/metrics/histogram_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 } 376 }
377 } 377 }
378 return static_cast<Inconsistencies>(inconsistencies); 378 return static_cast<Inconsistencies>(inconsistencies);
379 } 379 }
380 380
381 Histogram::ClassType Histogram::histogram_type() const { 381 Histogram::ClassType Histogram::histogram_type() const {
382 return HISTOGRAM; 382 return HISTOGRAM;
383 } 383 }
384 384
385 Histogram::Sample Histogram::ranges(size_t i) const { 385 Histogram::Sample Histogram::ranges(size_t i) const {
386 return cached_ranges_->ranges(i); 386 return bucket_ranges_->range(i);
387 } 387 }
388 388
389 size_t Histogram::bucket_count() const { 389 size_t Histogram::bucket_count() const {
390 return bucket_count_; 390 return bucket_count_;
391 } 391 }
392 392
393 // Do a safe atomic snapshot of sample data. 393 // Do a safe atomic snapshot of sample data.
394 // This implementation assumes we are on a safe single thread. 394 // This implementation assumes we are on a safe single thread.
395 void Histogram::SnapshotSample(SampleSet* sample) const { 395 void Histogram::SnapshotSample(SampleSet* sample) const {
396 // Note locking not done in this version!!! 396 // Note locking not done in this version!!!
(...skipping 19 matching lines...) Expand all
416 return CalculateRangeChecksum() == range_checksum_; 416 return CalculateRangeChecksum() == range_checksum_;
417 } 417 }
418 418
419 Histogram::Histogram(const std::string& name, Sample minimum, 419 Histogram::Histogram(const std::string& name, Sample minimum,
420 Sample maximum, size_t bucket_count) 420 Sample maximum, size_t bucket_count)
421 : HistogramBase(name), 421 : HistogramBase(name),
422 declared_min_(minimum), 422 declared_min_(minimum),
423 declared_max_(maximum), 423 declared_max_(maximum),
424 bucket_count_(bucket_count), 424 bucket_count_(bucket_count),
425 flags_(kNoFlags), 425 flags_(kNoFlags),
426 cached_ranges_(new CachedRanges(bucket_count + 1, 0)), 426 bucket_ranges_(new BucketRanges(bucket_count + 1)),
427 range_checksum_(0), 427 range_checksum_(0),
428 sample_() { 428 sample_() {
429 Initialize(); 429 Initialize();
430 } 430 }
431 431
432 Histogram::Histogram(const std::string& name, TimeDelta minimum, 432 Histogram::Histogram(const std::string& name, TimeDelta minimum,
433 TimeDelta maximum, size_t bucket_count) 433 TimeDelta maximum, size_t bucket_count)
434 : HistogramBase(name), 434 : HistogramBase(name),
435 declared_min_(static_cast<int> (minimum.InMilliseconds())), 435 declared_min_(static_cast<int> (minimum.InMilliseconds())),
436 declared_max_(static_cast<int> (maximum.InMilliseconds())), 436 declared_max_(static_cast<int> (maximum.InMilliseconds())),
437 bucket_count_(bucket_count), 437 bucket_count_(bucket_count),
438 flags_(kNoFlags), 438 flags_(kNoFlags),
439 cached_ranges_(new CachedRanges(bucket_count + 1, 0)), 439 bucket_ranges_(new BucketRanges(bucket_count + 1)),
440 range_checksum_(0), 440 range_checksum_(0),
441 sample_() { 441 sample_() {
442 Initialize(); 442 Initialize();
443 } 443 }
444 444
445 Histogram::~Histogram() { 445 Histogram::~Histogram() {
446 if (StatisticsRecorder::dump_on_exit()) { 446 if (StatisticsRecorder::dump_on_exit()) {
447 std::string output; 447 std::string output;
448 WriteAsciiImpl(true, "\n", &output); 448 WriteAsciiImpl(true, "\n", &output);
449 DLOG(INFO) << output; 449 DLOG(INFO) << output;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 550
551 // Update histogram data with new sample. 551 // Update histogram data with new sample.
552 void Histogram::Accumulate(Sample value, Count count, size_t index) { 552 void Histogram::Accumulate(Sample value, Count count, size_t index) {
553 // Note locking not done in this version!!! 553 // Note locking not done in this version!!!
554 sample_.Accumulate(value, count, index); 554 sample_.Accumulate(value, count, index);
555 } 555 }
556 556
557 void Histogram::SetBucketRange(size_t i, Sample value) { 557 void Histogram::SetBucketRange(size_t i, Sample value) {
558 DCHECK_GT(bucket_count_, i); 558 DCHECK_GT(bucket_count_, i);
559 DCHECK_GE(value, 0); 559 DCHECK_GE(value, 0);
560 cached_ranges_->SetBucketRange(i, value); 560 bucket_ranges_->set_range(i, value);
561 } 561 }
562 562
563 bool Histogram::ValidateBucketRanges() const { 563 bool Histogram::ValidateBucketRanges() const {
564 // Standard assertions that all bucket ranges should satisfy. 564 // Standard assertions that all bucket ranges should satisfy.
565 DCHECK_EQ(bucket_count_ + 1, cached_ranges_->size()); 565 DCHECK_EQ(bucket_count_ + 1, bucket_ranges_->size());
566 DCHECK_EQ(0, ranges(0)); 566 DCHECK_EQ(0, ranges(0));
567 DCHECK_EQ(declared_min(), ranges(1)); 567 DCHECK_EQ(declared_min(), ranges(1));
568 DCHECK_EQ(declared_max(), ranges(bucket_count_ - 1)); 568 DCHECK_EQ(declared_max(), ranges(bucket_count_ - 1));
569 DCHECK_EQ(kSampleType_MAX, ranges(bucket_count_)); 569 DCHECK_EQ(kSampleType_MAX, ranges(bucket_count_));
570 return true; 570 return true;
571 } 571 }
572 572
573 uint32 Histogram::CalculateRangeChecksum() const { 573 uint32 Histogram::CalculateRangeChecksum() const {
574 DCHECK_EQ(cached_ranges_->size(), bucket_count() + 1); 574 DCHECK_EQ(bucket_ranges_->size(), bucket_count() + 1);
575 // Seed checksum. 575 // Seed checksum.
576 uint32 checksum = static_cast<uint32>(cached_ranges_->size()); 576 uint32 checksum = static_cast<uint32>(bucket_ranges_->size());
577 for (size_t index = 0; index < bucket_count(); ++index) 577 for (size_t index = 0; index < bucket_count(); ++index)
578 checksum = Crc32(checksum, ranges(index)); 578 checksum = Crc32(checksum, ranges(index));
579 return checksum; 579 return checksum;
580 } 580 }
581 581
582 void Histogram::Initialize() { 582 void Histogram::Initialize() {
583 sample_.Resize(*this); 583 sample_.Resize(*this);
584 if (declared_min_ < 1) 584 if (declared_min_ < 1)
585 declared_min_ = 1; 585 declared_min_ = 1;
586 if (declared_max_ > kSampleType_MAX - 1) 586 if (declared_max_ > kSampleType_MAX - 1)
587 declared_max_ = kSampleType_MAX - 1; 587 declared_max_ = kSampleType_MAX - 1;
588 DCHECK_LE(declared_min_, declared_max_); 588 DCHECK_LE(declared_min_, declared_max_);
589 DCHECK_GT(bucket_count_, 1u); 589 DCHECK_GT(bucket_count_, 1u);
590 CHECK_LT(bucket_count_, kBucketCount_MAX); 590 CHECK_LT(bucket_count_, kBucketCount_MAX);
591 size_t maximal_bucket_count = declared_max_ - declared_min_ + 2; 591 size_t maximal_bucket_count = declared_max_ - declared_min_ + 2;
592 DCHECK_LE(bucket_count_, maximal_bucket_count); 592 DCHECK_LE(bucket_count_, maximal_bucket_count);
593 DCHECK_EQ(0, ranges(0)); 593 DCHECK_EQ(0, ranges(0));
594 cached_ranges_->SetBucketRange(bucket_count_, kSampleType_MAX); 594 bucket_ranges_->set_range(bucket_count_, kSampleType_MAX);
595 } 595 }
596 596
597 // We generate the CRC-32 using the low order bits to select whether to XOR in 597 // We generate the CRC-32 using the low order bits to select whether to XOR in
598 // the reversed polynomial 0xedb88320L. This is nice and simple, and allows us 598 // the reversed polynomial 0xedb88320L. This is nice and simple, and allows us
599 // to keep the quotient in a uint32. Since we're not concerned about the nature 599 // to keep the quotient in a uint32. Since we're not concerned about the nature
600 // of corruptions (i.e., we don't care about bit sequencing, since we are 600 // of corruptions (i.e., we don't care about bit sequencing, since we are
601 // handling memory changes, which are more grotesque) so we don't bother to 601 // handling memory changes, which are more grotesque) so we don't bother to
602 // get the CRC correct for big-endian vs little-ending calculations. All we 602 // get the CRC correct for big-endian vs little-ending calculations. All we
603 // need is a nice hash, that tends to depend on all the bits of the sample, with 603 // need is a nice hash, that tends to depend on all the bits of the sample, with
604 // very little chance of changes in one place impacting changes in another 604 // very little chance of changes in one place impacting changes in another
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 993
994 CustomHistogram::CustomHistogram(const std::string& name, 994 CustomHistogram::CustomHistogram(const std::string& name,
995 const std::vector<Sample>& custom_ranges) 995 const std::vector<Sample>& custom_ranges)
996 : Histogram(name, custom_ranges[1], custom_ranges.back(), 996 : Histogram(name, custom_ranges[1], custom_ranges.back(),
997 custom_ranges.size()) { 997 custom_ranges.size()) {
998 DCHECK_GT(custom_ranges.size(), 1u); 998 DCHECK_GT(custom_ranges.size(), 1u);
999 DCHECK_EQ(custom_ranges[0], 0); 999 DCHECK_EQ(custom_ranges[0], 0);
1000 } 1000 }
1001 1001
1002 bool CustomHistogram::SerializeRanges(Pickle* pickle) const { 1002 bool CustomHistogram::SerializeRanges(Pickle* pickle) const {
1003 for (size_t i = 0; i < cached_ranges()->size(); ++i) { 1003 for (size_t i = 0; i < bucket_ranges()->size(); ++i) {
1004 if (!pickle->WriteInt(cached_ranges()->ranges(i))) 1004 if (!pickle->WriteInt(bucket_ranges()->range(i)))
1005 return false; 1005 return false;
1006 } 1006 }
1007 return true; 1007 return true;
1008 } 1008 }
1009 1009
1010 // static 1010 // static
1011 bool CustomHistogram::DeserializeRanges( 1011 bool CustomHistogram::DeserializeRanges(
1012 PickleIterator* iter, std::vector<Histogram::Sample>* ranges) { 1012 PickleIterator* iter, std::vector<Histogram::Sample>* ranges) {
1013 for (size_t i = 0; i < ranges->size(); ++i) { 1013 for (size_t i = 0; i < ranges->size(); ++i) {
1014 if (!iter->ReadInt(&(*ranges)[i])) 1014 if (!iter->ReadInt(&(*ranges)[i]))
1015 return false; 1015 return false;
1016 } 1016 }
1017 return true; 1017 return true;
1018 } 1018 }
1019 1019
1020 void CustomHistogram::InitializedCustomBucketRange( 1020 void CustomHistogram::InitializedCustomBucketRange(
1021 const std::vector<Sample>& custom_ranges) { 1021 const std::vector<Sample>& custom_ranges) {
1022 DCHECK_GT(custom_ranges.size(), 1u); 1022 DCHECK_GT(custom_ranges.size(), 1u);
1023 DCHECK_EQ(custom_ranges[0], 0); 1023 DCHECK_EQ(custom_ranges[0], 0);
1024 DCHECK_LE(custom_ranges.size(), bucket_count()); 1024 DCHECK_LE(custom_ranges.size(), bucket_count());
1025 for (size_t index = 0; index < custom_ranges.size(); ++index) 1025 for (size_t index = 0; index < custom_ranges.size(); ++index)
1026 SetBucketRange(index, custom_ranges[index]); 1026 SetBucketRange(index, custom_ranges[index]);
1027 ResetRangeChecksum(); 1027 ResetRangeChecksum();
1028 } 1028 }
1029 1029
1030 double CustomHistogram::GetBucketSize(Count current, size_t i) const { 1030 double CustomHistogram::GetBucketSize(Count current, size_t i) const {
1031 return 1; 1031 return 1;
1032 } 1032 }
1033 1033
1034 CachedRanges::CachedRanges(size_t bucket_count, int initial_value)
1035 : ranges_(bucket_count, initial_value),
1036 range_checksum_(0) {
1037 }
1038
1039 CachedRanges::~CachedRanges() {
1040 }
1041
1042 void CachedRanges::SetBucketRange(size_t i, Histogram::Sample value) {
1043 DCHECK_LT(i, ranges_.size());
1044 DCHECK_GE(value, 0);
1045 ranges_[i] = value;
1046 }
1047
1048 bool CachedRanges::Equals(CachedRanges* other) const {
1049 if (range_checksum_ != other->range_checksum_)
1050 return false;
1051 if (ranges_.size() != other->ranges_.size())
1052 return false;
1053 for (size_t index = 0; index < ranges_.size(); ++index) {
1054 if (ranges_[index] != other->ranges_[index])
1055 return false;
1056 }
1057 return true;
1058 }
1059
1060 } // namespace base 1034 } // namespace base
OLDNEW
« no previous file with comments | « base/metrics/histogram.h ('k') | base/metrics/histogram_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698