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