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 // Histogram is an object that aggregates statistics, and can summarize them in 6*6777b538SAndroid Build Coastguard Worker // various forms, including ASCII graphical, HTML, and numerically (as a 7*6777b538SAndroid Build Coastguard Worker // vector of numbers corresponding to each of the aggregating buckets). 8*6777b538SAndroid Build Coastguard Worker 9*6777b538SAndroid Build Coastguard Worker // It supports calls to accumulate either time intervals (which are processed 10*6777b538SAndroid Build Coastguard Worker // as integral number of milliseconds), or arbitrary integral units. 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard Worker // For Histogram (exponential histogram), LinearHistogram and CustomHistogram, 13*6777b538SAndroid Build Coastguard Worker // the minimum for a declared range is 1 (instead of 0), while the maximum is 14*6777b538SAndroid Build Coastguard Worker // (HistogramBase::kSampleType_MAX - 1). However, there will always be underflow 15*6777b538SAndroid Build Coastguard Worker // and overflow buckets added automatically, so a 0 bucket will always exist 16*6777b538SAndroid Build Coastguard Worker // even when a minimum value of 1 is specified. 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Worker // Each use of a histogram with the same name will reference the same underlying 19*6777b538SAndroid Build Coastguard Worker // data, so it is safe to record to the same histogram from multiple locations 20*6777b538SAndroid Build Coastguard Worker // in the code. It is a runtime error if all uses of the same histogram do not 21*6777b538SAndroid Build Coastguard Worker // agree exactly in type, bucket size and range. 22*6777b538SAndroid Build Coastguard Worker 23*6777b538SAndroid Build Coastguard Worker // For Histogram and LinearHistogram, the maximum for a declared range should 24*6777b538SAndroid Build Coastguard Worker // always be larger (not equal) than minimal range. Zero and 25*6777b538SAndroid Build Coastguard Worker // HistogramBase::kSampleType_MAX are implicitly added as first and last ranges, 26*6777b538SAndroid Build Coastguard Worker // so the smallest legal bucket_count is 3. However CustomHistogram can have 27*6777b538SAndroid Build Coastguard Worker // bucket count as 2 (when you give a custom ranges vector containing only 1 28*6777b538SAndroid Build Coastguard Worker // range). 29*6777b538SAndroid Build Coastguard Worker // For these 3 kinds of histograms, the max bucket count is always 30*6777b538SAndroid Build Coastguard Worker // (Histogram::kBucketCount_MAX - 1). 31*6777b538SAndroid Build Coastguard Worker 32*6777b538SAndroid Build Coastguard Worker // The buckets layout of class Histogram is exponential. For example, buckets 33*6777b538SAndroid Build Coastguard Worker // might contain (sequentially) the count of values in the following intervals: 34*6777b538SAndroid Build Coastguard Worker // [0,1), [1,2), [2,4), [4,8), [8,16), [16,32), [32,64), [64,infinity) 35*6777b538SAndroid Build Coastguard Worker // That bucket allocation would actually result from construction of a histogram 36*6777b538SAndroid Build Coastguard Worker // for values between 1 and 64, with 8 buckets, such as: 37*6777b538SAndroid Build Coastguard Worker // Histogram count("some name", 1, 64, 8); 38*6777b538SAndroid Build Coastguard Worker // Note that the underflow bucket [0,1) and the overflow bucket [64,infinity) 39*6777b538SAndroid Build Coastguard Worker // are also counted by the constructor in the user supplied "bucket_count" 40*6777b538SAndroid Build Coastguard Worker // argument. 41*6777b538SAndroid Build Coastguard Worker // The above example has an exponential ratio of 2 (doubling the bucket width 42*6777b538SAndroid Build Coastguard Worker // in each consecutive bucket). The Histogram class automatically calculates 43*6777b538SAndroid Build Coastguard Worker // the smallest ratio that it can use to construct the number of buckets 44*6777b538SAndroid Build Coastguard Worker // selected in the constructor. An another example, if you had 50 buckets, 45*6777b538SAndroid Build Coastguard Worker // and millisecond time values from 1 to 10000, then the ratio between 46*6777b538SAndroid Build Coastguard Worker // consecutive bucket widths will be approximately somewhere around the 50th 47*6777b538SAndroid Build Coastguard Worker // root of 10000. This approach provides very fine grain (narrow) buckets 48*6777b538SAndroid Build Coastguard Worker // at the low end of the histogram scale, but allows the histogram to cover a 49*6777b538SAndroid Build Coastguard Worker // gigantic range with the addition of very few buckets. 50*6777b538SAndroid Build Coastguard Worker 51*6777b538SAndroid Build Coastguard Worker // Usually we use macros to define and use a histogram, which are defined in 52*6777b538SAndroid Build Coastguard Worker // base/metrics/histogram_macros.h. Note: Callers should include that header 53*6777b538SAndroid Build Coastguard Worker // directly if they only access the histogram APIs through macros. 54*6777b538SAndroid Build Coastguard Worker // 55*6777b538SAndroid Build Coastguard Worker // Macros use a pattern involving a function static variable, that is a pointer 56*6777b538SAndroid Build Coastguard Worker // to a histogram. This static is explicitly initialized on any thread 57*6777b538SAndroid Build Coastguard Worker // that detects a uninitialized (NULL) pointer. The potentially racy 58*6777b538SAndroid Build Coastguard Worker // initialization is not a problem as it is always set to point to the same 59*6777b538SAndroid Build Coastguard Worker // value (i.e., the FactoryGet always returns the same value). FactoryGet 60*6777b538SAndroid Build Coastguard Worker // is also completely thread safe, which results in a completely thread safe, 61*6777b538SAndroid Build Coastguard Worker // and relatively fast, set of counters. To avoid races at shutdown, the static 62*6777b538SAndroid Build Coastguard Worker // pointer is NOT deleted, and we leak the histograms at process termination. 63*6777b538SAndroid Build Coastguard Worker 64*6777b538SAndroid Build Coastguard Worker #ifndef BASE_METRICS_HISTOGRAM_H_ 65*6777b538SAndroid Build Coastguard Worker #define BASE_METRICS_HISTOGRAM_H_ 66*6777b538SAndroid Build Coastguard Worker 67*6777b538SAndroid Build Coastguard Worker #include <stddef.h> 68*6777b538SAndroid Build Coastguard Worker #include <stdint.h> 69*6777b538SAndroid Build Coastguard Worker 70*6777b538SAndroid Build Coastguard Worker #include <map> 71*6777b538SAndroid Build Coastguard Worker #include <memory> 72*6777b538SAndroid Build Coastguard Worker #include <string> 73*6777b538SAndroid Build Coastguard Worker #include <string_view> 74*6777b538SAndroid Build Coastguard Worker #include <vector> 75*6777b538SAndroid Build Coastguard Worker 76*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 77*6777b538SAndroid Build Coastguard Worker #include "base/compiler_specific.h" 78*6777b538SAndroid Build Coastguard Worker #include "base/containers/span.h" 79*6777b538SAndroid Build Coastguard Worker #include "base/dcheck_is_on.h" 80*6777b538SAndroid Build Coastguard Worker #include "base/gtest_prod_util.h" 81*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h" 82*6777b538SAndroid Build Coastguard Worker #include "base/metrics/bucket_ranges.h" 83*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram_base.h" 84*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram_samples.h" 85*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h" 86*6777b538SAndroid Build Coastguard Worker #include "base/values.h" 87*6777b538SAndroid Build Coastguard Worker 88*6777b538SAndroid Build Coastguard Worker namespace base { 89*6777b538SAndroid Build Coastguard Worker 90*6777b538SAndroid Build Coastguard Worker class BooleanHistogram; 91*6777b538SAndroid Build Coastguard Worker class CustomHistogram; 92*6777b538SAndroid Build Coastguard Worker class DelayedPersistentAllocation; 93*6777b538SAndroid Build Coastguard Worker class Histogram; 94*6777b538SAndroid Build Coastguard Worker class HistogramTest; 95*6777b538SAndroid Build Coastguard Worker class LinearHistogram; 96*6777b538SAndroid Build Coastguard Worker class Pickle; 97*6777b538SAndroid Build Coastguard Worker class PickleIterator; 98*6777b538SAndroid Build Coastguard Worker class SampleVector; 99*6777b538SAndroid Build Coastguard Worker class SampleVectorBase; 100*6777b538SAndroid Build Coastguard Worker 101*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT Histogram : public HistogramBase { 102*6777b538SAndroid Build Coastguard Worker public: 103*6777b538SAndroid Build Coastguard Worker // Initialize maximum number of buckets in histograms as 1000, plus over and 104*6777b538SAndroid Build Coastguard Worker // under. This must be a value that fits in a uint32_t (since that's how we 105*6777b538SAndroid Build Coastguard Worker // serialize bucket counts) as well as a Sample (since samples can be up to 106*6777b538SAndroid Build Coastguard Worker // this value). 107*6777b538SAndroid Build Coastguard Worker static constexpr size_t kBucketCount_MAX = 1002; 108*6777b538SAndroid Build Coastguard Worker 109*6777b538SAndroid Build Coastguard Worker typedef std::vector<Count> Counts; 110*6777b538SAndroid Build Coastguard Worker 111*6777b538SAndroid Build Coastguard Worker Histogram(const Histogram&) = delete; 112*6777b538SAndroid Build Coastguard Worker Histogram& operator=(const Histogram&) = delete; 113*6777b538SAndroid Build Coastguard Worker 114*6777b538SAndroid Build Coastguard Worker ~Histogram() override; 115*6777b538SAndroid Build Coastguard Worker 116*6777b538SAndroid Build Coastguard Worker //---------------------------------------------------------------------------- 117*6777b538SAndroid Build Coastguard Worker // For a valid histogram, input should follow these restrictions: 118*6777b538SAndroid Build Coastguard Worker // minimum > 0 (if a minimum below 1 is specified, it will implicitly be 119*6777b538SAndroid Build Coastguard Worker // normalized up to 1) 120*6777b538SAndroid Build Coastguard Worker // maximum > minimum 121*6777b538SAndroid Build Coastguard Worker // buckets > 2 [minimum buckets needed: underflow, overflow and the range] 122*6777b538SAndroid Build Coastguard Worker // Additionally, 123*6777b538SAndroid Build Coastguard Worker // buckets <= (maximum - minimum + 2) - this is to ensure that we don't have 124*6777b538SAndroid Build Coastguard Worker // more buckets than the range of numbers; having more buckets than 1 per 125*6777b538SAndroid Build Coastguard Worker // value in the range would be nonsensical. 126*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryGet(const std::string& name, 127*6777b538SAndroid Build Coastguard Worker Sample minimum, 128*6777b538SAndroid Build Coastguard Worker Sample maximum, 129*6777b538SAndroid Build Coastguard Worker size_t bucket_count, 130*6777b538SAndroid Build Coastguard Worker int32_t flags); 131*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryTimeGet(const std::string& name, 132*6777b538SAndroid Build Coastguard Worker base::TimeDelta minimum, 133*6777b538SAndroid Build Coastguard Worker base::TimeDelta maximum, 134*6777b538SAndroid Build Coastguard Worker size_t bucket_count, 135*6777b538SAndroid Build Coastguard Worker int32_t flags); 136*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryMicrosecondsTimeGet(const std::string& name, 137*6777b538SAndroid Build Coastguard Worker base::TimeDelta minimum, 138*6777b538SAndroid Build Coastguard Worker base::TimeDelta maximum, 139*6777b538SAndroid Build Coastguard Worker size_t bucket_count, 140*6777b538SAndroid Build Coastguard Worker int32_t flags); 141*6777b538SAndroid Build Coastguard Worker 142*6777b538SAndroid Build Coastguard Worker // Overloads of the above functions that take a const char* |name| param, to 143*6777b538SAndroid Build Coastguard Worker // avoid code bloat from the std::string constructor being inlined into call 144*6777b538SAndroid Build Coastguard Worker // sites. 145*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryGet(const char* name, 146*6777b538SAndroid Build Coastguard Worker Sample minimum, 147*6777b538SAndroid Build Coastguard Worker Sample maximum, 148*6777b538SAndroid Build Coastguard Worker size_t bucket_count, 149*6777b538SAndroid Build Coastguard Worker int32_t flags); 150*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryTimeGet(const char* name, 151*6777b538SAndroid Build Coastguard Worker base::TimeDelta minimum, 152*6777b538SAndroid Build Coastguard Worker base::TimeDelta maximum, 153*6777b538SAndroid Build Coastguard Worker size_t bucket_count, 154*6777b538SAndroid Build Coastguard Worker int32_t flags); 155*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryMicrosecondsTimeGet(const char* name, 156*6777b538SAndroid Build Coastguard Worker base::TimeDelta minimum, 157*6777b538SAndroid Build Coastguard Worker base::TimeDelta maximum, 158*6777b538SAndroid Build Coastguard Worker size_t bucket_count, 159*6777b538SAndroid Build Coastguard Worker int32_t flags); 160*6777b538SAndroid Build Coastguard Worker 161*6777b538SAndroid Build Coastguard Worker // Create a histogram using data in persistent storage. 162*6777b538SAndroid Build Coastguard Worker static std::unique_ptr<HistogramBase> PersistentCreate( 163*6777b538SAndroid Build Coastguard Worker const char* name, 164*6777b538SAndroid Build Coastguard Worker const BucketRanges* ranges, 165*6777b538SAndroid Build Coastguard Worker const DelayedPersistentAllocation& counts, 166*6777b538SAndroid Build Coastguard Worker const DelayedPersistentAllocation& logged_counts, 167*6777b538SAndroid Build Coastguard Worker HistogramSamples::Metadata* meta, 168*6777b538SAndroid Build Coastguard Worker HistogramSamples::Metadata* logged_meta); 169*6777b538SAndroid Build Coastguard Worker 170*6777b538SAndroid Build Coastguard Worker static void InitializeBucketRanges(Sample minimum, 171*6777b538SAndroid Build Coastguard Worker Sample maximum, 172*6777b538SAndroid Build Coastguard Worker BucketRanges* ranges); 173*6777b538SAndroid Build Coastguard Worker 174*6777b538SAndroid Build Coastguard Worker // This constant if for FindCorruption. Since snapshots of histograms are 175*6777b538SAndroid Build Coastguard Worker // taken asynchronously relative to sampling, and our counting code currently 176*6777b538SAndroid Build Coastguard Worker // does not prevent race conditions, it is pretty likely that we'll catch a 177*6777b538SAndroid Build Coastguard Worker // redundant count that doesn't match the sample count. We allow for a 178*6777b538SAndroid Build Coastguard Worker // certain amount of slop before flagging this as an inconsistency. Even with 179*6777b538SAndroid Build Coastguard Worker // an inconsistency, we'll snapshot it again (for UMA in about a half hour), 180*6777b538SAndroid Build Coastguard Worker // so we'll eventually get the data, if it was not the result of a corruption. 181*6777b538SAndroid Build Coastguard Worker static const int kCommonRaceBasedCountMismatch; 182*6777b538SAndroid Build Coastguard Worker 183*6777b538SAndroid Build Coastguard Worker // Check to see if bucket ranges, counts and tallies in the snapshot are 184*6777b538SAndroid Build Coastguard Worker // consistent with the bucket ranges and checksums in our histogram. This can 185*6777b538SAndroid Build Coastguard Worker // produce a false-alarm if a race occurred in the reading of the data during 186*6777b538SAndroid Build Coastguard Worker // a SnapShot process, but should otherwise be false at all times (unless we 187*6777b538SAndroid Build Coastguard Worker // have memory over-writes, or DRAM failures). Flag definitions are located 188*6777b538SAndroid Build Coastguard Worker // under "enum Inconsistency" in base/metrics/histogram_base.h. 189*6777b538SAndroid Build Coastguard Worker uint32_t FindCorruption(const HistogramSamples& samples) const override; 190*6777b538SAndroid Build Coastguard Worker 191*6777b538SAndroid Build Coastguard Worker //---------------------------------------------------------------------------- 192*6777b538SAndroid Build Coastguard Worker // Accessors for factory construction, serialization and testing. 193*6777b538SAndroid Build Coastguard Worker //---------------------------------------------------------------------------- 194*6777b538SAndroid Build Coastguard Worker const BucketRanges* bucket_ranges() const; 195*6777b538SAndroid Build Coastguard Worker Sample declared_min() const; 196*6777b538SAndroid Build Coastguard Worker Sample declared_max() const; 197*6777b538SAndroid Build Coastguard Worker virtual Sample ranges(size_t i) const; 198*6777b538SAndroid Build Coastguard Worker virtual size_t bucket_count() const; 199*6777b538SAndroid Build Coastguard Worker 200*6777b538SAndroid Build Coastguard Worker // This function validates histogram construction arguments. It returns false 201*6777b538SAndroid Build Coastguard Worker // if some of the arguments are bad but also corrects them so they should 202*6777b538SAndroid Build Coastguard Worker // function on non-dcheck builds without crashing. 203*6777b538SAndroid Build Coastguard Worker // Note. Currently it allow some bad input, e.g. 0 as minimum, but silently 204*6777b538SAndroid Build Coastguard Worker // converts it to good input: 1. 205*6777b538SAndroid Build Coastguard Worker static bool InspectConstructionArguments(std::string_view name, 206*6777b538SAndroid Build Coastguard Worker Sample* minimum, 207*6777b538SAndroid Build Coastguard Worker Sample* maximum, 208*6777b538SAndroid Build Coastguard Worker size_t* bucket_count); 209*6777b538SAndroid Build Coastguard Worker 210*6777b538SAndroid Build Coastguard Worker // HistogramBase implementation: 211*6777b538SAndroid Build Coastguard Worker uint64_t name_hash() const override; 212*6777b538SAndroid Build Coastguard Worker HistogramType GetHistogramType() const override; 213*6777b538SAndroid Build Coastguard Worker bool HasConstructionArguments(Sample expected_minimum, 214*6777b538SAndroid Build Coastguard Worker Sample expected_maximum, 215*6777b538SAndroid Build Coastguard Worker size_t expected_bucket_count) const override; 216*6777b538SAndroid Build Coastguard Worker void Add(Sample value) override; 217*6777b538SAndroid Build Coastguard Worker void AddCount(Sample value, int count) override; 218*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HistogramSamples> SnapshotSamples() const override; 219*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HistogramSamples> SnapshotUnloggedSamples() const override; 220*6777b538SAndroid Build Coastguard Worker void MarkSamplesAsLogged(const HistogramSamples& samples) final; 221*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HistogramSamples> SnapshotDelta() override; 222*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HistogramSamples> SnapshotFinalDelta() const override; 223*6777b538SAndroid Build Coastguard Worker void AddSamples(const HistogramSamples& samples) override; 224*6777b538SAndroid Build Coastguard Worker bool AddSamplesFromPickle(base::PickleIterator* iter) override; 225*6777b538SAndroid Build Coastguard Worker base::Value::Dict ToGraphDict() const override; 226*6777b538SAndroid Build Coastguard Worker 227*6777b538SAndroid Build Coastguard Worker protected: 228*6777b538SAndroid Build Coastguard Worker // This class, defined entirely within the .cc file, contains all the 229*6777b538SAndroid Build Coastguard Worker // common logic for building a Histogram and can be overridden by more 230*6777b538SAndroid Build Coastguard Worker // specific types to alter details of how the creation is done. It is 231*6777b538SAndroid Build Coastguard Worker // defined as an embedded class (rather than an anonymous one) so it 232*6777b538SAndroid Build Coastguard Worker // can access the protected constructors. 233*6777b538SAndroid Build Coastguard Worker class Factory; 234*6777b538SAndroid Build Coastguard Worker 235*6777b538SAndroid Build Coastguard Worker // |ranges| should contain the underflow and overflow buckets. See top 236*6777b538SAndroid Build Coastguard Worker // comments for example. 237*6777b538SAndroid Build Coastguard Worker Histogram(const char* name, const BucketRanges* ranges); 238*6777b538SAndroid Build Coastguard Worker 239*6777b538SAndroid Build Coastguard Worker // Traditionally, histograms allocate their own memory for the bucket 240*6777b538SAndroid Build Coastguard Worker // vector but "shared" histograms use memory regions allocated from a 241*6777b538SAndroid Build Coastguard Worker // special memory segment that is passed in here. It is assumed that 242*6777b538SAndroid Build Coastguard Worker // the life of this memory is managed externally and exceeds the lifetime 243*6777b538SAndroid Build Coastguard Worker // of this object. Practically, this memory is never released until the 244*6777b538SAndroid Build Coastguard Worker // process exits and the OS cleans it up. 245*6777b538SAndroid Build Coastguard Worker Histogram(const char* name, 246*6777b538SAndroid Build Coastguard Worker const BucketRanges* ranges, 247*6777b538SAndroid Build Coastguard Worker const DelayedPersistentAllocation& counts, 248*6777b538SAndroid Build Coastguard Worker const DelayedPersistentAllocation& logged_counts, 249*6777b538SAndroid Build Coastguard Worker HistogramSamples::Metadata* meta, 250*6777b538SAndroid Build Coastguard Worker HistogramSamples::Metadata* logged_meta); 251*6777b538SAndroid Build Coastguard Worker 252*6777b538SAndroid Build Coastguard Worker // HistogramBase implementation: 253*6777b538SAndroid Build Coastguard Worker void SerializeInfoImpl(base::Pickle* pickle) const override; 254*6777b538SAndroid Build Coastguard Worker 255*6777b538SAndroid Build Coastguard Worker // Return a string description of what goes in a given bucket. 256*6777b538SAndroid Build Coastguard Worker // Most commonly this is the numeric value, but in derived classes it may 257*6777b538SAndroid Build Coastguard Worker // be a name (or string description) given to the bucket. 258*6777b538SAndroid Build Coastguard Worker virtual const std::string GetAsciiBucketRange(size_t it) const; 259*6777b538SAndroid Build Coastguard Worker 260*6777b538SAndroid Build Coastguard Worker private: 261*6777b538SAndroid Build Coastguard Worker // Allow tests to corrupt our innards for testing purposes. 262*6777b538SAndroid Build Coastguard Worker friend class HistogramTest; 263*6777b538SAndroid Build Coastguard Worker friend class HistogramThreadsafeTest; 264*6777b538SAndroid Build Coastguard Worker FRIEND_TEST_ALL_PREFIXES(HistogramTest, BoundsTest); 265*6777b538SAndroid Build Coastguard Worker FRIEND_TEST_ALL_PREFIXES(HistogramTest, BucketPlacementTest); 266*6777b538SAndroid Build Coastguard Worker FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts); 267*6777b538SAndroid Build Coastguard Worker 268*6777b538SAndroid Build Coastguard Worker friend class StatisticsRecorder; // To allow it to delete duplicates. 269*6777b538SAndroid Build Coastguard Worker friend class StatisticsRecorderTest; 270*6777b538SAndroid Build Coastguard Worker 271*6777b538SAndroid Build Coastguard Worker friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( 272*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter); 273*6777b538SAndroid Build Coastguard Worker static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); 274*6777b538SAndroid Build Coastguard Worker 275*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryGetInternal(std::string_view name, 276*6777b538SAndroid Build Coastguard Worker Sample minimum, 277*6777b538SAndroid Build Coastguard Worker Sample maximum, 278*6777b538SAndroid Build Coastguard Worker size_t bucket_count, 279*6777b538SAndroid Build Coastguard Worker int32_t flags); 280*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryTimeGetInternal(std::string_view name, 281*6777b538SAndroid Build Coastguard Worker base::TimeDelta minimum, 282*6777b538SAndroid Build Coastguard Worker base::TimeDelta maximum, 283*6777b538SAndroid Build Coastguard Worker size_t bucket_count, 284*6777b538SAndroid Build Coastguard Worker int32_t flags); 285*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryMicrosecondsTimeGetInternal( 286*6777b538SAndroid Build Coastguard Worker std::string_view name, 287*6777b538SAndroid Build Coastguard Worker base::TimeDelta minimum, 288*6777b538SAndroid Build Coastguard Worker base::TimeDelta maximum, 289*6777b538SAndroid Build Coastguard Worker size_t bucket_count, 290*6777b538SAndroid Build Coastguard Worker int32_t flags); 291*6777b538SAndroid Build Coastguard Worker 292*6777b538SAndroid Build Coastguard Worker // Create a snapshot containing all samples (both logged and unlogged). 293*6777b538SAndroid Build Coastguard Worker // Implementation of SnapshotSamples method with a more specific type for 294*6777b538SAndroid Build Coastguard Worker // internal use. 295*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SampleVector> SnapshotAllSamples() const; 296*6777b538SAndroid Build Coastguard Worker 297*6777b538SAndroid Build Coastguard Worker // Returns a copy of unlogged samples as the underlying SampleVector class, 298*6777b538SAndroid Build Coastguard Worker // instead of the HistogramSamples base class. Used for tests and to avoid 299*6777b538SAndroid Build Coastguard Worker // virtual dispatch from some callsites. 300*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SampleVector> SnapshotUnloggedSamplesImpl() const; 301*6777b538SAndroid Build Coastguard Worker 302*6777b538SAndroid Build Coastguard Worker // Writes the type, min, max, and bucket count information of the histogram in 303*6777b538SAndroid Build Coastguard Worker // |params|. 304*6777b538SAndroid Build Coastguard Worker Value::Dict GetParameters() const override; 305*6777b538SAndroid Build Coastguard Worker 306*6777b538SAndroid Build Coastguard Worker // Samples that have not yet been logged with SnapshotDelta(). 307*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SampleVectorBase> unlogged_samples_; 308*6777b538SAndroid Build Coastguard Worker 309*6777b538SAndroid Build Coastguard Worker // Accumulation of all samples that have been logged with SnapshotDelta(). 310*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SampleVectorBase> logged_samples_; 311*6777b538SAndroid Build Coastguard Worker 312*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON() // Don't waste memory if it won't be used. 313*6777b538SAndroid Build Coastguard Worker // Flag to indicate if PrepareFinalDelta has been previously called. It is 314*6777b538SAndroid Build Coastguard Worker // used to DCHECK that a final delta is not created multiple times. 315*6777b538SAndroid Build Coastguard Worker mutable bool final_delta_created_ = false; 316*6777b538SAndroid Build Coastguard Worker #endif 317*6777b538SAndroid Build Coastguard Worker }; 318*6777b538SAndroid Build Coastguard Worker 319*6777b538SAndroid Build Coastguard Worker //------------------------------------------------------------------------------ 320*6777b538SAndroid Build Coastguard Worker 321*6777b538SAndroid Build Coastguard Worker // LinearHistogram is a more traditional histogram, with evenly spaced 322*6777b538SAndroid Build Coastguard Worker // buckets. 323*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT LinearHistogram : public Histogram { 324*6777b538SAndroid Build Coastguard Worker public: 325*6777b538SAndroid Build Coastguard Worker LinearHistogram(const LinearHistogram&) = delete; 326*6777b538SAndroid Build Coastguard Worker LinearHistogram& operator=(const LinearHistogram&) = delete; 327*6777b538SAndroid Build Coastguard Worker 328*6777b538SAndroid Build Coastguard Worker ~LinearHistogram() override; 329*6777b538SAndroid Build Coastguard Worker 330*6777b538SAndroid Build Coastguard Worker /* minimum should start from 1. 0 is as minimum is invalid. 0 is an implicit 331*6777b538SAndroid Build Coastguard Worker default underflow bucket. */ 332*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryGet(const std::string& name, 333*6777b538SAndroid Build Coastguard Worker Sample minimum, 334*6777b538SAndroid Build Coastguard Worker Sample maximum, 335*6777b538SAndroid Build Coastguard Worker size_t bucket_count, 336*6777b538SAndroid Build Coastguard Worker int32_t flags); 337*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryTimeGet(const std::string& name, 338*6777b538SAndroid Build Coastguard Worker TimeDelta minimum, 339*6777b538SAndroid Build Coastguard Worker TimeDelta maximum, 340*6777b538SAndroid Build Coastguard Worker size_t bucket_count, 341*6777b538SAndroid Build Coastguard Worker int32_t flags); 342*6777b538SAndroid Build Coastguard Worker 343*6777b538SAndroid Build Coastguard Worker // Overloads of the above two functions that take a const char* |name| param, 344*6777b538SAndroid Build Coastguard Worker // to avoid code bloat from the std::string constructor being inlined into 345*6777b538SAndroid Build Coastguard Worker // call sites. 346*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryGet(const char* name, 347*6777b538SAndroid Build Coastguard Worker Sample minimum, 348*6777b538SAndroid Build Coastguard Worker Sample maximum, 349*6777b538SAndroid Build Coastguard Worker size_t bucket_count, 350*6777b538SAndroid Build Coastguard Worker int32_t flags); 351*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryTimeGet(const char* name, 352*6777b538SAndroid Build Coastguard Worker TimeDelta minimum, 353*6777b538SAndroid Build Coastguard Worker TimeDelta maximum, 354*6777b538SAndroid Build Coastguard Worker size_t bucket_count, 355*6777b538SAndroid Build Coastguard Worker int32_t flags); 356*6777b538SAndroid Build Coastguard Worker 357*6777b538SAndroid Build Coastguard Worker // Create a histogram using data in persistent storage. 358*6777b538SAndroid Build Coastguard Worker static std::unique_ptr<HistogramBase> PersistentCreate( 359*6777b538SAndroid Build Coastguard Worker const char* name, 360*6777b538SAndroid Build Coastguard Worker const BucketRanges* ranges, 361*6777b538SAndroid Build Coastguard Worker const DelayedPersistentAllocation& counts, 362*6777b538SAndroid Build Coastguard Worker const DelayedPersistentAllocation& logged_counts, 363*6777b538SAndroid Build Coastguard Worker HistogramSamples::Metadata* meta, 364*6777b538SAndroid Build Coastguard Worker HistogramSamples::Metadata* logged_meta); 365*6777b538SAndroid Build Coastguard Worker 366*6777b538SAndroid Build Coastguard Worker struct DescriptionPair { 367*6777b538SAndroid Build Coastguard Worker Sample sample; 368*6777b538SAndroid Build Coastguard Worker const char* description; // Null means end of a list of pairs. 369*6777b538SAndroid Build Coastguard Worker }; 370*6777b538SAndroid Build Coastguard Worker 371*6777b538SAndroid Build Coastguard Worker // Create a LinearHistogram and store a list of number/text values for use in 372*6777b538SAndroid Build Coastguard Worker // writing the histogram graph. 373*6777b538SAndroid Build Coastguard Worker // |descriptions| can be NULL, which means no special descriptions to set. If 374*6777b538SAndroid Build Coastguard Worker // it's not NULL, the last element in the array must has a NULL in its 375*6777b538SAndroid Build Coastguard Worker // "description" field. 376*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryGetWithRangeDescription( 377*6777b538SAndroid Build Coastguard Worker std::string_view name, 378*6777b538SAndroid Build Coastguard Worker Sample minimum, 379*6777b538SAndroid Build Coastguard Worker Sample maximum, 380*6777b538SAndroid Build Coastguard Worker size_t bucket_count, 381*6777b538SAndroid Build Coastguard Worker int32_t flags, 382*6777b538SAndroid Build Coastguard Worker const DescriptionPair descriptions[]); 383*6777b538SAndroid Build Coastguard Worker 384*6777b538SAndroid Build Coastguard Worker static void InitializeBucketRanges(Sample minimum, 385*6777b538SAndroid Build Coastguard Worker Sample maximum, 386*6777b538SAndroid Build Coastguard Worker BucketRanges* ranges); 387*6777b538SAndroid Build Coastguard Worker 388*6777b538SAndroid Build Coastguard Worker // Overridden from Histogram: 389*6777b538SAndroid Build Coastguard Worker HistogramType GetHistogramType() const override; 390*6777b538SAndroid Build Coastguard Worker 391*6777b538SAndroid Build Coastguard Worker protected: 392*6777b538SAndroid Build Coastguard Worker class Factory; 393*6777b538SAndroid Build Coastguard Worker 394*6777b538SAndroid Build Coastguard Worker LinearHistogram(const char* name, const BucketRanges* ranges); 395*6777b538SAndroid Build Coastguard Worker 396*6777b538SAndroid Build Coastguard Worker LinearHistogram(const char* name, 397*6777b538SAndroid Build Coastguard Worker const BucketRanges* ranges, 398*6777b538SAndroid Build Coastguard Worker const DelayedPersistentAllocation& counts, 399*6777b538SAndroid Build Coastguard Worker const DelayedPersistentAllocation& logged_counts, 400*6777b538SAndroid Build Coastguard Worker HistogramSamples::Metadata* meta, 401*6777b538SAndroid Build Coastguard Worker HistogramSamples::Metadata* logged_meta); 402*6777b538SAndroid Build Coastguard Worker 403*6777b538SAndroid Build Coastguard Worker // If we have a description for a bucket, then return that. Otherwise 404*6777b538SAndroid Build Coastguard Worker // let parent class provide a (numeric) description. 405*6777b538SAndroid Build Coastguard Worker const std::string GetAsciiBucketRange(size_t i) const override; 406*6777b538SAndroid Build Coastguard Worker 407*6777b538SAndroid Build Coastguard Worker private: 408*6777b538SAndroid Build Coastguard Worker friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( 409*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter); 410*6777b538SAndroid Build Coastguard Worker static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); 411*6777b538SAndroid Build Coastguard Worker 412*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryGetInternal(std::string_view name, 413*6777b538SAndroid Build Coastguard Worker Sample minimum, 414*6777b538SAndroid Build Coastguard Worker Sample maximum, 415*6777b538SAndroid Build Coastguard Worker size_t bucket_count, 416*6777b538SAndroid Build Coastguard Worker int32_t flags); 417*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryTimeGetInternal(std::string_view name, 418*6777b538SAndroid Build Coastguard Worker TimeDelta minimum, 419*6777b538SAndroid Build Coastguard Worker TimeDelta maximum, 420*6777b538SAndroid Build Coastguard Worker size_t bucket_count, 421*6777b538SAndroid Build Coastguard Worker int32_t flags); 422*6777b538SAndroid Build Coastguard Worker 423*6777b538SAndroid Build Coastguard Worker // For some ranges, we store a printable description of a bucket range. 424*6777b538SAndroid Build Coastguard Worker // If there is no description, then GetAsciiBucketRange() uses parent class 425*6777b538SAndroid Build Coastguard Worker // to provide a description. 426*6777b538SAndroid Build Coastguard Worker typedef std::map<Sample, std::string> BucketDescriptionMap; 427*6777b538SAndroid Build Coastguard Worker BucketDescriptionMap bucket_description_; 428*6777b538SAndroid Build Coastguard Worker }; 429*6777b538SAndroid Build Coastguard Worker 430*6777b538SAndroid Build Coastguard Worker //------------------------------------------------------------------------------ 431*6777b538SAndroid Build Coastguard Worker 432*6777b538SAndroid Build Coastguard Worker // ScaledLinearHistogram is a wrapper around a linear histogram that scales the 433*6777b538SAndroid Build Coastguard Worker // counts down by some factor. Remainder values are kept locally but lost when 434*6777b538SAndroid Build Coastguard Worker // uploaded or serialized. The integral counts are rounded up/down so should 435*6777b538SAndroid Build Coastguard Worker // average to the correct value when many reports are added. 436*6777b538SAndroid Build Coastguard Worker // 437*6777b538SAndroid Build Coastguard Worker // This is most useful when adding many counts at once via AddCount() that can 438*6777b538SAndroid Build Coastguard Worker // cause overflows of the 31-bit counters, usually with an enum as the value. 439*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT ScaledLinearHistogram { 440*6777b538SAndroid Build Coastguard Worker using AtomicCount = Histogram::AtomicCount; 441*6777b538SAndroid Build Coastguard Worker using Sample = Histogram::Sample; 442*6777b538SAndroid Build Coastguard Worker 443*6777b538SAndroid Build Coastguard Worker public: 444*6777b538SAndroid Build Coastguard Worker // Currently only works with "exact" linear histograms: minimum=1, maximum=N, 445*6777b538SAndroid Build Coastguard Worker // and bucket_count=N+1. 446*6777b538SAndroid Build Coastguard Worker ScaledLinearHistogram(const char* name, 447*6777b538SAndroid Build Coastguard Worker Sample minimum, 448*6777b538SAndroid Build Coastguard Worker Sample maximum, 449*6777b538SAndroid Build Coastguard Worker size_t bucket_count, 450*6777b538SAndroid Build Coastguard Worker int32_t scale, 451*6777b538SAndroid Build Coastguard Worker int32_t flags); 452*6777b538SAndroid Build Coastguard Worker ScaledLinearHistogram(const std::string& name, 453*6777b538SAndroid Build Coastguard Worker Sample minimum, 454*6777b538SAndroid Build Coastguard Worker Sample maximum, 455*6777b538SAndroid Build Coastguard Worker size_t bucket_count, 456*6777b538SAndroid Build Coastguard Worker int32_t scale, 457*6777b538SAndroid Build Coastguard Worker int32_t flags); 458*6777b538SAndroid Build Coastguard Worker 459*6777b538SAndroid Build Coastguard Worker ScaledLinearHistogram(const ScaledLinearHistogram&) = delete; 460*6777b538SAndroid Build Coastguard Worker ScaledLinearHistogram& operator=(const ScaledLinearHistogram&) = delete; 461*6777b538SAndroid Build Coastguard Worker 462*6777b538SAndroid Build Coastguard Worker ~ScaledLinearHistogram(); 463*6777b538SAndroid Build Coastguard Worker 464*6777b538SAndroid Build Coastguard Worker // Like AddCount() but actually accumulates |count|/|scale| and increments 465*6777b538SAndroid Build Coastguard Worker // the accumulated remainder by |count|%|scale|. An additional increment 466*6777b538SAndroid Build Coastguard Worker // is done when the remainder has grown sufficiently large. 467*6777b538SAndroid Build Coastguard Worker // The value after scaling must fit into 32-bit signed integer. 468*6777b538SAndroid Build Coastguard Worker void AddScaledCount(Sample value, int64_t count); 469*6777b538SAndroid Build Coastguard Worker scale()470*6777b538SAndroid Build Coastguard Worker int32_t scale() const { return scale_; } histogram()471*6777b538SAndroid Build Coastguard Worker HistogramBase* histogram() { return histogram_; } 472*6777b538SAndroid Build Coastguard Worker 473*6777b538SAndroid Build Coastguard Worker private: 474*6777b538SAndroid Build Coastguard Worker // Pointer to the underlying histogram. Ownership of it remains with 475*6777b538SAndroid Build Coastguard Worker // the statistics-recorder. This is typed as HistogramBase because it may be a 476*6777b538SAndroid Build Coastguard Worker // DummyHistogram if expired. 477*6777b538SAndroid Build Coastguard Worker const raw_ptr<HistogramBase> histogram_; 478*6777b538SAndroid Build Coastguard Worker 479*6777b538SAndroid Build Coastguard Worker // The scale factor of the sample counts. 480*6777b538SAndroid Build Coastguard Worker const int32_t scale_; 481*6777b538SAndroid Build Coastguard Worker 482*6777b538SAndroid Build Coastguard Worker // A vector of "remainder" counts indexed by bucket number. These values 483*6777b538SAndroid Build Coastguard Worker // may be negative as the scaled count is actually bumped once the 484*6777b538SAndroid Build Coastguard Worker // remainder is 1/2 way to the scale value (thus "rounding"). 485*6777b538SAndroid Build Coastguard Worker std::vector<AtomicCount> remainders_; 486*6777b538SAndroid Build Coastguard Worker }; 487*6777b538SAndroid Build Coastguard Worker 488*6777b538SAndroid Build Coastguard Worker //------------------------------------------------------------------------------ 489*6777b538SAndroid Build Coastguard Worker 490*6777b538SAndroid Build Coastguard Worker // BooleanHistogram is a histogram for booleans. 491*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT BooleanHistogram : public LinearHistogram { 492*6777b538SAndroid Build Coastguard Worker public: 493*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryGet(const std::string& name, int32_t flags); 494*6777b538SAndroid Build Coastguard Worker 495*6777b538SAndroid Build Coastguard Worker // Overload of the above function that takes a const char* |name| param, 496*6777b538SAndroid Build Coastguard Worker // to avoid code bloat from the std::string constructor being inlined into 497*6777b538SAndroid Build Coastguard Worker // call sites. 498*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryGet(const char* name, int32_t flags); 499*6777b538SAndroid Build Coastguard Worker 500*6777b538SAndroid Build Coastguard Worker BooleanHistogram(const BooleanHistogram&) = delete; 501*6777b538SAndroid Build Coastguard Worker BooleanHistogram& operator=(const BooleanHistogram&) = delete; 502*6777b538SAndroid Build Coastguard Worker 503*6777b538SAndroid Build Coastguard Worker // Create a histogram using data in persistent storage. 504*6777b538SAndroid Build Coastguard Worker static std::unique_ptr<HistogramBase> PersistentCreate( 505*6777b538SAndroid Build Coastguard Worker const char* name, 506*6777b538SAndroid Build Coastguard Worker const BucketRanges* ranges, 507*6777b538SAndroid Build Coastguard Worker const DelayedPersistentAllocation& counts, 508*6777b538SAndroid Build Coastguard Worker const DelayedPersistentAllocation& logged_counts, 509*6777b538SAndroid Build Coastguard Worker HistogramSamples::Metadata* meta, 510*6777b538SAndroid Build Coastguard Worker HistogramSamples::Metadata* logged_meta); 511*6777b538SAndroid Build Coastguard Worker 512*6777b538SAndroid Build Coastguard Worker HistogramType GetHistogramType() const override; 513*6777b538SAndroid Build Coastguard Worker 514*6777b538SAndroid Build Coastguard Worker protected: 515*6777b538SAndroid Build Coastguard Worker class Factory; 516*6777b538SAndroid Build Coastguard Worker 517*6777b538SAndroid Build Coastguard Worker private: 518*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryGetInternal(std::string_view name, 519*6777b538SAndroid Build Coastguard Worker int32_t flags); 520*6777b538SAndroid Build Coastguard Worker 521*6777b538SAndroid Build Coastguard Worker BooleanHistogram(const char* name, const BucketRanges* ranges); 522*6777b538SAndroid Build Coastguard Worker BooleanHistogram(const char* name, 523*6777b538SAndroid Build Coastguard Worker const BucketRanges* ranges, 524*6777b538SAndroid Build Coastguard Worker const DelayedPersistentAllocation& counts, 525*6777b538SAndroid Build Coastguard Worker const DelayedPersistentAllocation& logged_counts, 526*6777b538SAndroid Build Coastguard Worker HistogramSamples::Metadata* meta, 527*6777b538SAndroid Build Coastguard Worker HistogramSamples::Metadata* logged_meta); 528*6777b538SAndroid Build Coastguard Worker 529*6777b538SAndroid Build Coastguard Worker friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( 530*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter); 531*6777b538SAndroid Build Coastguard Worker static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); 532*6777b538SAndroid Build Coastguard Worker }; 533*6777b538SAndroid Build Coastguard Worker 534*6777b538SAndroid Build Coastguard Worker //------------------------------------------------------------------------------ 535*6777b538SAndroid Build Coastguard Worker 536*6777b538SAndroid Build Coastguard Worker // CustomHistogram is a histogram for a set of custom integers. 537*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT CustomHistogram : public Histogram { 538*6777b538SAndroid Build Coastguard Worker public: 539*6777b538SAndroid Build Coastguard Worker // |custom_ranges| contains a vector of limits on ranges. Each limit should be 540*6777b538SAndroid Build Coastguard Worker // > 0 and < kSampleType_MAX. (Currently 0 is still accepted for backward 541*6777b538SAndroid Build Coastguard Worker // compatibility). The limits can be unordered or contain duplication, but 542*6777b538SAndroid Build Coastguard Worker // client should not depend on this. 543*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryGet(const std::string& name, 544*6777b538SAndroid Build Coastguard Worker const std::vector<Sample>& custom_ranges, 545*6777b538SAndroid Build Coastguard Worker int32_t flags); 546*6777b538SAndroid Build Coastguard Worker 547*6777b538SAndroid Build Coastguard Worker // Overload of the above function that takes a const char* |name| param, 548*6777b538SAndroid Build Coastguard Worker // to avoid code bloat from the std::string constructor being inlined into 549*6777b538SAndroid Build Coastguard Worker // call sites. 550*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryGet(const char* name, 551*6777b538SAndroid Build Coastguard Worker const std::vector<Sample>& custom_ranges, 552*6777b538SAndroid Build Coastguard Worker int32_t flags); 553*6777b538SAndroid Build Coastguard Worker 554*6777b538SAndroid Build Coastguard Worker CustomHistogram(const CustomHistogram&) = delete; 555*6777b538SAndroid Build Coastguard Worker CustomHistogram& operator=(const CustomHistogram&) = delete; 556*6777b538SAndroid Build Coastguard Worker 557*6777b538SAndroid Build Coastguard Worker // Create a histogram using data in persistent storage. 558*6777b538SAndroid Build Coastguard Worker static std::unique_ptr<HistogramBase> PersistentCreate( 559*6777b538SAndroid Build Coastguard Worker const char* name, 560*6777b538SAndroid Build Coastguard Worker const BucketRanges* ranges, 561*6777b538SAndroid Build Coastguard Worker const DelayedPersistentAllocation& counts, 562*6777b538SAndroid Build Coastguard Worker const DelayedPersistentAllocation& logged_counts, 563*6777b538SAndroid Build Coastguard Worker HistogramSamples::Metadata* meta, 564*6777b538SAndroid Build Coastguard Worker HistogramSamples::Metadata* logged_meta); 565*6777b538SAndroid Build Coastguard Worker 566*6777b538SAndroid Build Coastguard Worker // Overridden from Histogram: 567*6777b538SAndroid Build Coastguard Worker HistogramType GetHistogramType() const override; 568*6777b538SAndroid Build Coastguard Worker 569*6777b538SAndroid Build Coastguard Worker // Helper method for transforming an array of valid enumeration values 570*6777b538SAndroid Build Coastguard Worker // to the std::vector<int> expected by UMA_HISTOGRAM_CUSTOM_ENUMERATION. 571*6777b538SAndroid Build Coastguard Worker // This function ensures that a guard bucket exists right after any 572*6777b538SAndroid Build Coastguard Worker // valid sample value (unless the next higher sample is also a valid value), 573*6777b538SAndroid Build Coastguard Worker // so that invalid samples never fall into the same bucket as valid samples. 574*6777b538SAndroid Build Coastguard Worker static std::vector<Sample> ArrayToCustomEnumRanges( 575*6777b538SAndroid Build Coastguard Worker base::span<const Sample> values); 576*6777b538SAndroid Build Coastguard Worker 577*6777b538SAndroid Build Coastguard Worker protected: 578*6777b538SAndroid Build Coastguard Worker class Factory; 579*6777b538SAndroid Build Coastguard Worker 580*6777b538SAndroid Build Coastguard Worker CustomHistogram(const char* name, const BucketRanges* ranges); 581*6777b538SAndroid Build Coastguard Worker 582*6777b538SAndroid Build Coastguard Worker CustomHistogram(const char* name, 583*6777b538SAndroid Build Coastguard Worker const BucketRanges* ranges, 584*6777b538SAndroid Build Coastguard Worker const DelayedPersistentAllocation& counts, 585*6777b538SAndroid Build Coastguard Worker const DelayedPersistentAllocation& logged_counts, 586*6777b538SAndroid Build Coastguard Worker HistogramSamples::Metadata* meta, 587*6777b538SAndroid Build Coastguard Worker HistogramSamples::Metadata* logged_meta); 588*6777b538SAndroid Build Coastguard Worker 589*6777b538SAndroid Build Coastguard Worker // HistogramBase implementation: 590*6777b538SAndroid Build Coastguard Worker void SerializeInfoImpl(base::Pickle* pickle) const override; 591*6777b538SAndroid Build Coastguard Worker 592*6777b538SAndroid Build Coastguard Worker private: 593*6777b538SAndroid Build Coastguard Worker friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( 594*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter); 595*6777b538SAndroid Build Coastguard Worker static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); 596*6777b538SAndroid Build Coastguard Worker 597*6777b538SAndroid Build Coastguard Worker static HistogramBase* FactoryGetInternal( 598*6777b538SAndroid Build Coastguard Worker std::string_view name, 599*6777b538SAndroid Build Coastguard Worker const std::vector<Sample>& custom_ranges, 600*6777b538SAndroid Build Coastguard Worker int32_t flags); 601*6777b538SAndroid Build Coastguard Worker 602*6777b538SAndroid Build Coastguard Worker static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges); 603*6777b538SAndroid Build Coastguard Worker }; 604*6777b538SAndroid Build Coastguard Worker 605*6777b538SAndroid Build Coastguard Worker } // namespace base 606*6777b538SAndroid Build Coastguard Worker 607*6777b538SAndroid Build Coastguard Worker #endif // BASE_METRICS_HISTOGRAM_H_ 608