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 
5 #ifndef BASE_METRICS_HISTOGRAM_SAMPLES_H_
6 #define BASE_METRICS_HISTOGRAM_SAMPLES_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include "base/atomicops.h"
12 #include "base/macros.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/metrics/histogram_base.h"
15 
16 namespace base {
17 
18 class Pickle;
19 class PickleIterator;
20 class SampleCountIterator;
21 
22 // HistogramSamples is a container storing all samples of a histogram.
23 class BASE_EXPORT HistogramSamples {
24  public:
25   struct Metadata {
26     // Initialized when the sample-set is first created with a value provided
27     // by the caller. It is generally used to identify the sample-set across
28     // threads and processes, though not necessarily uniquely as it is possible
29     // to have multiple sample-sets representing subsets of the data.
30     uint64_t id;
31 
32     // The sum of all the entries, effectivly the sum(sample * count) for
33     // all samples. Despite being atomic, no guarantees are made on the
34     // accuracy of this value; there may be races during histogram
35     // accumulation and snapshotting that we choose to accept. It should
36     // be treated as approximate.
37     // TODO(bcwhite): Change this to std::atomic<int64_t>.
38     int64_t sum;
39 
40     // A "redundant" count helps identify memory corruption. It redundantly
41     // stores the total number of samples accumulated in the histogram. We
42     // can compare this count to the sum of the counts (TotalCount() function),
43     // and detect problems. Note, depending on the implementation of different
44     // histogram types, there might be races during histogram accumulation
45     // and snapshotting that we choose to accept. In this case, the tallies
46     // might mismatch even when no memory corruption has happened.
47     HistogramBase::AtomicCount redundant_count;
48 
MetadataMetadata49     Metadata() : id(0), sum(0), redundant_count(0) {}
50   };
51 
52   explicit HistogramSamples(uint64_t id);
53   HistogramSamples(uint64_t id, Metadata* meta);
54   virtual ~HistogramSamples();
55 
56   virtual void Accumulate(HistogramBase::Sample value,
57                           HistogramBase::Count count) = 0;
58   virtual HistogramBase::Count GetCount(HistogramBase::Sample value) const = 0;
59   virtual HistogramBase::Count TotalCount() const = 0;
60 
61   virtual void Add(const HistogramSamples& other);
62 
63   // Add from serialized samples.
64   virtual bool AddFromPickle(PickleIterator* iter);
65 
66   virtual void Subtract(const HistogramSamples& other);
67 
68   virtual scoped_ptr<SampleCountIterator> Iterator() const = 0;
69   virtual bool Serialize(Pickle* pickle) const;
70 
71   // Accessor fuctions.
id()72   uint64_t id() const { return meta_->id; }
sum()73   int64_t sum() const { return meta_->sum; }
redundant_count()74   HistogramBase::Count redundant_count() const {
75     return subtle::NoBarrier_Load(&meta_->redundant_count);
76   }
77 
78  protected:
79   // Based on |op| type, add or subtract sample counts data from the iterator.
80   enum Operator { ADD, SUBTRACT };
81   virtual bool AddSubtractImpl(SampleCountIterator* iter, Operator op) = 0;
82 
83   void IncreaseSum(int64_t diff);
84   void IncreaseRedundantCount(HistogramBase::Count diff);
85 
86  private:
87   // In order to support histograms shared through an external memory segment,
88   // meta values may be the local storage or external storage depending on the
89   // wishes of the derived class.
90   Metadata local_meta_;
91   Metadata* meta_;
92 
93   DISALLOW_COPY_AND_ASSIGN(HistogramSamples);
94 };
95 
96 class BASE_EXPORT SampleCountIterator {
97  public:
98   virtual ~SampleCountIterator();
99 
100   virtual bool Done() const = 0;
101   virtual void Next() = 0;
102 
103   // Get the sample and count at current position.
104   // |min| |max| and |count| can be NULL if the value is not of interest.
105   // Requires: !Done();
106   virtual void Get(HistogramBase::Sample* min,
107                    HistogramBase::Sample* max,
108                    HistogramBase::Count* count) const = 0;
109 
110   // Get the index of current histogram bucket.
111   // For histograms that don't use predefined buckets, it returns false.
112   // Requires: !Done();
113   virtual bool GetBucketIndex(size_t* index) const;
114 };
115 
116 }  // namespace base
117 
118 #endif  // BASE_METRICS_HISTOGRAM_SAMPLES_H_
119