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 3 // found in the LICENSE file. 4 // 5 // BucketRanges stores the vector of ranges that delimit what samples are 6 // tallied in the corresponding buckets of a histogram. Histograms that have 7 // same ranges for all their corresponding buckets should share the same 8 // BucketRanges object. 9 // 10 // E.g. A 5 buckets LinearHistogram with 1 as minimal value and 4 as maximal 11 // value will need a BucketRanges with 6 ranges: 12 // 0, 1, 2, 3, 4, INT_MAX 13 // 14 // TODO(kaiwang): Currently we keep all negative values in 0~1 bucket. Consider 15 // changing 0 to INT_MIN. 16 17 #ifndef BASE_METRICS_BUCKET_RANGES_H_ 18 #define BASE_METRICS_BUCKET_RANGES_H_ 19 20 #include <stddef.h> 21 #include <stdint.h> 22 23 #include <vector> 24 25 #include <limits.h> 26 27 #include "base/atomicops.h" 28 #include "base/base_export.h" 29 #include "base/macros.h" 30 #include "base/metrics/histogram_base.h" 31 32 namespace base { 33 34 class BASE_EXPORT BucketRanges { 35 public: 36 typedef std::vector<HistogramBase::Sample> Ranges; 37 38 explicit BucketRanges(size_t num_ranges); 39 ~BucketRanges(); 40 size()41 size_t size() const { return ranges_.size(); } range(size_t i)42 HistogramBase::Sample range(size_t i) const { return ranges_[i]; } set_range(size_t i,HistogramBase::Sample value)43 void set_range(size_t i, HistogramBase::Sample value) { 44 DCHECK_LT(i, ranges_.size()); 45 DCHECK_GE(value, 0); 46 ranges_[i] = value; 47 } checksum()48 uint32_t checksum() const { return checksum_; } set_checksum(uint32_t checksum)49 void set_checksum(uint32_t checksum) { checksum_ = checksum; } 50 51 // A bucket is defined by a consecutive pair of entries in |ranges|, so there 52 // is one fewer bucket than there are ranges. For example, if |ranges| is 53 // [0, 1, 3, 7, INT_MAX], then the buckets in this histogram are 54 // [0, 1), [1, 3), [3, 7), and [7, INT_MAX). bucket_count()55 size_t bucket_count() const { return ranges_.size() - 1; } 56 57 // Checksum methods to verify whether the ranges are corrupted (e.g. bad 58 // memory access). 59 uint32_t CalculateChecksum() const; 60 bool HasValidChecksum() const; 61 void ResetChecksum(); 62 63 // Return true iff |other| object has same ranges_ as |this| object's ranges_. 64 bool Equals(const BucketRanges* other) const; 65 66 // Set and get a reference into persistent memory where this bucket data 67 // can be found (and re-used). These calls are internally atomic with no 68 // safety against overwriting an existing value since though it is wasteful 69 // to have multiple identical persistent records, it is still safe. set_persistent_reference(uint32_t ref)70 void set_persistent_reference(uint32_t ref) const { 71 subtle::Release_Store(&persistent_reference_, ref); 72 } persistent_reference()73 uint32_t persistent_reference() const { 74 return subtle::Acquire_Load(&persistent_reference_); 75 } 76 77 private: 78 // A monotonically increasing list of values which determine which bucket to 79 // put a sample into. For each index, show the smallest sample that can be 80 // added to the corresponding bucket. 81 Ranges ranges_; 82 83 // Checksum for the conntents of ranges_. Used to detect random over-writes 84 // of our data, and to quickly see if some other BucketRanges instance is 85 // possibly Equal() to this instance. 86 // TODO(kaiwang): Consider change this to uint64_t. Because we see a lot of 87 // noise on UMA dashboard. 88 uint32_t checksum_; 89 90 // A reference into a global PersistentMemoryAllocator where the ranges 91 // information is stored. This allows for the record to be created once and 92 // re-used simply by having all histograms with the same ranges use the 93 // same reference. 94 mutable subtle::Atomic32 persistent_reference_ = 0; 95 96 DISALLOW_COPY_AND_ASSIGN(BucketRanges); 97 }; 98 99 ////////////////////////////////////////////////////////////////////////////// 100 // Expose only for test. 101 BASE_EXPORT extern const uint32_t kCrcTable[256]; 102 103 } // namespace base 104 105 #endif // BASE_METRICS_BUCKET_RANGES_H_ 106