[email protected] | a93721e2 | 2012-01-06 02:13:28 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 4 | |
| 5 | // Histogram is an object that aggregates statistics, and can summarize them in |
| 6 | // various forms, including ASCII graphical, HTML, and numerically (as a |
| 7 | // vector of numbers corresponding to each of the aggregating buckets). |
| 8 | |
| 9 | // It supports calls to accumulate either time intervals (which are processed |
| 10 | // as integral number of milliseconds), or arbitrary integral units. |
| 11 | |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 12 | // For Histogram(exponential histogram), LinearHistogram and CustomHistogram, |
| 13 | // the minimum for a declared range is 1 (instead of 0), while the maximum is |
| 14 | // (HistogramBase::kSampleType_MAX - 1). Currently you can declare histograms |
| 15 | // with ranges exceeding those limits (e.g. 0 as minimal or |
| 16 | // HistogramBase::kSampleType_MAX as maximal), but those excesses will be |
| 17 | // silently clamped to those limits (for backwards compatibility with existing |
| 18 | // code). Best practice is to not exceed the limits. |
| 19 | |
[email protected] | 5841981 | 2012-10-27 12:44:07 | [diff] [blame] | 20 | // Each use of a histogram with the same name will reference the same underlying |
| 21 | // data, so it is safe to record to the same histogram from multiple locations |
| 22 | // in the code. It is a runtime error if all uses of the same histogram do not |
| 23 | // agree exactly in type, bucket size and range. |
| 24 | |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 25 | // For Histogram and LinearHistogram, the maximum for a declared range should |
[email protected] | ed0f237 | 2013-11-20 08:37:34 | [diff] [blame] | 26 | // always be larger (not equal) than minimal range. Zero and |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 27 | // HistogramBase::kSampleType_MAX are implicitly added as first and last ranges, |
| 28 | // so the smallest legal bucket_count is 3. However CustomHistogram can have |
| 29 | // bucket count as 2 (when you give a custom ranges vector containing only 1 |
| 30 | // range). |
| 31 | // For these 3 kinds of histograms, the max bucket count is always |
| 32 | // (Histogram::kBucketCount_MAX - 1). |
| 33 | |
| 34 | // The buckets layout of class Histogram is exponential. For example, buckets |
| 35 | // might contain (sequentially) the count of values in the following intervals: |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 36 | // [0,1), [1,2), [2,4), [4,8), [8,16), [16,32), [32,64), [64,infinity) |
| 37 | // That bucket allocation would actually result from construction of a histogram |
| 38 | // for values between 1 and 64, with 8 buckets, such as: |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 39 | // Histogram count("some name", 1, 64, 8); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 40 | // Note that the underflow bucket [0,1) and the overflow bucket [64,infinity) |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 41 | // are also counted by the constructor in the user supplied "bucket_count" |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 42 | // argument. |
| 43 | // The above example has an exponential ratio of 2 (doubling the bucket width |
| 44 | // in each consecutive bucket. The Histogram class automatically calculates |
| 45 | // the smallest ratio that it can use to construct the number of buckets |
| 46 | // selected in the constructor. An another example, if you had 50 buckets, |
| 47 | // and millisecond time values from 1 to 10000, then the ratio between |
| 48 | // consecutive bucket widths will be approximately somewhere around the 50th |
| 49 | // root of 10000. This approach provides very fine grain (narrow) buckets |
| 50 | // at the low end of the histogram scale, but allows the histogram to cover a |
| 51 | // gigantic range with the addition of very few buckets. |
| 52 | |
asvitkine | d7bf9c45 | 2014-11-15 01:47:07 | [diff] [blame] | 53 | // Usually we use macros to define and use a histogram, which are defined in |
| 54 | // base/metrics/histogram_macros.h. Note: Callers should include that header |
| 55 | // directly if they only access the histogram APIs through macros. |
| 56 | // |
| 57 | // Macros use a pattern involving a function static variable, that is a pointer |
| 58 | // to a histogram. This static is explicitly initialized on any thread |
[email protected] | 81ce9f3b | 2011-04-05 04:48:53 | [diff] [blame] | 59 | // that detects a uninitialized (NULL) pointer. The potentially racy |
| 60 | // initialization is not a problem as it is always set to point to the same |
| 61 | // value (i.e., the FactoryGet always returns the same value). FactoryGet |
| 62 | // is also completely thread safe, which results in a completely thread safe, |
| 63 | // and relatively fast, set of counters. To avoid races at shutdown, the static |
| 64 | // pointer is NOT deleted, and we leak the histograms at process termination. |
| 65 | |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 66 | #ifndef BASE_METRICS_HISTOGRAM_H_ |
| 67 | #define BASE_METRICS_HISTOGRAM_H_ |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 68 | |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 69 | #include <stddef.h> |
| 70 | #include <stdint.h> |
| 71 | |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 72 | #include <map> |
| 73 | #include <string> |
| 74 | #include <vector> |
| 75 | |
[email protected] | 0bea725 | 2011-08-05 15:34:00 | [diff] [blame] | 76 | #include "base/base_export.h" |
[email protected] | cd56dff | 2011-11-13 04:19:15 | [diff] [blame] | 77 | #include "base/compiler_specific.h" |
[email protected] | 93a41d7 | 2010-11-03 23:36:24 | [diff] [blame] | 78 | #include "base/gtest_prod_util.h" |
[email protected] | e8829a19 | 2009-12-06 00:09:37 | [diff] [blame] | 79 | #include "base/logging.h" |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 80 | #include "base/macros.h" |
[email protected] | 2f7d9cd | 2012-09-22 03:42:12 | [diff] [blame] | 81 | #include "base/memory/scoped_ptr.h" |
[email protected] | 4a32f12 | 2012-07-25 20:02:48 | [diff] [blame] | 82 | #include "base/metrics/bucket_ranges.h" |
[email protected] | c884117b | 2012-07-19 05:31:49 | [diff] [blame] | 83 | #include "base/metrics/histogram_base.h" |
asvitkine | d7bf9c45 | 2014-11-15 01:47:07 | [diff] [blame] | 84 | // TODO(asvitkine): Migrate callers to to include this directly and remove this. |
| 85 | #include "base/metrics/histogram_macros.h" |
[email protected] | 2f7d9cd | 2012-09-22 03:42:12 | [diff] [blame] | 86 | #include "base/metrics/histogram_samples.h" |
[email protected] | 99084f6 | 2013-06-28 00:49:07 | [diff] [blame] | 87 | #include "base/time/time.h" |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 88 | |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 89 | namespace base { |
[email protected] | 4dcbc1b | 2010-07-16 20:30:47 | [diff] [blame] | 90 | |
[email protected] | 2f7d9cd | 2012-09-22 03:42:12 | [diff] [blame] | 91 | class BooleanHistogram; |
[email protected] | 70cc56e4 | 2010-04-29 22:39:55 | [diff] [blame] | 92 | class CustomHistogram; |
[email protected] | e8829a19 | 2009-12-06 00:09:37 | [diff] [blame] | 93 | class Histogram; |
| 94 | class LinearHistogram; |
bcwhite | 5cb99eb | 2016-02-01 21:07:56 | [diff] [blame] | 95 | class PersistentMemoryAllocator; |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame] | 96 | class Pickle; |
| 97 | class PickleIterator; |
asvitkine | d7bf9c45 | 2014-11-15 01:47:07 | [diff] [blame] | 98 | class SampleVector; |
[email protected] | 3f38385 | 2009-04-03 18:18:55 | [diff] [blame] | 99 | |
[email protected] | c884117b | 2012-07-19 05:31:49 | [diff] [blame] | 100 | class BASE_EXPORT Histogram : public HistogramBase { |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 101 | public: |
[email protected] | 9fce5f0 | 2011-03-02 08:04:57 | [diff] [blame] | 102 | // Initialize maximum number of buckets in histograms as 16,384. |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 103 | static const uint32_t kBucketCount_MAX; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 104 | |
| 105 | typedef std::vector<Count> Counts; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 106 | |
bcwhite | 33d95806a | 2016-03-16 02:37:45 | [diff] [blame] | 107 | ~Histogram() override; |
| 108 | |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 109 | //---------------------------------------------------------------------------- |
[email protected] | a93721e2 | 2012-01-06 02:13:28 | [diff] [blame] | 110 | // For a valid histogram, input should follow these restrictions: |
| 111 | // minimum > 0 (if a minimum below 1 is specified, it will implicitly be |
| 112 | // normalized up to 1) |
| 113 | // maximum > minimum |
| 114 | // buckets > 2 [minimum buckets needed: underflow, overflow and the range] |
| 115 | // Additionally, |
| 116 | // buckets <= (maximum - minimum + 2) - this is to ensure that we don't have |
| 117 | // more buckets than the range of numbers; having more buckets than 1 per |
| 118 | // value in the range would be nonsensical. |
[email protected] | de41555 | 2013-01-23 04:12:17 | [diff] [blame] | 119 | static HistogramBase* FactoryGet(const std::string& name, |
| 120 | Sample minimum, |
| 121 | Sample maximum, |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 122 | uint32_t bucket_count, |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 123 | int32_t flags); |
[email protected] | de41555 | 2013-01-23 04:12:17 | [diff] [blame] | 124 | static HistogramBase* FactoryTimeGet(const std::string& name, |
| 125 | base::TimeDelta minimum, |
| 126 | base::TimeDelta maximum, |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 127 | uint32_t bucket_count, |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 128 | int32_t flags); |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 129 | |
asvitkine | 5c2d502 | 2015-06-19 00:37:50 | [diff] [blame] | 130 | // Overloads of the above two functions that take a const char* |name| param, |
| 131 | // to avoid code bloat from the std::string constructor being inlined into |
| 132 | // call sites. |
| 133 | static HistogramBase* FactoryGet(const char* name, |
| 134 | Sample minimum, |
| 135 | Sample maximum, |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 136 | uint32_t bucket_count, |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 137 | int32_t flags); |
asvitkine | 5c2d502 | 2015-06-19 00:37:50 | [diff] [blame] | 138 | static HistogramBase* FactoryTimeGet(const char* name, |
| 139 | base::TimeDelta minimum, |
| 140 | base::TimeDelta maximum, |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 141 | uint32_t bucket_count, |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 142 | int32_t flags); |
asvitkine | 5c2d502 | 2015-06-19 00:37:50 | [diff] [blame] | 143 | |
bcwhite | 33d95806a | 2016-03-16 02:37:45 | [diff] [blame] | 144 | // Create a histogram using data in persistent storage. |
| 145 | static scoped_ptr<HistogramBase> PersistentCreate( |
| 146 | const std::string& name, |
| 147 | Sample minimum, |
| 148 | Sample maximum, |
| 149 | const BucketRanges* ranges, |
| 150 | HistogramBase::AtomicCount* counts, |
| 151 | HistogramBase::AtomicCount* logged_counts, |
| 152 | uint32_t counts_size, |
| 153 | HistogramSamples::Metadata* meta, |
| 154 | HistogramSamples::Metadata* logged_meta); |
bcwhite | 5cb99eb | 2016-02-01 21:07:56 | [diff] [blame] | 155 | |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 156 | static void InitializeBucketRanges(Sample minimum, |
| 157 | Sample maximum, |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 158 | BucketRanges* ranges); |
| 159 | |
[email protected] | 2f7d9cd | 2012-09-22 03:42:12 | [diff] [blame] | 160 | // This constant if for FindCorruption. Since snapshots of histograms are |
| 161 | // taken asynchronously relative to sampling, and our counting code currently |
| 162 | // does not prevent race conditions, it is pretty likely that we'll catch a |
| 163 | // redundant count that doesn't match the sample count. We allow for a |
| 164 | // certain amount of slop before flagging this as an inconsistency. Even with |
| 165 | // an inconsistency, we'll snapshot it again (for UMA in about a half hour), |
| 166 | // so we'll eventually get the data, if it was not the result of a corruption. |
| 167 | static const int kCommonRaceBasedCountMismatch; |
| 168 | |
[email protected] | 93a41d7 | 2010-11-03 23:36:24 | [diff] [blame] | 169 | // Check to see if bucket ranges, counts and tallies in the snapshot are |
| 170 | // consistent with the bucket ranges and checksums in our histogram. This can |
| 171 | // produce a false-alarm if a race occurred in the reading of the data during |
| 172 | // a SnapShot process, but should otherwise be false at all times (unless we |
bcwhite | c85a1f82 | 2016-02-18 21:22:14 | [diff] [blame] | 173 | // have memory over-writes, or DRAM failures). Flag definitions are located |
| 174 | // under "enum Inconsistency" in base/metrics/histogram_base.h. |
| 175 | uint32_t FindCorruption(const HistogramSamples& samples) const override; |
[email protected] | 93a41d7 | 2010-11-03 23:36:24 | [diff] [blame] | 176 | |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 177 | //---------------------------------------------------------------------------- |
[email protected] | ed0f237 | 2013-11-20 08:37:34 | [diff] [blame] | 178 | // Accessors for factory construction, serialization and testing. |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 179 | //---------------------------------------------------------------------------- |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 180 | Sample declared_min() const { return declared_min_; } |
| 181 | Sample declared_max() const { return declared_max_; } |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 182 | virtual Sample ranges(uint32_t i) const; |
| 183 | virtual uint32_t bucket_count() const; |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 184 | const BucketRanges* bucket_ranges() const { return bucket_ranges_; } |
| 185 | |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 186 | // This function validates histogram construction arguments. It returns false |
| 187 | // if some of the arguments are totally bad. |
| 188 | // Note. Currently it allow some bad input, e.g. 0 as minimum, but silently |
| 189 | // converts it to good input: 1. |
| 190 | // TODO(kaiwang): Be more restrict and return false for any bad input, and |
| 191 | // make this a readonly validating function. |
| 192 | static bool InspectConstructionArguments(const std::string& name, |
| 193 | Sample* minimum, |
| 194 | Sample* maximum, |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 195 | uint32_t* bucket_count); |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 196 | |
[email protected] | abae9b02 | 2012-10-24 08:18:52 | [diff] [blame] | 197 | // HistogramBase implementation: |
bcwhite | b036e432 | 2015-12-10 18:36:34 | [diff] [blame] | 198 | uint64_t name_hash() const override; |
dcheng | 5648818 | 2014-10-21 10:54:51 | [diff] [blame] | 199 | HistogramType GetHistogramType() const override; |
| 200 | bool HasConstructionArguments(Sample expected_minimum, |
| 201 | Sample expected_maximum, |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 202 | uint32_t expected_bucket_count) const override; |
dcheng | 5648818 | 2014-10-21 10:54:51 | [diff] [blame] | 203 | void Add(Sample value) override; |
amohammadkhan | 6779b5c3 | 2015-08-05 20:31:11 | [diff] [blame] | 204 | void AddCount(Sample value, int count) override; |
dcheng | 5648818 | 2014-10-21 10:54:51 | [diff] [blame] | 205 | scoped_ptr<HistogramSamples> SnapshotSamples() const override; |
bcwhite | c85a1f82 | 2016-02-18 21:22:14 | [diff] [blame] | 206 | scoped_ptr<HistogramSamples> SnapshotDelta() override; |
dcheng | 5648818 | 2014-10-21 10:54:51 | [diff] [blame] | 207 | void AddSamples(const HistogramSamples& samples) override; |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame] | 208 | bool AddSamplesFromPickle(base::PickleIterator* iter) override; |
dcheng | 5648818 | 2014-10-21 10:54:51 | [diff] [blame] | 209 | void WriteHTMLGraph(std::string* output) const override; |
| 210 | void WriteAscii(std::string* output) const override; |
[email protected] | abae9b02 | 2012-10-24 08:18:52 | [diff] [blame] | 211 | |
| 212 | protected: |
bcwhite | 5cb99eb | 2016-02-01 21:07:56 | [diff] [blame] | 213 | // This class, defined entirely within the .cc file, contains all the |
| 214 | // common logic for building a Histogram and can be overridden by more |
| 215 | // specific types to alter details of how the creation is done. It is |
| 216 | // defined as an embedded class (rather than an anonymous one) so it |
| 217 | // can access the protected constructors. |
| 218 | class Factory; |
| 219 | |
[email protected] | 15ce384 | 2013-06-27 14:38:45 | [diff] [blame] | 220 | // |ranges| should contain the underflow and overflow buckets. See top |
| 221 | // comments for example. |
[email protected] | abae9b02 | 2012-10-24 08:18:52 | [diff] [blame] | 222 | Histogram(const std::string& name, |
| 223 | Sample minimum, |
| 224 | Sample maximum, |
[email protected] | abae9b02 | 2012-10-24 08:18:52 | [diff] [blame] | 225 | const BucketRanges* ranges); |
| 226 | |
bcwhite | 5cb99eb | 2016-02-01 21:07:56 | [diff] [blame] | 227 | // Traditionally, histograms allocate their own memory for the bucket |
| 228 | // vector but "shared" histograms use memory regions allocated from a |
| 229 | // special memory segment that is passed in here. It is assumed that |
| 230 | // the life of this memory is managed externally and exceeds the lifetime |
| 231 | // of this object. Practically, this memory is never released until the |
| 232 | // process exits and the OS cleans it up. |
| 233 | Histogram(const std::string& name, |
| 234 | Sample minimum, |
| 235 | Sample maximum, |
| 236 | const BucketRanges* ranges, |
| 237 | HistogramBase::AtomicCount* counts, |
bcwhite | c85a1f82 | 2016-02-18 21:22:14 | [diff] [blame] | 238 | HistogramBase::AtomicCount* logged_counts, |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 239 | uint32_t counts_size, |
bcwhite | c85a1f82 | 2016-02-18 21:22:14 | [diff] [blame] | 240 | HistogramSamples::Metadata* meta, |
| 241 | HistogramSamples::Metadata* logged_meta); |
bcwhite | 5cb99eb | 2016-02-01 21:07:56 | [diff] [blame] | 242 | |
[email protected] | c50c21d | 2013-01-11 21:52:44 | [diff] [blame] | 243 | // HistogramBase implementation: |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame] | 244 | bool SerializeInfoImpl(base::Pickle* pickle) const override; |
[email protected] | cd56dff | 2011-11-13 04:19:15 | [diff] [blame] | 245 | |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 246 | // Method to override to skip the display of the i'th bucket if it's empty. |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 247 | virtual bool PrintEmptyBucket(uint32_t index) const; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 248 | |
[email protected] | 908de52 | 2011-10-20 00:55:00 | [diff] [blame] | 249 | // Get normalized size, relative to the ranges(i). |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 250 | virtual double GetBucketSize(Count current, uint32_t i) const; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 251 | |
| 252 | // Return a string description of what goes in a given bucket. |
| 253 | // Most commonly this is the numeric value, but in derived classes it may |
| 254 | // be a name (or string description) given to the bucket. |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 255 | virtual const std::string GetAsciiBucketRange(uint32_t it) const; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 256 | |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 257 | private: |
[email protected] | 93a41d7 | 2010-11-03 23:36:24 | [diff] [blame] | 258 | // Allow tests to corrupt our innards for testing purposes. |
[email protected] | 877ef56 | 2012-10-20 02:56:18 | [diff] [blame] | 259 | FRIEND_TEST_ALL_PREFIXES(HistogramTest, BoundsTest); |
| 260 | FRIEND_TEST_ALL_PREFIXES(HistogramTest, BucketPlacementTest); |
[email protected] | 225020ce | 2011-11-29 14:45:53 | [diff] [blame] | 261 | FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts); |
[email protected] | 93a41d7 | 2010-11-03 23:36:24 | [diff] [blame] | 262 | |
[email protected] | 81ce9f3b | 2011-04-05 04:48:53 | [diff] [blame] | 263 | friend class StatisticsRecorder; // To allow it to delete duplicates. |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 264 | friend class StatisticsRecorderTest; |
[email protected] | 93a41d7 | 2010-11-03 23:36:24 | [diff] [blame] | 265 | |
xhwang | 3e9ca56 | 2015-11-06 18:50:36 | [diff] [blame] | 266 | friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame] | 267 | base::PickleIterator* iter); |
| 268 | static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); |
[email protected] | c50c21d | 2013-01-11 21:52:44 | [diff] [blame] | 269 | |
[email protected] | 877ef56 | 2012-10-20 02:56:18 | [diff] [blame] | 270 | // Implementation of SnapshotSamples function. |
| 271 | scoped_ptr<SampleVector> SnapshotSampleVector() const; |
| 272 | |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 273 | //---------------------------------------------------------------------------- |
| 274 | // Helpers for emitting Ascii graphic. Each method appends data to output. |
| 275 | |
[email protected] | 4a32f12 | 2012-07-25 20:02:48 | [diff] [blame] | 276 | void WriteAsciiImpl(bool graph_it, |
| 277 | const std::string& newline, |
| 278 | std::string* output) const; |
| 279 | |
[email protected] | 2f7d9cd | 2012-09-22 03:42:12 | [diff] [blame] | 280 | // Find out how large (graphically) the largest bucket will appear to be. |
| 281 | double GetPeakBucketSize(const SampleVector& samples) const; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 282 | |
| 283 | // Write a common header message describing this histogram. |
[email protected] | 2f7d9cd | 2012-09-22 03:42:12 | [diff] [blame] | 284 | void WriteAsciiHeader(const SampleVector& samples, |
| 285 | Count sample_count, |
| 286 | std::string* output) const; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 287 | |
| 288 | // Write information about previous, current, and next buckets. |
| 289 | // Information such as cumulative percentage, etc. |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 290 | void WriteAsciiBucketContext(const int64_t past, |
| 291 | const Count current, |
| 292 | const int64_t remaining, |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 293 | const uint32_t i, |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 294 | std::string* output) const; |
| 295 | |
[email protected] | 24a7ec5e | 2012-10-08 10:31:50 | [diff] [blame] | 296 | // WriteJSON calls these. |
dcheng | 5648818 | 2014-10-21 10:54:51 | [diff] [blame] | 297 | void GetParameters(DictionaryValue* params) const override; |
[email protected] | 24a7ec5e | 2012-10-08 10:31:50 | [diff] [blame] | 298 | |
dcheng | 5648818 | 2014-10-21 10:54:51 | [diff] [blame] | 299 | void GetCountAndBucketData(Count* count, |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 300 | int64_t* sum, |
dcheng | 5648818 | 2014-10-21 10:54:51 | [diff] [blame] | 301 | ListValue* buckets) const override; |
[email protected] | 24a7ec5e | 2012-10-08 10:31:50 | [diff] [blame] | 302 | |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 303 | // Does not own this object. Should get from StatisticsRecorder. |
| 304 | const BucketRanges* bucket_ranges_; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 305 | |
[email protected] | 15ce384 | 2013-06-27 14:38:45 | [diff] [blame] | 306 | Sample declared_min_; // Less than this goes into the first bucket. |
| 307 | Sample declared_max_; // Over this goes into the last bucket. |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 308 | |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 309 | // Finally, provide the state that changes with the addition of each new |
| 310 | // sample. |
[email protected] | 2f7d9cd | 2012-09-22 03:42:12 | [diff] [blame] | 311 | scoped_ptr<SampleVector> samples_; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 312 | |
bcwhite | c85a1f82 | 2016-02-18 21:22:14 | [diff] [blame] | 313 | // Also keep a previous uploaded state for calculating deltas. |
| 314 | scoped_ptr<HistogramSamples> logged_samples_; |
| 315 | |
[email protected] | 55e57d4 | 2009-02-25 06:10:17 | [diff] [blame] | 316 | DISALLOW_COPY_AND_ASSIGN(Histogram); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 317 | }; |
| 318 | |
| 319 | //------------------------------------------------------------------------------ |
| 320 | |
| 321 | // LinearHistogram is a more traditional histogram, with evenly spaced |
| 322 | // buckets. |
[email protected] | 0bea725 | 2011-08-05 15:34:00 | [diff] [blame] | 323 | class BASE_EXPORT LinearHistogram : public Histogram { |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 324 | public: |
dcheng | 5648818 | 2014-10-21 10:54:51 | [diff] [blame] | 325 | ~LinearHistogram() override; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 326 | |
[email protected] | e8829a19 | 2009-12-06 00:09:37 | [diff] [blame] | 327 | /* minimum should start from 1. 0 is as minimum is invalid. 0 is an implicit |
| 328 | default underflow bucket. */ |
[email protected] | de41555 | 2013-01-23 04:12:17 | [diff] [blame] | 329 | static HistogramBase* FactoryGet(const std::string& name, |
| 330 | Sample minimum, |
| 331 | Sample maximum, |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 332 | uint32_t bucket_count, |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 333 | int32_t flags); |
[email protected] | de41555 | 2013-01-23 04:12:17 | [diff] [blame] | 334 | static HistogramBase* FactoryTimeGet(const std::string& name, |
| 335 | TimeDelta minimum, |
| 336 | TimeDelta maximum, |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 337 | uint32_t bucket_count, |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 338 | int32_t flags); |
[email protected] | 55e57d4 | 2009-02-25 06:10:17 | [diff] [blame] | 339 | |
asvitkine | 5c2d502 | 2015-06-19 00:37:50 | [diff] [blame] | 340 | // Overloads of the above two functions that take a const char* |name| param, |
| 341 | // to avoid code bloat from the std::string constructor being inlined into |
| 342 | // call sites. |
| 343 | static HistogramBase* FactoryGet(const char* name, |
| 344 | Sample minimum, |
| 345 | Sample maximum, |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 346 | uint32_t bucket_count, |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 347 | int32_t flags); |
asvitkine | 5c2d502 | 2015-06-19 00:37:50 | [diff] [blame] | 348 | static HistogramBase* FactoryTimeGet(const char* name, |
| 349 | TimeDelta minimum, |
| 350 | TimeDelta maximum, |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 351 | uint32_t bucket_count, |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 352 | int32_t flags); |
asvitkine | 5c2d502 | 2015-06-19 00:37:50 | [diff] [blame] | 353 | |
bcwhite | 33d95806a | 2016-03-16 02:37:45 | [diff] [blame] | 354 | // Create a histogram using data in persistent storage. |
| 355 | static scoped_ptr<HistogramBase> PersistentCreate( |
| 356 | const std::string& name, |
| 357 | Sample minimum, |
| 358 | Sample maximum, |
| 359 | const BucketRanges* ranges, |
| 360 | HistogramBase::AtomicCount* counts, |
| 361 | HistogramBase::AtomicCount* logged_counts, |
| 362 | uint32_t counts_size, |
| 363 | HistogramSamples::Metadata* meta, |
| 364 | HistogramSamples::Metadata* logged_meta); |
bcwhite | 5cb99eb | 2016-02-01 21:07:56 | [diff] [blame] | 365 | |
[email protected] | c50c21d | 2013-01-11 21:52:44 | [diff] [blame] | 366 | struct DescriptionPair { |
| 367 | Sample sample; |
| 368 | const char* description; // Null means end of a list of pairs. |
| 369 | }; |
| 370 | |
[email protected] | 07c0240 | 2012-10-31 06:20:25 | [diff] [blame] | 371 | // Create a LinearHistogram and store a list of number/text values for use in |
| 372 | // writing the histogram graph. |
| 373 | // |descriptions| can be NULL, which means no special descriptions to set. If |
| 374 | // it's not NULL, the last element in the array must has a NULL in its |
| 375 | // "description" field. |
[email protected] | de41555 | 2013-01-23 04:12:17 | [diff] [blame] | 376 | static HistogramBase* FactoryGetWithRangeDescription( |
[email protected] | 07c0240 | 2012-10-31 06:20:25 | [diff] [blame] | 377 | const std::string& name, |
| 378 | Sample minimum, |
| 379 | Sample maximum, |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 380 | uint32_t bucket_count, |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 381 | int32_t flags, |
[email protected] | 07c0240 | 2012-10-31 06:20:25 | [diff] [blame] | 382 | const DescriptionPair descriptions[]); |
| 383 | |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 384 | static void InitializeBucketRanges(Sample minimum, |
| 385 | Sample maximum, |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 386 | BucketRanges* ranges); |
| 387 | |
[email protected] | a502bbe7 | 2011-01-07 18:06:45 | [diff] [blame] | 388 | // Overridden from Histogram: |
dcheng | 5648818 | 2014-10-21 10:54:51 | [diff] [blame] | 389 | HistogramType GetHistogramType() const override; |
[email protected] | d4799a3 | 2010-09-28 22:54:58 | [diff] [blame] | 390 | |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 391 | protected: |
bcwhite | 5cb99eb | 2016-02-01 21:07:56 | [diff] [blame] | 392 | class Factory; |
| 393 | |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 394 | LinearHistogram(const std::string& name, |
| 395 | Sample minimum, |
| 396 | Sample maximum, |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 397 | const BucketRanges* ranges); |
[email protected] | e8829a19 | 2009-12-06 00:09:37 | [diff] [blame] | 398 | |
bcwhite | 5cb99eb | 2016-02-01 21:07:56 | [diff] [blame] | 399 | LinearHistogram(const std::string& name, |
| 400 | Sample minimum, |
| 401 | Sample maximum, |
| 402 | const BucketRanges* ranges, |
| 403 | HistogramBase::AtomicCount* counts, |
bcwhite | c85a1f82 | 2016-02-18 21:22:14 | [diff] [blame] | 404 | HistogramBase::AtomicCount* logged_counts, |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 405 | uint32_t counts_size, |
bcwhite | c85a1f82 | 2016-02-18 21:22:14 | [diff] [blame] | 406 | HistogramSamples::Metadata* meta, |
| 407 | HistogramSamples::Metadata* logged_meta); |
bcwhite | 5cb99eb | 2016-02-01 21:07:56 | [diff] [blame] | 408 | |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 409 | double GetBucketSize(Count current, uint32_t i) const override; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 410 | |
| 411 | // If we have a description for a bucket, then return that. Otherwise |
| 412 | // let parent class provide a (numeric) description. |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 413 | const std::string GetAsciiBucketRange(uint32_t i) const override; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 414 | |
| 415 | // Skip printing of name for numeric range if we have a name (and if this is |
| 416 | // an empty bucket). |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 417 | bool PrintEmptyBucket(uint32_t index) const override; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 418 | |
| 419 | private: |
xhwang | 3e9ca56 | 2015-11-06 18:50:36 | [diff] [blame] | 420 | friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame] | 421 | base::PickleIterator* iter); |
| 422 | static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); |
[email protected] | c50c21d | 2013-01-11 21:52:44 | [diff] [blame] | 423 | |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 424 | // For some ranges, we store a printable description of a bucket range. |
[email protected] | ed0f237 | 2013-11-20 08:37:34 | [diff] [blame] | 425 | // If there is no description, then GetAsciiBucketRange() uses parent class |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 426 | // to provide a description. |
| 427 | typedef std::map<Sample, std::string> BucketDescriptionMap; |
| 428 | BucketDescriptionMap bucket_description_; |
| 429 | |
[email protected] | 55e57d4 | 2009-02-25 06:10:17 | [diff] [blame] | 430 | DISALLOW_COPY_AND_ASSIGN(LinearHistogram); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 431 | }; |
| 432 | |
[email protected] | 30629139 | 2009-01-17 19:15:36 | [diff] [blame] | 433 | //------------------------------------------------------------------------------ |
| 434 | |
| 435 | // BooleanHistogram is a histogram for booleans. |
[email protected] | 0bea725 | 2011-08-05 15:34:00 | [diff] [blame] | 436 | class BASE_EXPORT BooleanHistogram : public LinearHistogram { |
[email protected] | 30629139 | 2009-01-17 19:15:36 | [diff] [blame] | 437 | public: |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 438 | static HistogramBase* FactoryGet(const std::string& name, int32_t flags); |
[email protected] | 30629139 | 2009-01-17 19:15:36 | [diff] [blame] | 439 | |
asvitkine | 5c2d502 | 2015-06-19 00:37:50 | [diff] [blame] | 440 | // Overload of the above function that takes a const char* |name| param, |
| 441 | // to avoid code bloat from the std::string constructor being inlined into |
| 442 | // call sites. |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 443 | static HistogramBase* FactoryGet(const char* name, int32_t flags); |
asvitkine | 5c2d502 | 2015-06-19 00:37:50 | [diff] [blame] | 444 | |
bcwhite | 33d95806a | 2016-03-16 02:37:45 | [diff] [blame] | 445 | // Create a histogram using data in persistent storage. |
| 446 | static scoped_ptr<HistogramBase> PersistentCreate( |
| 447 | const std::string& name, |
| 448 | const BucketRanges* ranges, |
| 449 | HistogramBase::AtomicCount* counts, |
| 450 | HistogramBase::AtomicCount* logged_counts, |
| 451 | HistogramSamples::Metadata* meta, |
| 452 | HistogramSamples::Metadata* logged_meta); |
bcwhite | 5cb99eb | 2016-02-01 21:07:56 | [diff] [blame] | 453 | |
dcheng | 5648818 | 2014-10-21 10:54:51 | [diff] [blame] | 454 | HistogramType GetHistogramType() const override; |
[email protected] | e8829a19 | 2009-12-06 00:09:37 | [diff] [blame] | 455 | |
bcwhite | 5cb99eb | 2016-02-01 21:07:56 | [diff] [blame] | 456 | protected: |
| 457 | class Factory; |
| 458 | |
[email protected] | 30629139 | 2009-01-17 19:15:36 | [diff] [blame] | 459 | private: |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 460 | BooleanHistogram(const std::string& name, const BucketRanges* ranges); |
bcwhite | 5cb99eb | 2016-02-01 21:07:56 | [diff] [blame] | 461 | BooleanHistogram(const std::string& name, |
| 462 | const BucketRanges* ranges, |
| 463 | HistogramBase::AtomicCount* counts, |
bcwhite | c85a1f82 | 2016-02-18 21:22:14 | [diff] [blame] | 464 | HistogramBase::AtomicCount* logged_counts, |
| 465 | HistogramSamples::Metadata* meta, |
| 466 | HistogramSamples::Metadata* logged_meta); |
[email protected] | e8829a19 | 2009-12-06 00:09:37 | [diff] [blame] | 467 | |
xhwang | 3e9ca56 | 2015-11-06 18:50:36 | [diff] [blame] | 468 | friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame] | 469 | base::PickleIterator* iter); |
| 470 | static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); |
[email protected] | c50c21d | 2013-01-11 21:52:44 | [diff] [blame] | 471 | |
[email protected] | 55e57d4 | 2009-02-25 06:10:17 | [diff] [blame] | 472 | DISALLOW_COPY_AND_ASSIGN(BooleanHistogram); |
[email protected] | 30629139 | 2009-01-17 19:15:36 | [diff] [blame] | 473 | }; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 474 | |
| 475 | //------------------------------------------------------------------------------ |
[email protected] | 70cc56e4 | 2010-04-29 22:39:55 | [diff] [blame] | 476 | |
| 477 | // CustomHistogram is a histogram for a set of custom integers. |
[email protected] | 0bea725 | 2011-08-05 15:34:00 | [diff] [blame] | 478 | class BASE_EXPORT CustomHistogram : public Histogram { |
[email protected] | 70cc56e4 | 2010-04-29 22:39:55 | [diff] [blame] | 479 | public: |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 480 | // |custom_ranges| contains a vector of limits on ranges. Each limit should be |
| 481 | // > 0 and < kSampleType_MAX. (Currently 0 is still accepted for backward |
| 482 | // compatibility). The limits can be unordered or contain duplication, but |
| 483 | // client should not depend on this. |
[email protected] | de41555 | 2013-01-23 04:12:17 | [diff] [blame] | 484 | static HistogramBase* FactoryGet(const std::string& name, |
| 485 | const std::vector<Sample>& custom_ranges, |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 486 | int32_t flags); |
[email protected] | 70cc56e4 | 2010-04-29 22:39:55 | [diff] [blame] | 487 | |
asvitkine | 5c2d502 | 2015-06-19 00:37:50 | [diff] [blame] | 488 | // Overload of the above function that takes a const char* |name| param, |
| 489 | // to avoid code bloat from the std::string constructor being inlined into |
| 490 | // call sites. |
| 491 | static HistogramBase* FactoryGet(const char* name, |
| 492 | const std::vector<Sample>& custom_ranges, |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 493 | int32_t flags); |
asvitkine | 5c2d502 | 2015-06-19 00:37:50 | [diff] [blame] | 494 | |
bcwhite | 33d95806a | 2016-03-16 02:37:45 | [diff] [blame] | 495 | // Create a histogram using data in persistent storage. |
| 496 | static scoped_ptr<HistogramBase> PersistentCreate( |
| 497 | const std::string& name, |
| 498 | const BucketRanges* ranges, |
| 499 | HistogramBase::AtomicCount* counts, |
| 500 | HistogramBase::AtomicCount* logged_counts, |
| 501 | uint32_t counts_size, |
| 502 | HistogramSamples::Metadata* meta, |
| 503 | HistogramSamples::Metadata* logged_meta); |
bcwhite | 5cb99eb | 2016-02-01 21:07:56 | [diff] [blame] | 504 | |
[email protected] | a502bbe7 | 2011-01-07 18:06:45 | [diff] [blame] | 505 | // Overridden from Histogram: |
dcheng | 5648818 | 2014-10-21 10:54:51 | [diff] [blame] | 506 | HistogramType GetHistogramType() const override; |
[email protected] | a502bbe7 | 2011-01-07 18:06:45 | [diff] [blame] | 507 | |
[email protected] | 961fefb | 2011-05-24 13:59:58 | [diff] [blame] | 508 | // Helper method for transforming an array of valid enumeration values |
asvitkine | c0fb802 | 2014-08-26 04:39:35 | [diff] [blame] | 509 | // to the std::vector<int> expected by UMA_HISTOGRAM_CUSTOM_ENUMERATION. |
[email protected] | 961fefb | 2011-05-24 13:59:58 | [diff] [blame] | 510 | // This function ensures that a guard bucket exists right after any |
| 511 | // valid sample value (unless the next higher sample is also a valid value), |
| 512 | // so that invalid samples never fall into the same bucket as valid samples. |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 513 | // TODO(kaiwang): Change name to ArrayToCustomEnumRanges. |
[email protected] | 961fefb | 2011-05-24 13:59:58 | [diff] [blame] | 514 | static std::vector<Sample> ArrayToCustomRanges(const Sample* values, |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 515 | uint32_t num_values); |
[email protected] | 70cc56e4 | 2010-04-29 22:39:55 | [diff] [blame] | 516 | protected: |
bcwhite | 5cb99eb | 2016-02-01 21:07:56 | [diff] [blame] | 517 | class Factory; |
| 518 | |
[email protected] | 70cc56e4 | 2010-04-29 22:39:55 | [diff] [blame] | 519 | CustomHistogram(const std::string& name, |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 520 | const BucketRanges* ranges); |
[email protected] | 70cc56e4 | 2010-04-29 22:39:55 | [diff] [blame] | 521 | |
bcwhite | 5cb99eb | 2016-02-01 21:07:56 | [diff] [blame] | 522 | CustomHistogram(const std::string& name, |
| 523 | const BucketRanges* ranges, |
| 524 | HistogramBase::AtomicCount* counts, |
bcwhite | c85a1f82 | 2016-02-18 21:22:14 | [diff] [blame] | 525 | HistogramBase::AtomicCount* logged_counts, |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 526 | uint32_t counts_size, |
bcwhite | c85a1f82 | 2016-02-18 21:22:14 | [diff] [blame] | 527 | HistogramSamples::Metadata* meta, |
| 528 | HistogramSamples::Metadata* logged_meta); |
bcwhite | 5cb99eb | 2016-02-01 21:07:56 | [diff] [blame] | 529 | |
[email protected] | c50c21d | 2013-01-11 21:52:44 | [diff] [blame] | 530 | // HistogramBase implementation: |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame] | 531 | bool SerializeInfoImpl(base::Pickle* pickle) const override; |
[email protected] | cd56dff | 2011-11-13 04:19:15 | [diff] [blame] | 532 | |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 533 | double GetBucketSize(Count current, uint32_t i) const override; |
[email protected] | 70cc56e4 | 2010-04-29 22:39:55 | [diff] [blame] | 534 | |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 535 | private: |
xhwang | 3e9ca56 | 2015-11-06 18:50:36 | [diff] [blame] | 536 | friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame] | 537 | base::PickleIterator* iter); |
| 538 | static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); |
[email protected] | c50c21d | 2013-01-11 21:52:44 | [diff] [blame] | 539 | |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 540 | static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges); |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 541 | |
[email protected] | 70cc56e4 | 2010-04-29 22:39:55 | [diff] [blame] | 542 | DISALLOW_COPY_AND_ASSIGN(CustomHistogram); |
| 543 | }; |
| 544 | |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 545 | } // namespace base |
| 546 | |
| 547 | #endif // BASE_METRICS_HISTOGRAM_H_ |