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