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

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

Issue 7696017: Cache the ranges_ vector and share the ranges_ vector (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 67 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL,
68 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 68 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
69 0x2d02ef8dL, 69 0x2d02ef8dL,
70 }; 70 };
71 71
72 typedef Histogram::Count Count; 72 typedef Histogram::Count Count;
73 73
74 // static 74 // static
75 const size_t Histogram::kBucketCount_MAX = 16384u; 75 const size_t Histogram::kBucketCount_MAX = 16384u;
76 76
77 // Collect the number of histograms created.
78 static uint32 number_of_histograms_ = 0;
79 // Collect the number of vectors saved because of caching ranges.
80 static uint32 number_of_vectors_saved_ = 0;
81 // Collect the number of ranges_ elements saved because of caching ranges.
82 static size_t saved_ranges_size_ = 0;
83
77 Histogram* Histogram::FactoryGet(const std::string& name, 84 Histogram* Histogram::FactoryGet(const std::string& name,
78 Sample minimum, 85 Sample minimum,
79 Sample maximum, 86 Sample maximum,
80 size_t bucket_count, 87 size_t bucket_count,
81 Flags flags) { 88 Flags flags) {
82 Histogram* histogram(NULL); 89 Histogram* histogram(NULL);
83 90
84 // Defensive code. 91 // Defensive code.
85 if (minimum < 1) 92 if (minimum < 1)
86 minimum = 1; 93 minimum = 1;
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 } 355 }
349 } 356 }
350 return static_cast<Inconsistencies>(inconsistencies); 357 return static_cast<Inconsistencies>(inconsistencies);
351 } 358 }
352 359
353 Histogram::ClassType Histogram::histogram_type() const { 360 Histogram::ClassType Histogram::histogram_type() const {
354 return HISTOGRAM; 361 return HISTOGRAM;
355 } 362 }
356 363
357 Histogram::Sample Histogram::ranges(size_t i) const { 364 Histogram::Sample Histogram::ranges(size_t i) const {
358 return ranges_[i]; 365 return cached_ranges_->ranges(i);
359 } 366 }
360 367
361 size_t Histogram::bucket_count() const { 368 size_t Histogram::bucket_count() const {
362 return bucket_count_; 369 return bucket_count_;
363 } 370 }
364 371
365 // Do a safe atomic snapshot of sample data. 372 // Do a safe atomic snapshot of sample data.
366 // This implementation assumes we are on a safe single thread. 373 // This implementation assumes we are on a safe single thread.
367 void Histogram::SnapshotSample(SampleSet* sample) const { 374 void Histogram::SnapshotSample(SampleSet* sample) const {
368 // Note locking not done in this version!!! 375 // Note locking not done in this version!!!
(...skipping 19 matching lines...) Expand all
388 return CalculateRangeChecksum() == range_checksum_; 395 return CalculateRangeChecksum() == range_checksum_;
389 } 396 }
390 397
391 Histogram::Histogram(const std::string& name, Sample minimum, 398 Histogram::Histogram(const std::string& name, Sample minimum,
392 Sample maximum, size_t bucket_count) 399 Sample maximum, size_t bucket_count)
393 : histogram_name_(name), 400 : histogram_name_(name),
394 declared_min_(minimum), 401 declared_min_(minimum),
395 declared_max_(maximum), 402 declared_max_(maximum),
396 bucket_count_(bucket_count), 403 bucket_count_(bucket_count),
397 flags_(kNoFlags), 404 flags_(kNoFlags),
398 ranges_(bucket_count + 1, 0), 405 cached_ranges_(new CachedRanges(bucket_count + 1, 0)),
399 range_checksum_(0), 406 range_checksum_(0),
400 sample_() { 407 sample_() {
401 Initialize(); 408 Initialize();
402 } 409 }
403 410
404 Histogram::Histogram(const std::string& name, TimeDelta minimum, 411 Histogram::Histogram(const std::string& name, TimeDelta minimum,
405 TimeDelta maximum, size_t bucket_count) 412 TimeDelta maximum, size_t bucket_count)
406 : histogram_name_(name), 413 : histogram_name_(name),
407 declared_min_(static_cast<int> (minimum.InMilliseconds())), 414 declared_min_(static_cast<int> (minimum.InMilliseconds())),
408 declared_max_(static_cast<int> (maximum.InMilliseconds())), 415 declared_max_(static_cast<int> (maximum.InMilliseconds())),
409 bucket_count_(bucket_count), 416 bucket_count_(bucket_count),
410 flags_(kNoFlags), 417 flags_(kNoFlags),
411 ranges_(bucket_count + 1, 0), 418 cached_ranges_(new CachedRanges(bucket_count + 1, 0)),
412 range_checksum_(0), 419 range_checksum_(0),
413 sample_() { 420 sample_() {
414 Initialize(); 421 Initialize();
415 } 422 }
416 423
417 Histogram::~Histogram() { 424 Histogram::~Histogram() {
418 if (StatisticsRecorder::dump_on_exit()) { 425 if (StatisticsRecorder::dump_on_exit()) {
419 std::string output; 426 std::string output;
420 WriteAscii(true, "\n", &output); 427 WriteAscii(true, "\n", &output);
421 LOG(INFO) << output; 428 LOG(INFO) << output;
422 } 429 }
423 430
424 // Just to make sure most derived class did this properly... 431 // Just to make sure most derived class did this properly...
425 DCHECK(ValidateBucketRanges()); 432 DCHECK(ValidateBucketRanges());
426 } 433 }
427 434
428 // Calculate what range of values are held in each bucket. 435 // Calculate what range of values are held in each bucket.
429 // We have to be careful that we don't pick a ratio between starting points in 436 // We have to be careful that we don't pick a ratio between starting points in
430 // consecutive buckets that is sooo small, that the integer bounds are the same 437 // consecutive buckets that is sooo small, that the integer bounds are the same
431 // (effectively making one bucket get no values). We need to avoid: 438 // (effectively making one bucket get no values). We need to avoid:
432 // ranges_[i] == ranges_[i + 1] 439 // ranges(i) == ranges(i + 1)
433 // To avoid that, we just do a fine-grained bucket width as far as we need to 440 // To avoid that, we just do a fine-grained bucket width as far as we need to
434 // until we get a ratio that moves us along at least 2 units at a time. From 441 // until we get a ratio that moves us along at least 2 units at a time. From
435 // that bucket onward we do use the exponential growth of buckets. 442 // that bucket onward we do use the exponential growth of buckets.
436 void Histogram::InitializeBucketRange() { 443 void Histogram::InitializeBucketRange() {
437 double log_max = log(static_cast<double>(declared_max())); 444 double log_max = log(static_cast<double>(declared_max()));
438 double log_ratio; 445 double log_ratio;
439 double log_next; 446 double log_next;
440 size_t bucket_index = 1; 447 size_t bucket_index = 1;
441 Sample current = declared_min(); 448 Sample current = declared_min();
442 SetBucketRange(bucket_index, current); 449 SetBucketRange(bucket_index, current);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 525
519 // Update histogram data with new sample. 526 // Update histogram data with new sample.
520 void Histogram::Accumulate(Sample value, Count count, size_t index) { 527 void Histogram::Accumulate(Sample value, Count count, size_t index) {
521 // Note locking not done in this version!!! 528 // Note locking not done in this version!!!
522 sample_.Accumulate(value, count, index); 529 sample_.Accumulate(value, count, index);
523 } 530 }
524 531
525 void Histogram::SetBucketRange(size_t i, Sample value) { 532 void Histogram::SetBucketRange(size_t i, Sample value) {
526 DCHECK_GT(bucket_count_, i); 533 DCHECK_GT(bucket_count_, i);
527 DCHECK_GE(value, 0); 534 DCHECK_GE(value, 0);
528 ranges_[i] = value; 535 cached_ranges_->SetBucketRange(i, value);
529 } 536 }
530 537
531 bool Histogram::ValidateBucketRanges() const { 538 bool Histogram::ValidateBucketRanges() const {
532 // Standard assertions that all bucket ranges should satisfy. 539 // Standard assertions that all bucket ranges should satisfy.
533 DCHECK_EQ(bucket_count_ + 1, ranges_.size()); 540 DCHECK_EQ(bucket_count_ + 1, cached_ranges_->size());
534 DCHECK_EQ(0, ranges_[0]); 541 DCHECK_EQ(0, ranges(0));
535 DCHECK_EQ(declared_min(), ranges_[1]); 542 DCHECK_EQ(declared_min(), ranges(1));
536 DCHECK_EQ(declared_max(), ranges_[bucket_count_ - 1]); 543 DCHECK_EQ(declared_max(), ranges(bucket_count_ - 1));
537 DCHECK_EQ(kSampleType_MAX, ranges_[bucket_count_]); 544 DCHECK_EQ(kSampleType_MAX, ranges(bucket_count_));
538 return true; 545 return true;
539 } 546 }
540 547
541 uint32 Histogram::CalculateRangeChecksum() const { 548 uint32 Histogram::CalculateRangeChecksum() const {
542 DCHECK_EQ(ranges_.size(), bucket_count() + 1); 549 DCHECK_EQ(cached_ranges_->size(), bucket_count() + 1);
543 uint32 checksum = static_cast<uint32>(ranges_.size()); // Seed checksum. 550 // Seed checksum.
551 uint32 checksum = static_cast<uint32>(cached_ranges_->size());
544 for (size_t index = 0; index < bucket_count(); ++index) 552 for (size_t index = 0; index < bucket_count(); ++index)
545 checksum = Crc32(checksum, ranges(index)); 553 checksum = Crc32(checksum, ranges(index));
546 return checksum; 554 return checksum;
547 } 555 }
548 556
549 void Histogram::Initialize() { 557 void Histogram::Initialize() {
550 sample_.Resize(*this); 558 sample_.Resize(*this);
551 if (declared_min_ < 1) 559 if (declared_min_ < 1)
552 declared_min_ = 1; 560 declared_min_ = 1;
553 if (declared_max_ > kSampleType_MAX - 1) 561 if (declared_max_ > kSampleType_MAX - 1)
554 declared_max_ = kSampleType_MAX - 1; 562 declared_max_ = kSampleType_MAX - 1;
555 DCHECK_LE(declared_min_, declared_max_); 563 DCHECK_LE(declared_min_, declared_max_);
556 DCHECK_GT(bucket_count_, 1u); 564 DCHECK_GT(bucket_count_, 1u);
557 CHECK_LT(bucket_count_, kBucketCount_MAX); 565 CHECK_LT(bucket_count_, kBucketCount_MAX);
558 size_t maximal_bucket_count = declared_max_ - declared_min_ + 2; 566 size_t maximal_bucket_count = declared_max_ - declared_min_ + 2;
559 DCHECK_LE(bucket_count_, maximal_bucket_count); 567 DCHECK_LE(bucket_count_, maximal_bucket_count);
560 DCHECK_EQ(0, ranges_[0]); 568 DCHECK_EQ(0, ranges(0));
561 ranges_[bucket_count_] = kSampleType_MAX; 569 cached_ranges_->SetBucketRange(bucket_count_, kSampleType_MAX);
562 } 570 }
563 571
564 // We generate the CRC-32 using the low order bits to select whether to XOR in 572 // We generate the CRC-32 using the low order bits to select whether to XOR in
565 // the reversed polynomial 0xedb88320L. This is nice and simple, and allows us 573 // the reversed polynomial 0xedb88320L. This is nice and simple, and allows us
566 // to keep the quotient in a uint32. Since we're not concerned about the nature 574 // to keep the quotient in a uint32. Since we're not concerned about the nature
567 // of corruptions (i.e., we don't care about bit sequencing, since we are 575 // of corruptions (i.e., we don't care about bit sequencing, since we are
568 // handling memory changes, which are more grotesque) so we don't bother to 576 // handling memory changes, which are more grotesque) so we don't bother to
569 // get the CRC correct for big-endian vs little-ending calculations. All we 577 // get the CRC correct for big-endian vs little-ending calculations. All we
570 // need is a nice hash, that tends to depend on all the bits of the sample, with 578 // need is a nice hash, that tends to depend on all the bits of the sample, with
571 // very little chance of changes in one place impacting changes in another 579 // very little chance of changes in one place impacting changes in another
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 // This will leak on purpose. It's the only way to make sure we won't race 1001 // This will leak on purpose. It's the only way to make sure we won't race
994 // against the static uninitialization of the module while one of our 1002 // against the static uninitialization of the module while one of our
995 // static methods relying on the lock get called at an inappropriate time 1003 // static methods relying on the lock get called at an inappropriate time
996 // during the termination phase. Since it's a static data member, we will 1004 // during the termination phase. Since it's a static data member, we will
997 // leak one per process, which would be similar to the instance allocated 1005 // leak one per process, which would be similar to the instance allocated
998 // during static initialization and released only on process termination. 1006 // during static initialization and released only on process termination.
999 lock_ = new base::Lock; 1007 lock_ = new base::Lock;
1000 } 1008 }
1001 base::AutoLock auto_lock(*lock_); 1009 base::AutoLock auto_lock(*lock_);
1002 histograms_ = new HistogramMap; 1010 histograms_ = new HistogramMap;
1011 ranges_ = new RangesMap;
1003 } 1012 }
1004 1013
1005 StatisticsRecorder::~StatisticsRecorder() { 1014 StatisticsRecorder::~StatisticsRecorder() {
1006 DCHECK(histograms_ && lock_); 1015 DCHECK(histograms_ && lock_);
1007 1016
1008 if (dump_on_exit_) { 1017 if (dump_on_exit_) {
1009 std::string output; 1018 std::string output;
1010 WriteGraph("", &output); 1019 WriteGraph("", &output);
1011 LOG(INFO) << output; 1020 LOG(INFO) << output;
1012 } 1021 }
1013 // Clean up. 1022 // Clean up.
1014 HistogramMap* histograms = NULL; 1023 HistogramMap* histograms = NULL;
1015 { 1024 {
1016 base::AutoLock auto_lock(*lock_); 1025 base::AutoLock auto_lock(*lock_);
1017 histograms = histograms_; 1026 histograms = histograms_;
1018 histograms_ = NULL; 1027 histograms_ = NULL;
1019 } 1028 }
1020 delete histograms; 1029 delete histograms;
1030 RangesMap* ranges = NULL;
1031 {
1032 base::AutoLock auto_lock(*lock_);
1033 ranges = ranges_;
1034 ranges_ = NULL;
1035 }
1036 delete ranges;
jar (doing other things) 2011/10/04 22:32:38 I'd suggest we explicity comment that we are going
ramant (doing other things) 2011/10/19 01:09:52 Done.
1021 // We don't delete lock_ on purpose to avoid having to properly protect 1037 // We don't delete lock_ on purpose to avoid having to properly protect
1022 // against it going away after we checked for NULL in the static methods. 1038 // against it going away after we checked for NULL in the static methods.
1023 } 1039 }
1024 1040
1025 // static 1041 // static
1026 bool StatisticsRecorder::IsActive() { 1042 bool StatisticsRecorder::IsActive() {
1027 if (lock_ == NULL) 1043 if (lock_ == NULL)
1028 return false; 1044 return false;
1029 base::AutoLock auto_lock(*lock_); 1045 base::AutoLock auto_lock(*lock_);
1030 return NULL != histograms_; 1046 return NULL != histograms_;
(...skipping 14 matching lines...) Expand all
1045 if (!histograms_) { 1061 if (!histograms_) {
1046 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322 1062 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322
1047 return histogram; 1063 return histogram;
1048 } 1064 }
1049 const std::string name = histogram->histogram_name(); 1065 const std::string name = histogram->histogram_name();
1050 HistogramMap::iterator it = histograms_->find(name); 1066 HistogramMap::iterator it = histograms_->find(name);
1051 // Avoid overwriting a previous registration. 1067 // Avoid overwriting a previous registration.
1052 if (histograms_->end() == it) { 1068 if (histograms_->end() == it) {
1053 (*histograms_)[name] = histogram; 1069 (*histograms_)[name] = histogram;
1054 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322 1070 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322
1071 RegisterOrDeleteDuplicateRanges(histogram);
1072 ++number_of_histograms_;
1055 } else { 1073 } else {
1056 delete histogram; // We already have one by this name. 1074 delete histogram; // We already have one by this name.
1057 histogram = it->second; 1075 histogram = it->second;
1058 } 1076 }
1059 return histogram; 1077 return histogram;
1060 } 1078 }
1061 1079
1062 // static 1080 // static
1081 void StatisticsRecorder::RegisterOrDeleteDuplicateRanges(Histogram* histogram) {
1082 DCHECK(histogram);
1083 CachedRanges* cached_ranges = histogram->cached_ranges();
jar (doing other things) 2011/10/04 22:32:38 nit: suggest name change for the local variable he
ramant (doing other things) 2011/10/19 01:09:52 Done.
1084 DCHECK(cached_ranges);
1085 uint32 checksum = histogram->range_checksum();
1086 cached_ranges->SetRangeChecksum(checksum);
1087
1088 RangesMap::iterator ranges_it = ranges_->find(checksum);
1089 if (ranges_->end() == ranges_it) {
1090 // Register the new CachedRanges.
1091 std::list<CachedRanges*>* ranges_list(new std::list<CachedRanges*>());
jar (doing other things) 2011/10/04 22:32:38 nit: suggest name change for local variable: rang
ramant (doing other things) 2011/10/19 01:09:52 Done.
1092 ranges_list->push_front(cached_ranges);
1093 (*ranges_)[checksum] = ranges_list;
1094 return;
1095 }
1096
1097 // Use the registered CachedRanges if the registered CachedRanges has same
1098 // ranges_ as |histogram|'s CachedRanges.
1099 std::list<CachedRanges*>* ranges_list = ranges_it->second;
1100 std::list<CachedRanges*>::iterator ranges_list_it;
1101 for (ranges_list_it = ranges_list->begin();
1102 ranges_list_it != ranges_list->end();
1103 ++ranges_list_it) {
1104 CachedRanges* existing_cached_ranges = *ranges_list_it;
1105 DCHECK(existing_cached_ranges);
1106 if (existing_cached_ranges->Equals(cached_ranges)) {
1107 histogram->set_cached_ranges(existing_cached_ranges);
1108 ++number_of_vectors_saved_;
1109 saved_ranges_size_ += cached_ranges->size();
1110 delete cached_ranges;
1111 return;
1112 }
1113 }
1114
1115 // We haven't found a CachedRanges which has the same ranges. Register the
1116 // new CachedRanges.
1117 DCHECK(ranges_list_it == ranges_list->end());
1118 ranges_list->push_front(cached_ranges);
1119 }
1120
1121 // static
1122 void StatisticsRecorder::CollectHistogramStats(const std::string& suffix) {
1123 static int uma_upload_attempt = 0;
1124 ++uma_upload_attempt;
1125 if (uma_upload_attempt == 1) {
1126 UMA_HISTOGRAM_COUNTS_10000("Histogram.FirstUpload.Count." + suffix,
jar (doing other things) 2011/10/04 22:32:38 For histogram naming, it is always nice to have si
ramant (doing other things) 2011/10/19 01:09:52 Done.
1127 number_of_histograms_);
1128 UMA_HISTOGRAM_COUNTS_10000("Histogram.FirstUpload.RangesSaved." + suffix,
1129 number_of_vectors_saved_);
1130 UMA_HISTOGRAM_COUNTS("Histogram.FirstUpload.RangesElementsSaved." + suffix,
1131 static_cast<int>(saved_ranges_size_));
1132 number_of_histograms_ = 0;
1133 number_of_vectors_saved_ = 0;
1134 saved_ranges_size_ = 0;
1135 return;
1136 }
1137 if (uma_upload_attempt == 2) {
1138 UMA_HISTOGRAM_COUNTS_10000("Histogram.SecondUpload.Count." + suffix,
1139 number_of_histograms_);
1140 UMA_HISTOGRAM_COUNTS_10000("Histogram.SecondUpload.RangesSaved." + suffix,
1141 number_of_vectors_saved_);
1142 UMA_HISTOGRAM_COUNTS("Histogram.SecondUpload.RangesElementsSaved" + suffix,
1143 static_cast<int>(saved_ranges_size_));
1144 number_of_histograms_ = 0;
1145 number_of_vectors_saved_ = 0;
1146 saved_ranges_size_ = 0;
1147 return;
1148 }
1149 UMA_HISTOGRAM_COUNTS_10000("Histogram.RestOfUploads.Count." + suffix,
1150 number_of_histograms_);
1151 UMA_HISTOGRAM_COUNTS_10000("Histogram.RestOfUploads.RangesSaved." + suffix,
1152 number_of_vectors_saved_);
1153 UMA_HISTOGRAM_COUNTS("Histogram.RestOfUploads.RangesElementsSaved." + suffix,
1154 static_cast<int>(saved_ranges_size_));
1155 }
1156
1157 // static
1063 void StatisticsRecorder::WriteHTMLGraph(const std::string& query, 1158 void StatisticsRecorder::WriteHTMLGraph(const std::string& query,
1064 std::string* output) { 1159 std::string* output) {
1065 if (!IsActive()) 1160 if (!IsActive())
1066 return; 1161 return;
1067 1162
1068 Histograms snapshot; 1163 Histograms snapshot;
1069 GetSnapshot(query, &snapshot); 1164 GetSnapshot(query, &snapshot);
1070 for (Histograms::iterator it = snapshot.begin(); 1165 for (Histograms::iterator it = snapshot.begin();
1071 it != snapshot.end(); 1166 it != snapshot.end();
1072 ++it) { 1167 ++it) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 if (!histograms_) 1228 if (!histograms_)
1134 return; 1229 return;
1135 for (HistogramMap::iterator it = histograms_->begin(); 1230 for (HistogramMap::iterator it = histograms_->begin();
1136 histograms_->end() != it; 1231 histograms_->end() != it;
1137 ++it) { 1232 ++it) {
1138 if (it->first.find(query) != std::string::npos) 1233 if (it->first.find(query) != std::string::npos)
1139 snapshot->push_back(it->second); 1234 snapshot->push_back(it->second);
1140 } 1235 }
1141 } 1236 }
1142 1237
1238 CachedRanges::CachedRanges(size_t bucket_count, int initial_value)
1239 : ranges_(bucket_count, initial_value),
1240 range_checksum_(0) {
1241 }
1242
1243 CachedRanges::~CachedRanges() {
1244 }
1245
1246 void CachedRanges::SetBucketRange(size_t i, Histogram::Sample value) {
1247 DCHECK_LT(i, ranges_.size());
1248 DCHECK_GE(value, 0);
1249 ranges_[i] = value;
1250 }
1251
1252 bool CachedRanges::Equals(CachedRanges* other) const {
1253 if (range_checksum_ != other->range_checksum_)
1254 return false;
1255 if (ranges_.size() != other->ranges_.size())
1256 return false;
1257 for (size_t index = 0; index < ranges_.size(); ++index) {
1258 if (ranges_[index] != other->ranges_[index])
1259 return false;
1260 }
1261 return true;
1262 }
1263
1143 // static 1264 // static
1144 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; 1265 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL;
1145 // static 1266 // static
1267 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL;
1268 // static
1146 base::Lock* StatisticsRecorder::lock_ = NULL; 1269 base::Lock* StatisticsRecorder::lock_ = NULL;
1147 // static 1270 // static
1148 bool StatisticsRecorder::dump_on_exit_ = false; 1271 bool StatisticsRecorder::dump_on_exit_ = false;
1149
1150 } // namespace base 1272 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698