xref: /aosp_15_r20/external/libchrome/base/metrics/histogram.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
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