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