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