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

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, 2 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) 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 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 } 363 }
357 } 364 }
358 return static_cast<Inconsistencies>(inconsistencies); 365 return static_cast<Inconsistencies>(inconsistencies);
359 } 366 }
360 367
361 Histogram::ClassType Histogram::histogram_type() const { 368 Histogram::ClassType Histogram::histogram_type() const {
362 return HISTOGRAM; 369 return HISTOGRAM;
363 } 370 }
364 371
365 Histogram::Sample Histogram::ranges(size_t i) const { 372 Histogram::Sample Histogram::ranges(size_t i) const {
366 return ranges_[i]; 373 return cached_ranges_->ranges(i);
367 } 374 }
368 375
369 size_t Histogram::bucket_count() const { 376 size_t Histogram::bucket_count() const {
370 return bucket_count_; 377 return bucket_count_;
371 } 378 }
372 379
373 // Do a safe atomic snapshot of sample data. 380 // Do a safe atomic snapshot of sample data.
374 // This implementation assumes we are on a safe single thread. 381 // This implementation assumes we are on a safe single thread.
375 void Histogram::SnapshotSample(SampleSet* sample) const { 382 void Histogram::SnapshotSample(SampleSet* sample) const {
376 // Note locking not done in this version!!! 383 // Note locking not done in this version!!!
(...skipping 19 matching lines...) Expand all
396 return CalculateRangeChecksum() == range_checksum_; 403 return CalculateRangeChecksum() == range_checksum_;
397 } 404 }
398 405
399 Histogram::Histogram(const std::string& name, Sample minimum, 406 Histogram::Histogram(const std::string& name, Sample minimum,
400 Sample maximum, size_t bucket_count) 407 Sample maximum, size_t bucket_count)
401 : histogram_name_(name), 408 : histogram_name_(name),
402 declared_min_(minimum), 409 declared_min_(minimum),
403 declared_max_(maximum), 410 declared_max_(maximum),
404 bucket_count_(bucket_count), 411 bucket_count_(bucket_count),
405 flags_(kNoFlags), 412 flags_(kNoFlags),
406 ranges_(bucket_count + 1, 0), 413 cached_ranges_(new CachedRanges(bucket_count + 1, 0)),
407 range_checksum_(0), 414 range_checksum_(0),
408 sample_() { 415 sample_() {
409 Initialize(); 416 Initialize();
410 } 417 }
411 418
412 Histogram::Histogram(const std::string& name, TimeDelta minimum, 419 Histogram::Histogram(const std::string& name, TimeDelta minimum,
413 TimeDelta maximum, size_t bucket_count) 420 TimeDelta maximum, size_t bucket_count)
414 : histogram_name_(name), 421 : histogram_name_(name),
415 declared_min_(static_cast<int> (minimum.InMilliseconds())), 422 declared_min_(static_cast<int> (minimum.InMilliseconds())),
416 declared_max_(static_cast<int> (maximum.InMilliseconds())), 423 declared_max_(static_cast<int> (maximum.InMilliseconds())),
417 bucket_count_(bucket_count), 424 bucket_count_(bucket_count),
418 flags_(kNoFlags), 425 flags_(kNoFlags),
419 ranges_(bucket_count + 1, 0), 426 cached_ranges_(new CachedRanges(bucket_count + 1, 0)),
420 range_checksum_(0), 427 range_checksum_(0),
421 sample_() { 428 sample_() {
422 Initialize(); 429 Initialize();
423 } 430 }
424 431
425 Histogram::~Histogram() { 432 Histogram::~Histogram() {
426 if (StatisticsRecorder::dump_on_exit()) { 433 if (StatisticsRecorder::dump_on_exit()) {
427 std::string output; 434 std::string output;
428 WriteAscii(true, "\n", &output); 435 WriteAscii(true, "\n", &output);
429 LOG(INFO) << output; 436 LOG(INFO) << output;
430 } 437 }
431 438
432 // Just to make sure most derived class did this properly... 439 // Just to make sure most derived class did this properly...
433 DCHECK(ValidateBucketRanges()); 440 DCHECK(ValidateBucketRanges());
434 } 441 }
435 442
436 // Calculate what range of values are held in each bucket. 443 // Calculate what range of values are held in each bucket.
437 // We have to be careful that we don't pick a ratio between starting points in 444 // We have to be careful that we don't pick a ratio between starting points in
438 // consecutive buckets that is sooo small, that the integer bounds are the same 445 // consecutive buckets that is sooo small, that the integer bounds are the same
439 // (effectively making one bucket get no values). We need to avoid: 446 // (effectively making one bucket get no values). We need to avoid:
440 // ranges_[i] == ranges_[i + 1] 447 // ranges(i) == ranges(i + 1)
441 // To avoid that, we just do a fine-grained bucket width as far as we need to 448 // To avoid that, we just do a fine-grained bucket width as far as we need to
442 // until we get a ratio that moves us along at least 2 units at a time. From 449 // until we get a ratio that moves us along at least 2 units at a time. From
443 // that bucket onward we do use the exponential growth of buckets. 450 // that bucket onward we do use the exponential growth of buckets.
444 void Histogram::InitializeBucketRange() { 451 void Histogram::InitializeBucketRange() {
445 double log_max = log(static_cast<double>(declared_max())); 452 double log_max = log(static_cast<double>(declared_max()));
446 double log_ratio; 453 double log_ratio;
447 double log_next; 454 double log_next;
448 size_t bucket_index = 1; 455 size_t bucket_index = 1;
449 Sample current = declared_min(); 456 Sample current = declared_min();
450 SetBucketRange(bucket_index, current); 457 SetBucketRange(bucket_index, current);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 533
527 // Update histogram data with new sample. 534 // Update histogram data with new sample.
528 void Histogram::Accumulate(Sample value, Count count, size_t index) { 535 void Histogram::Accumulate(Sample value, Count count, size_t index) {
529 // Note locking not done in this version!!! 536 // Note locking not done in this version!!!
530 sample_.Accumulate(value, count, index); 537 sample_.Accumulate(value, count, index);
531 } 538 }
532 539
533 void Histogram::SetBucketRange(size_t i, Sample value) { 540 void Histogram::SetBucketRange(size_t i, Sample value) {
534 DCHECK_GT(bucket_count_, i); 541 DCHECK_GT(bucket_count_, i);
535 DCHECK_GE(value, 0); 542 DCHECK_GE(value, 0);
536 ranges_[i] = value; 543 cached_ranges_->SetBucketRange(i, value);
537 } 544 }
538 545
539 bool Histogram::ValidateBucketRanges() const { 546 bool Histogram::ValidateBucketRanges() const {
540 // Standard assertions that all bucket ranges should satisfy. 547 // Standard assertions that all bucket ranges should satisfy.
541 DCHECK_EQ(bucket_count_ + 1, ranges_.size()); 548 DCHECK_EQ(bucket_count_ + 1, cached_ranges_->size());
542 DCHECK_EQ(0, ranges_[0]); 549 DCHECK_EQ(0, ranges(0));
543 DCHECK_EQ(declared_min(), ranges_[1]); 550 DCHECK_EQ(declared_min(), ranges(1));
544 DCHECK_EQ(declared_max(), ranges_[bucket_count_ - 1]); 551 DCHECK_EQ(declared_max(), ranges(bucket_count_ - 1));
545 DCHECK_EQ(kSampleType_MAX, ranges_[bucket_count_]); 552 DCHECK_EQ(kSampleType_MAX, ranges(bucket_count_));
546 return true; 553 return true;
547 } 554 }
548 555
549 uint32 Histogram::CalculateRangeChecksum() const { 556 uint32 Histogram::CalculateRangeChecksum() const {
550 DCHECK_EQ(ranges_.size(), bucket_count() + 1); 557 DCHECK_EQ(cached_ranges_->size(), bucket_count() + 1);
551 uint32 checksum = static_cast<uint32>(ranges_.size()); // Seed checksum. 558 // Seed checksum.
559 uint32 checksum = static_cast<uint32>(cached_ranges_->size());
552 for (size_t index = 0; index < bucket_count(); ++index) 560 for (size_t index = 0; index < bucket_count(); ++index)
553 checksum = Crc32(checksum, ranges(index)); 561 checksum = Crc32(checksum, ranges(index));
554 return checksum; 562 return checksum;
555 } 563 }
556 564
557 void Histogram::Initialize() { 565 void Histogram::Initialize() {
558 sample_.Resize(*this); 566 sample_.Resize(*this);
559 if (declared_min_ < 1) 567 if (declared_min_ < 1)
560 declared_min_ = 1; 568 declared_min_ = 1;
561 if (declared_max_ > kSampleType_MAX - 1) 569 if (declared_max_ > kSampleType_MAX - 1)
562 declared_max_ = kSampleType_MAX - 1; 570 declared_max_ = kSampleType_MAX - 1;
563 DCHECK_LE(declared_min_, declared_max_); 571 DCHECK_LE(declared_min_, declared_max_);
564 DCHECK_GT(bucket_count_, 1u); 572 DCHECK_GT(bucket_count_, 1u);
565 CHECK_LT(bucket_count_, kBucketCount_MAX); 573 CHECK_LT(bucket_count_, kBucketCount_MAX);
566 size_t maximal_bucket_count = declared_max_ - declared_min_ + 2; 574 size_t maximal_bucket_count = declared_max_ - declared_min_ + 2;
567 DCHECK_LE(bucket_count_, maximal_bucket_count); 575 DCHECK_LE(bucket_count_, maximal_bucket_count);
568 DCHECK_EQ(0, ranges_[0]); 576 DCHECK_EQ(0, ranges(0));
569 ranges_[bucket_count_] = kSampleType_MAX; 577 cached_ranges_->SetBucketRange(bucket_count_, kSampleType_MAX);
570 } 578 }
571 579
572 // We generate the CRC-32 using the low order bits to select whether to XOR in 580 // We generate the CRC-32 using the low order bits to select whether to XOR in
573 // the reversed polynomial 0xedb88320L. This is nice and simple, and allows us 581 // the reversed polynomial 0xedb88320L. This is nice and simple, and allows us
574 // to keep the quotient in a uint32. Since we're not concerned about the nature 582 // to keep the quotient in a uint32. Since we're not concerned about the nature
575 // of corruptions (i.e., we don't care about bit sequencing, since we are 583 // of corruptions (i.e., we don't care about bit sequencing, since we are
576 // handling memory changes, which are more grotesque) so we don't bother to 584 // handling memory changes, which are more grotesque) so we don't bother to
577 // get the CRC correct for big-endian vs little-ending calculations. All we 585 // get the CRC correct for big-endian vs little-ending calculations. All we
578 // need is a nice hash, that tends to depend on all the bits of the sample, with 586 // need is a nice hash, that tends to depend on all the bits of the sample, with
579 // very little chance of changes in one place impacting changes in another 587 // very little chance of changes in one place impacting changes in another
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 // This will leak on purpose. It's the only way to make sure we won't race 1009 // This will leak on purpose. It's the only way to make sure we won't race
1002 // against the static uninitialization of the module while one of our 1010 // against the static uninitialization of the module while one of our
1003 // static methods relying on the lock get called at an inappropriate time 1011 // static methods relying on the lock get called at an inappropriate time
1004 // during the termination phase. Since it's a static data member, we will 1012 // during the termination phase. Since it's a static data member, we will
1005 // leak one per process, which would be similar to the instance allocated 1013 // leak one per process, which would be similar to the instance allocated
1006 // during static initialization and released only on process termination. 1014 // during static initialization and released only on process termination.
1007 lock_ = new base::Lock; 1015 lock_ = new base::Lock;
1008 } 1016 }
1009 base::AutoLock auto_lock(*lock_); 1017 base::AutoLock auto_lock(*lock_);
1010 histograms_ = new HistogramMap; 1018 histograms_ = new HistogramMap;
1019 ranges_ = new RangesMap;
1011 } 1020 }
1012 1021
1013 StatisticsRecorder::~StatisticsRecorder() { 1022 StatisticsRecorder::~StatisticsRecorder() {
1014 DCHECK(histograms_ && lock_); 1023 DCHECK(histograms_ && lock_);
1015 1024
1016 if (dump_on_exit_) { 1025 if (dump_on_exit_) {
1017 std::string output; 1026 std::string output;
1018 WriteGraph("", &output); 1027 WriteGraph("", &output);
1019 LOG(INFO) << output; 1028 LOG(INFO) << output;
1020 } 1029 }
1021 // Clean up. 1030 // Clean up.
1022 HistogramMap* histograms = NULL; 1031 HistogramMap* histograms = NULL;
1023 { 1032 {
1024 base::AutoLock auto_lock(*lock_); 1033 base::AutoLock auto_lock(*lock_);
1025 histograms = histograms_; 1034 histograms = histograms_;
1026 histograms_ = NULL; 1035 histograms_ = NULL;
1027 } 1036 }
1037 RangesMap* ranges = NULL;
1038 {
1039 base::AutoLock auto_lock(*lock_);
1040 ranges = ranges_;
1041 ranges_ = NULL;
1042 }
1043 // We are going to leak the histograms and the ranges.
1028 delete histograms; 1044 delete histograms;
1045 delete ranges;
1029 // We don't delete lock_ on purpose to avoid having to properly protect 1046 // We don't delete lock_ on purpose to avoid having to properly protect
1030 // against it going away after we checked for NULL in the static methods. 1047 // against it going away after we checked for NULL in the static methods.
1031 } 1048 }
1032 1049
1033 // static 1050 // static
1034 bool StatisticsRecorder::IsActive() { 1051 bool StatisticsRecorder::IsActive() {
1035 if (lock_ == NULL) 1052 if (lock_ == NULL)
1036 return false; 1053 return false;
1037 base::AutoLock auto_lock(*lock_); 1054 base::AutoLock auto_lock(*lock_);
1038 return NULL != histograms_; 1055 return NULL != histograms_;
(...skipping 14 matching lines...) Expand all
1053 if (!histograms_) { 1070 if (!histograms_) {
1054 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322 1071 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322
1055 return histogram; 1072 return histogram;
1056 } 1073 }
1057 const std::string name = histogram->histogram_name(); 1074 const std::string name = histogram->histogram_name();
1058 HistogramMap::iterator it = histograms_->find(name); 1075 HistogramMap::iterator it = histograms_->find(name);
1059 // Avoid overwriting a previous registration. 1076 // Avoid overwriting a previous registration.
1060 if (histograms_->end() == it) { 1077 if (histograms_->end() == it) {
1061 (*histograms_)[name] = histogram; 1078 (*histograms_)[name] = histogram;
1062 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322 1079 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322
1080 RegisterOrDeleteDuplicateRanges(histogram);
1081 ++number_of_histograms_;
1063 } else { 1082 } else {
1064 delete histogram; // We already have one by this name. 1083 delete histogram; // We already have one by this name.
1065 histogram = it->second; 1084 histogram = it->second;
1066 } 1085 }
1067 return histogram; 1086 return histogram;
1068 } 1087 }
1069 1088
1070 // static 1089 // static
1090 void StatisticsRecorder::RegisterOrDeleteDuplicateRanges(Histogram* histogram) {
1091 DCHECK(histogram);
1092 CachedRanges* histogram_ranges = histogram->cached_ranges();
1093 DCHECK(histogram_ranges);
1094 uint32 checksum = histogram->range_checksum();
1095 histogram_ranges->SetRangeChecksum(checksum);
1096
1097 RangesMap::iterator ranges_it = ranges_->find(checksum);
1098 if (ranges_->end() == ranges_it) {
1099 // Register the new CachedRanges.
1100 std::list<CachedRanges*>* checksum_matching_list(
1101 new std::list<CachedRanges*>());
1102 checksum_matching_list->push_front(histogram_ranges);
1103 (*ranges_)[checksum] = checksum_matching_list;
1104 return;
1105 }
1106
1107 // Use the registered CachedRanges if the registered CachedRanges has same
1108 // ranges_ as |histogram|'s CachedRanges.
1109 std::list<CachedRanges*>* checksum_matching_list = ranges_it->second;
1110 std::list<CachedRanges*>::iterator checksum_matching_list_it;
1111 for (checksum_matching_list_it = checksum_matching_list->begin();
1112 checksum_matching_list_it != checksum_matching_list->end();
1113 ++checksum_matching_list_it) {
1114 CachedRanges* existing_histogram_ranges = *checksum_matching_list_it;
1115 DCHECK(existing_histogram_ranges);
1116 if (existing_histogram_ranges->Equals(histogram_ranges)) {
1117 histogram->set_cached_ranges(existing_histogram_ranges);
1118 ++number_of_vectors_saved_;
1119 saved_ranges_size_ += histogram_ranges->size();
1120 delete histogram_ranges;
1121 return;
1122 }
1123 }
1124
1125 // We haven't found a CachedRanges which has the same ranges. Register the
1126 // new CachedRanges.
1127 DCHECK(checksum_matching_list_it == checksum_matching_list->end());
1128 checksum_matching_list->push_front(histogram_ranges);
1129 }
1130
1131 // static
1132 void StatisticsRecorder::CollectHistogramStats(const std::string& suffix) {
1133 static int uma_upload_attempt = 0;
1134 ++uma_upload_attempt;
1135 if (uma_upload_attempt == 1) {
1136 UMA_HISTOGRAM_COUNTS_10000(
1137 "Histogram.SharedRange.Count.FirstUpload." + suffix,
1138 number_of_histograms_);
1139 UMA_HISTOGRAM_COUNTS_10000(
1140 "Histogram.SharedRange.RangesSaved.FirstUpload." + suffix,
1141 number_of_vectors_saved_);
1142 UMA_HISTOGRAM_COUNTS(
1143 "Histogram.SharedRange.ElementsSaved.FirstUpload." + suffix,
1144 static_cast<int>(saved_ranges_size_));
1145 number_of_histograms_ = 0;
1146 number_of_vectors_saved_ = 0;
1147 saved_ranges_size_ = 0;
1148 return;
1149 }
1150 if (uma_upload_attempt == 2) {
1151 UMA_HISTOGRAM_COUNTS_10000(
1152 "Histogram.SharedRange.Count.SecondUpload." + suffix,
1153 number_of_histograms_);
1154 UMA_HISTOGRAM_COUNTS_10000(
1155 "Histogram.SharedRange.RangesSaved.SecondUpload." + suffix,
1156 number_of_vectors_saved_);
1157 UMA_HISTOGRAM_COUNTS(
1158 "Histogram.SharedRange.ElementsSaved.SecondUpload." + suffix,
1159 static_cast<int>(saved_ranges_size_));
1160 number_of_histograms_ = 0;
1161 number_of_vectors_saved_ = 0;
1162 saved_ranges_size_ = 0;
1163 return;
1164 }
1165 UMA_HISTOGRAM_COUNTS_10000(
1166 "Histogram.SharedRange.Count.RestOfUploads." + suffix,
1167 number_of_histograms_);
1168 UMA_HISTOGRAM_COUNTS_10000(
1169 "Histogram.SharedRange.RangesSaved.RestOfUploads." + suffix,
1170 number_of_vectors_saved_);
1171 UMA_HISTOGRAM_COUNTS(
1172 "Histogram.SharedRange.ElementsSaved.RestOfUploads." + suffix,
1173 static_cast<int>(saved_ranges_size_));
1174 }
1175
1176 // static
1071 void StatisticsRecorder::WriteHTMLGraph(const std::string& query, 1177 void StatisticsRecorder::WriteHTMLGraph(const std::string& query,
1072 std::string* output) { 1178 std::string* output) {
1073 if (!IsActive()) 1179 if (!IsActive())
1074 return; 1180 return;
1075 1181
1076 Histograms snapshot; 1182 Histograms snapshot;
1077 GetSnapshot(query, &snapshot); 1183 GetSnapshot(query, &snapshot);
1078 for (Histograms::iterator it = snapshot.begin(); 1184 for (Histograms::iterator it = snapshot.begin();
1079 it != snapshot.end(); 1185 it != snapshot.end();
1080 ++it) { 1186 ++it) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 if (!histograms_) 1247 if (!histograms_)
1142 return; 1248 return;
1143 for (HistogramMap::iterator it = histograms_->begin(); 1249 for (HistogramMap::iterator it = histograms_->begin();
1144 histograms_->end() != it; 1250 histograms_->end() != it;
1145 ++it) { 1251 ++it) {
1146 if (it->first.find(query) != std::string::npos) 1252 if (it->first.find(query) != std::string::npos)
1147 snapshot->push_back(it->second); 1253 snapshot->push_back(it->second);
1148 } 1254 }
1149 } 1255 }
1150 1256
1257 CachedRanges::CachedRanges(size_t bucket_count, int initial_value)
1258 : ranges_(bucket_count, initial_value),
1259 range_checksum_(0) {
1260 }
1261
1262 CachedRanges::~CachedRanges() {
1263 }
1264
1265 void CachedRanges::SetBucketRange(size_t i, Histogram::Sample value) {
1266 DCHECK_LT(i, ranges_.size());
1267 DCHECK_GE(value, 0);
1268 ranges_[i] = value;
1269 }
1270
1271 bool CachedRanges::Equals(CachedRanges* other) const {
1272 if (range_checksum_ != other->range_checksum_)
1273 return false;
1274 if (ranges_.size() != other->ranges_.size())
1275 return false;
1276 for (size_t index = 0; index < ranges_.size(); ++index) {
1277 if (ranges_[index] != other->ranges_[index])
1278 return false;
1279 }
1280 return true;
1281 }
1282
1151 // static 1283 // static
1152 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; 1284 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL;
1153 // static 1285 // static
1286 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL;
1287 // static
1154 base::Lock* StatisticsRecorder::lock_ = NULL; 1288 base::Lock* StatisticsRecorder::lock_ = NULL;
1155 // static 1289 // static
1156 bool StatisticsRecorder::dump_on_exit_ = false; 1290 bool StatisticsRecorder::dump_on_exit_ = false;
1157
1158 } // namespace base 1291 } // 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