xref: /aosp_15_r20/external/cronet/base/metrics/persistent_sample_map.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2016 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker // PersistentSampleMap implements HistogramSamples interface. It is used
6*6777b538SAndroid Build Coastguard Worker // by the SparseHistogram class to store samples in persistent memory which
7*6777b538SAndroid Build Coastguard Worker // allows it to be shared between processes or live across restarts.
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #ifndef BASE_METRICS_PERSISTENT_SAMPLE_MAP_H_
10*6777b538SAndroid Build Coastguard Worker #define BASE_METRICS_PERSISTENT_SAMPLE_MAP_H_
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker #include <map>
15*6777b538SAndroid Build Coastguard Worker #include <memory>
16*6777b538SAndroid Build Coastguard Worker #include <optional>
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/compiler_specific.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram_base.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram_samples.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/metrics/persistent_memory_allocator.h"
24*6777b538SAndroid Build Coastguard Worker 
25*6777b538SAndroid Build Coastguard Worker namespace base {
26*6777b538SAndroid Build Coastguard Worker 
27*6777b538SAndroid Build Coastguard Worker class PersistentHistogramAllocator;
28*6777b538SAndroid Build Coastguard Worker class PersistentSampleMapRecords;
29*6777b538SAndroid Build Coastguard Worker 
30*6777b538SAndroid Build Coastguard Worker // The logic here is similar to that of SampleMap but with different data
31*6777b538SAndroid Build Coastguard Worker // structures. Changes here likely need to be duplicated there.
32*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT PersistentSampleMap : public HistogramSamples {
33*6777b538SAndroid Build Coastguard Worker  public:
34*6777b538SAndroid Build Coastguard Worker   // Constructs a persistent sample map using a PersistentHistogramAllocator
35*6777b538SAndroid Build Coastguard Worker   // as the data source for persistent records.
36*6777b538SAndroid Build Coastguard Worker   PersistentSampleMap(uint64_t id,
37*6777b538SAndroid Build Coastguard Worker                       PersistentHistogramAllocator* allocator,
38*6777b538SAndroid Build Coastguard Worker                       Metadata* meta);
39*6777b538SAndroid Build Coastguard Worker 
40*6777b538SAndroid Build Coastguard Worker   PersistentSampleMap(const PersistentSampleMap&) = delete;
41*6777b538SAndroid Build Coastguard Worker   PersistentSampleMap& operator=(const PersistentSampleMap&) = delete;
42*6777b538SAndroid Build Coastguard Worker 
43*6777b538SAndroid Build Coastguard Worker   ~PersistentSampleMap() override;
44*6777b538SAndroid Build Coastguard Worker 
45*6777b538SAndroid Build Coastguard Worker   // HistogramSamples:
46*6777b538SAndroid Build Coastguard Worker   void Accumulate(HistogramBase::Sample value,
47*6777b538SAndroid Build Coastguard Worker                   HistogramBase::Count count) override;
48*6777b538SAndroid Build Coastguard Worker   HistogramBase::Count GetCount(HistogramBase::Sample value) const override;
49*6777b538SAndroid Build Coastguard Worker   HistogramBase::Count TotalCount() const override;
50*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<SampleCountIterator> Iterator() const override;
51*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<SampleCountIterator> ExtractingIterator() override;
52*6777b538SAndroid Build Coastguard Worker   bool IsDefinitelyEmpty() const override;
53*6777b538SAndroid Build Coastguard Worker 
54*6777b538SAndroid Build Coastguard Worker   // Uses a persistent-memory |iterator| to locate and return information about
55*6777b538SAndroid Build Coastguard Worker   // the next record holding information for a PersistentSampleMap (in
56*6777b538SAndroid Build Coastguard Worker   // particular, the reference and the sample |value| it holds). The record
57*6777b538SAndroid Build Coastguard Worker   // could be for any Map so return the |sample_map_id| as well.
58*6777b538SAndroid Build Coastguard Worker   static PersistentMemoryAllocator::Reference GetNextPersistentRecord(
59*6777b538SAndroid Build Coastguard Worker       PersistentMemoryAllocator::Iterator& iterator,
60*6777b538SAndroid Build Coastguard Worker       uint64_t* sample_map_id,
61*6777b538SAndroid Build Coastguard Worker       HistogramBase::Sample* value);
62*6777b538SAndroid Build Coastguard Worker 
63*6777b538SAndroid Build Coastguard Worker   // Creates a new record in an |allocator| storing count information for a
64*6777b538SAndroid Build Coastguard Worker   // specific sample |value| of a histogram with the given |sample_map_id|.
65*6777b538SAndroid Build Coastguard Worker   static PersistentMemoryAllocator::Reference CreatePersistentRecord(
66*6777b538SAndroid Build Coastguard Worker       PersistentMemoryAllocator* allocator,
67*6777b538SAndroid Build Coastguard Worker       uint64_t sample_map_id,
68*6777b538SAndroid Build Coastguard Worker       HistogramBase::Sample value);
69*6777b538SAndroid Build Coastguard Worker 
70*6777b538SAndroid Build Coastguard Worker  protected:
71*6777b538SAndroid Build Coastguard Worker   // Performs arithemetic. |op| is ADD or SUBTRACT.
72*6777b538SAndroid Build Coastguard Worker   bool AddSubtractImpl(SampleCountIterator* iter, Operator op) override;
73*6777b538SAndroid Build Coastguard Worker 
74*6777b538SAndroid Build Coastguard Worker   // Gets a pointer to a "count" corresponding to a given |value|. Returns NULL
75*6777b538SAndroid Build Coastguard Worker   // if sample does not exist.
76*6777b538SAndroid Build Coastguard Worker   HistogramBase::Count* GetSampleCountStorage(HistogramBase::Sample value);
77*6777b538SAndroid Build Coastguard Worker 
78*6777b538SAndroid Build Coastguard Worker   // Gets a pointer to a "count" corresponding to a given |value|, creating
79*6777b538SAndroid Build Coastguard Worker   // the sample (initialized to zero) if it does not already exists.
80*6777b538SAndroid Build Coastguard Worker   HistogramBase::Count* GetOrCreateSampleCountStorage(
81*6777b538SAndroid Build Coastguard Worker       HistogramBase::Sample value);
82*6777b538SAndroid Build Coastguard Worker 
83*6777b538SAndroid Build Coastguard Worker  private:
84*6777b538SAndroid Build Coastguard Worker   // Gets the object that manages persistent records. This returns the
85*6777b538SAndroid Build Coastguard Worker   // |records_| member after first initializing it if necessary.
86*6777b538SAndroid Build Coastguard Worker   PersistentSampleMapRecords* GetRecords();
87*6777b538SAndroid Build Coastguard Worker 
88*6777b538SAndroid Build Coastguard Worker   // Imports samples from persistent memory by iterating over all sample records
89*6777b538SAndroid Build Coastguard Worker   // found therein, adding them to the sample_counts_ map. If a count for the
90*6777b538SAndroid Build Coastguard Worker   // sample |until_value| is found, stop the import and return a pointer to that
91*6777b538SAndroid Build Coastguard Worker   // counter. If that value is not found, null will be returned after all
92*6777b538SAndroid Build Coastguard Worker   // currently available samples have been loaded. Pass a nullopt for
93*6777b538SAndroid Build Coastguard Worker   // |until_value| to force the importing of all available samples (null will
94*6777b538SAndroid Build Coastguard Worker   // always be returned in this case).
95*6777b538SAndroid Build Coastguard Worker   HistogramBase::Count* ImportSamples(
96*6777b538SAndroid Build Coastguard Worker       std::optional<HistogramBase::Sample> until_value);
97*6777b538SAndroid Build Coastguard Worker 
98*6777b538SAndroid Build Coastguard Worker   // All created/loaded sample values and their associated counts. The storage
99*6777b538SAndroid Build Coastguard Worker   // for the actual Count numbers is owned by the |records_| object and its
100*6777b538SAndroid Build Coastguard Worker   // underlying allocator.
101*6777b538SAndroid Build Coastguard Worker   std::map<HistogramBase::Sample, HistogramBase::Count*> sample_counts_;
102*6777b538SAndroid Build Coastguard Worker 
103*6777b538SAndroid Build Coastguard Worker   // The allocator that manages histograms inside persistent memory. This is
104*6777b538SAndroid Build Coastguard Worker   // owned externally and is expected to live beyond the life of this object.
105*6777b538SAndroid Build Coastguard Worker   raw_ptr<PersistentHistogramAllocator> allocator_;
106*6777b538SAndroid Build Coastguard Worker 
107*6777b538SAndroid Build Coastguard Worker   // The object that manages sample records inside persistent memory. The
108*6777b538SAndroid Build Coastguard Worker   // underlying data used is owned by the |allocator_| object (above). This
109*6777b538SAndroid Build Coastguard Worker   // value is lazily-initialized on first use via the GetRecords() accessor
110*6777b538SAndroid Build Coastguard Worker   // method.
111*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<PersistentSampleMapRecords> records_ = nullptr;
112*6777b538SAndroid Build Coastguard Worker };
113*6777b538SAndroid Build Coastguard Worker 
114*6777b538SAndroid Build Coastguard Worker }  // namespace base
115*6777b538SAndroid Build Coastguard Worker 
116*6777b538SAndroid Build Coastguard Worker #endif  // BASE_METRICS_PERSISTENT_SAMPLE_MAP_H_
117