histogram.h 26 KB

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