histogram.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  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/check_op.h"
  66. #include "base/compiler_specific.h"
  67. #include "base/containers/span.h"
  68. #include "base/gtest_prod_util.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. // Writes the type, min, max, and bucket count information of the histogram in
  274. // |params|.
  275. void GetParameters(DictionaryValue* params) const override;
  276. // Samples that have not yet been logged with SnapshotDelta().
  277. std::unique_ptr<SampleVectorBase> unlogged_samples_;
  278. // Accumulation of all samples that have been logged with SnapshotDelta().
  279. std::unique_ptr<SampleVectorBase> logged_samples_;
  280. #if DCHECK_IS_ON() // Don't waste memory if it won't be used.
  281. // Flag to indicate if PrepareFinalDelta has been previously called. It is
  282. // used to DCHECK that a final delta is not created multiple times.
  283. mutable bool final_delta_created_ = false;
  284. #endif
  285. DISALLOW_COPY_AND_ASSIGN(Histogram);
  286. };
  287. //------------------------------------------------------------------------------
  288. // LinearHistogram is a more traditional histogram, with evenly spaced
  289. // buckets.
  290. class BASE_EXPORT LinearHistogram : public Histogram {
  291. public:
  292. ~LinearHistogram() override;
  293. /* minimum should start from 1. 0 is as minimum is invalid. 0 is an implicit
  294. default underflow bucket. */
  295. static HistogramBase* FactoryGet(const std::string& name,
  296. Sample minimum,
  297. Sample maximum,
  298. uint32_t bucket_count,
  299. int32_t flags);
  300. static HistogramBase* FactoryTimeGet(const std::string& name,
  301. TimeDelta minimum,
  302. TimeDelta maximum,
  303. uint32_t bucket_count,
  304. int32_t flags);
  305. // Overloads of the above two functions that take a const char* |name| param,
  306. // to avoid code bloat from the std::string constructor being inlined into
  307. // call sites.
  308. static HistogramBase* FactoryGet(const char* name,
  309. Sample minimum,
  310. Sample maximum,
  311. uint32_t bucket_count,
  312. int32_t flags);
  313. static HistogramBase* FactoryTimeGet(const char* name,
  314. TimeDelta minimum,
  315. TimeDelta maximum,
  316. uint32_t bucket_count,
  317. int32_t flags);
  318. // Create a histogram using data in persistent storage.
  319. static std::unique_ptr<HistogramBase> PersistentCreate(
  320. const char* name,
  321. Sample minimum,
  322. Sample maximum,
  323. const BucketRanges* ranges,
  324. const DelayedPersistentAllocation& counts,
  325. const DelayedPersistentAllocation& logged_counts,
  326. HistogramSamples::Metadata* meta,
  327. HistogramSamples::Metadata* logged_meta);
  328. struct DescriptionPair {
  329. Sample sample;
  330. const char* description; // Null means end of a list of pairs.
  331. };
  332. // Create a LinearHistogram and store a list of number/text values for use in
  333. // writing the histogram graph.
  334. // |descriptions| can be NULL, which means no special descriptions to set. If
  335. // it's not NULL, the last element in the array must has a NULL in its
  336. // "description" field.
  337. static HistogramBase* FactoryGetWithRangeDescription(
  338. const std::string& name,
  339. Sample minimum,
  340. Sample maximum,
  341. uint32_t bucket_count,
  342. int32_t flags,
  343. const DescriptionPair descriptions[]);
  344. static void InitializeBucketRanges(Sample minimum,
  345. Sample maximum,
  346. BucketRanges* ranges);
  347. // Overridden from Histogram:
  348. HistogramType GetHistogramType() const override;
  349. protected:
  350. class Factory;
  351. LinearHistogram(const char* name,
  352. Sample minimum,
  353. Sample maximum,
  354. const BucketRanges* ranges);
  355. LinearHistogram(const char* name,
  356. Sample minimum,
  357. Sample maximum,
  358. const BucketRanges* ranges,
  359. const DelayedPersistentAllocation& counts,
  360. const DelayedPersistentAllocation& logged_counts,
  361. HistogramSamples::Metadata* meta,
  362. HistogramSamples::Metadata* logged_meta);
  363. double GetBucketSize(Count current, uint32_t i) const override;
  364. // If we have a description for a bucket, then return that. Otherwise
  365. // let parent class provide a (numeric) description.
  366. const std::string GetAsciiBucketRange(uint32_t i) const override;
  367. // Skip printing of name for numeric range if we have a name (and if this is
  368. // an empty bucket).
  369. bool PrintEmptyBucket(uint32_t index) const override;
  370. private:
  371. friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo(
  372. base::PickleIterator* iter);
  373. static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter);
  374. // For some ranges, we store a printable description of a bucket range.
  375. // If there is no description, then GetAsciiBucketRange() uses parent class
  376. // to provide a description.
  377. typedef std::map<Sample, std::string> BucketDescriptionMap;
  378. BucketDescriptionMap bucket_description_;
  379. DISALLOW_COPY_AND_ASSIGN(LinearHistogram);
  380. };
  381. //------------------------------------------------------------------------------
  382. // ScaledLinearHistogram is a wrapper around a linear histogram that scales the
  383. // counts down by some factor. Remainder values are kept locally but lost when
  384. // uploaded or serialized. The integral counts are rounded up/down so should
  385. // average to the correct value when many reports are added.
  386. //
  387. // This is most useful when adding many counts at once via AddCount() that can
  388. // cause overflows of the 31-bit counters, usually with an enum as the value.
  389. class BASE_EXPORT ScaledLinearHistogram {
  390. using AtomicCount = Histogram::AtomicCount;
  391. using Sample = Histogram::Sample;
  392. public:
  393. // Currently only works with "exact" linear histograms: minimum=1, maximum=N,
  394. // and bucket_count=N+1.
  395. ScaledLinearHistogram(const char* name,
  396. Sample minimum,
  397. Sample maximum,
  398. uint32_t bucket_count,
  399. int32_t scale,
  400. int32_t flags);
  401. ScaledLinearHistogram(const std::string& name,
  402. Sample minimum,
  403. Sample maximum,
  404. uint32_t bucket_count,
  405. int32_t scale,
  406. int32_t flags);
  407. ~ScaledLinearHistogram();
  408. // Like AddCount() but actually accumulates |count|/|scale| and increments
  409. // the accumulated remainder by |count|%|scale|. An additional increment
  410. // is done when the remainder has grown sufficiently large.
  411. void AddScaledCount(Sample value, int count);
  412. int32_t scale() const { return scale_; }
  413. HistogramBase* histogram() { return histogram_; }
  414. private:
  415. // Pointer to the underlying histogram. Ownership of it remains with
  416. // the statistics-recorder. This is typed as HistogramBase because it may be a
  417. // DummyHistogram if expired.
  418. HistogramBase* const histogram_;
  419. // The scale factor of the sample counts.
  420. const int32_t scale_;
  421. // A vector of "remainder" counts indexed by bucket number. These values
  422. // may be negative as the scaled count is actually bumped once the
  423. // remainder is 1/2 way to the scale value (thus "rounding").
  424. std::vector<AtomicCount> remainders_;
  425. DISALLOW_COPY_AND_ASSIGN(ScaledLinearHistogram);
  426. };
  427. //------------------------------------------------------------------------------
  428. // BooleanHistogram is a histogram for booleans.
  429. class BASE_EXPORT BooleanHistogram : public LinearHistogram {
  430. public:
  431. static HistogramBase* FactoryGet(const std::string& name, int32_t flags);
  432. // Overload of the above function that takes a const char* |name| param,
  433. // to avoid code bloat from the std::string constructor being inlined into
  434. // call sites.
  435. static HistogramBase* FactoryGet(const char* name, int32_t flags);
  436. // Create a histogram using data in persistent storage.
  437. static std::unique_ptr<HistogramBase> PersistentCreate(
  438. const char* name,
  439. const BucketRanges* ranges,
  440. const DelayedPersistentAllocation& counts,
  441. const DelayedPersistentAllocation& logged_counts,
  442. HistogramSamples::Metadata* meta,
  443. HistogramSamples::Metadata* logged_meta);
  444. HistogramType GetHistogramType() const override;
  445. protected:
  446. class Factory;
  447. private:
  448. BooleanHistogram(const char* name, const BucketRanges* ranges);
  449. BooleanHistogram(const char* name,
  450. const BucketRanges* ranges,
  451. const DelayedPersistentAllocation& counts,
  452. const DelayedPersistentAllocation& logged_counts,
  453. HistogramSamples::Metadata* meta,
  454. HistogramSamples::Metadata* logged_meta);
  455. friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo(
  456. base::PickleIterator* iter);
  457. static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter);
  458. DISALLOW_COPY_AND_ASSIGN(BooleanHistogram);
  459. };
  460. //------------------------------------------------------------------------------
  461. // CustomHistogram is a histogram for a set of custom integers.
  462. class BASE_EXPORT CustomHistogram : public Histogram {
  463. public:
  464. // |custom_ranges| contains a vector of limits on ranges. Each limit should be
  465. // > 0 and < kSampleType_MAX. (Currently 0 is still accepted for backward
  466. // compatibility). The limits can be unordered or contain duplication, but
  467. // client should not depend on this.
  468. static HistogramBase* FactoryGet(const std::string& name,
  469. const std::vector<Sample>& custom_ranges,
  470. int32_t flags);
  471. // Overload of the above function that takes a const char* |name| param,
  472. // to avoid code bloat from the std::string constructor being inlined into
  473. // call sites.
  474. static HistogramBase* FactoryGet(const char* name,
  475. const std::vector<Sample>& custom_ranges,
  476. int32_t flags);
  477. // Create a histogram using data in persistent storage.
  478. static std::unique_ptr<HistogramBase> PersistentCreate(
  479. const char* name,
  480. const BucketRanges* ranges,
  481. const DelayedPersistentAllocation& counts,
  482. const DelayedPersistentAllocation& logged_counts,
  483. HistogramSamples::Metadata* meta,
  484. HistogramSamples::Metadata* logged_meta);
  485. // Overridden from Histogram:
  486. HistogramType GetHistogramType() const override;
  487. // Helper method for transforming an array of valid enumeration values
  488. // to the std::vector<int> expected by UMA_HISTOGRAM_CUSTOM_ENUMERATION.
  489. // This function ensures that a guard bucket exists right after any
  490. // valid sample value (unless the next higher sample is also a valid value),
  491. // so that invalid samples never fall into the same bucket as valid samples.
  492. static std::vector<Sample> ArrayToCustomEnumRanges(
  493. base::span<const Sample> values);
  494. protected:
  495. class Factory;
  496. CustomHistogram(const char* name, const BucketRanges* ranges);
  497. CustomHistogram(const char* name,
  498. const BucketRanges* ranges,
  499. const DelayedPersistentAllocation& counts,
  500. const DelayedPersistentAllocation& logged_counts,
  501. HistogramSamples::Metadata* meta,
  502. HistogramSamples::Metadata* logged_meta);
  503. // HistogramBase implementation:
  504. void SerializeInfoImpl(base::Pickle* pickle) const override;
  505. double GetBucketSize(Count current, uint32_t i) const override;
  506. private:
  507. friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo(
  508. base::PickleIterator* iter);
  509. static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter);
  510. static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges);
  511. DISALLOW_COPY_AND_ASSIGN(CustomHistogram);
  512. };
  513. } // namespace base
  514. #endif // BASE_METRICS_HISTOGRAM_H_