| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |