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