blob: 04010b91aa6576081601e8f23e55960b81ce4131 [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2016 The Chromium Authors
bcwhite3dd85c4f2016-03-17 13:21:562// 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
Peter Kasting852967472025-01-06 16:42:2014#include <atomic>
bcwhite3dd85c4f2016-03-17 13:21:5615#include <map>
dcheng093de9b2016-04-04 21:25:5116#include <memory>
Arthur Sonzognie5fff99c2024-02-21 15:58:2417#include <optional>
bcwhite3dd85c4f2016-03-17 13:21:5618
David Sanders6e709942022-04-05 06:49:2619#include "base/base_export.h"
Keishi Hattori0e45c022021-11-27 09:25:5220#include "base/memory/raw_ptr.h"
bcwhite3dd85c4f2016-03-17 13:21:5621#include "base/metrics/histogram_base.h"
22#include "base/metrics/histogram_samples.h"
Victor Hugo Vianna Silva858706f2025-01-07 15:01:0723#include "base/metrics/persistent_histogram_allocator.h"
bcwhite3dd85c4f2016-03-17 13:21:5624#include "base/metrics/persistent_memory_allocator.h"
25
26namespace base {
27
28// The logic here is similar to that of SampleMap but with different data
29// structures. Changes here likely need to be duplicated there.
30class BASE_EXPORT PersistentSampleMap : public HistogramSamples {
31 public:
Peter Kastingc4639bb2025-01-07 18:34:1332 using SampleToCountMap =
Ramon Cano Aparicio79e06642025-01-09 19:10:2233 std::map<HistogramBase::Sample32,
Ramon Cano Apariciob2cba0f2025-01-22 21:26:1034 raw_ptr<std::atomic<HistogramBase::Count32>, CtnExperimental>>;
Peter Kastingc4639bb2025-01-07 18:34:1335
bcwhite1d02f432016-04-28 18:59:5336 // Constructs a persistent sample map using a PersistentHistogramAllocator
37 // as the data source for persistent records.
bcwhite3dd85c4f2016-03-17 13:21:5638 PersistentSampleMap(uint64_t id,
bcwhiteb0bb9192016-04-18 01:33:1039 PersistentHistogramAllocator* allocator,
bcwhite3dd85c4f2016-03-17 13:21:5640 Metadata* meta);
bcwhiteb0bb9192016-04-18 01:33:1041
Peter Boström7319bbd2021-09-15 22:59:3842 PersistentSampleMap(const PersistentSampleMap&) = delete;
43 PersistentSampleMap& operator=(const PersistentSampleMap&) = delete;
44
bcwhite3dd85c4f2016-03-17 13:21:5645 ~PersistentSampleMap() override;
46
47 // HistogramSamples:
Ramon Cano Aparicio79e06642025-01-09 19:10:2248 void Accumulate(HistogramBase::Sample32 value,
Ramon Cano Apariciob2cba0f2025-01-22 21:26:1049 HistogramBase::Count32 count) override;
50 HistogramBase::Count32 GetCount(HistogramBase::Sample32 value) const override;
51 HistogramBase::Count32 TotalCount() const override;
dcheng093de9b2016-04-04 21:25:5152 std::unique_ptr<SampleCountIterator> Iterator() const override;
Luc Nguyen6458a5c2023-03-31 20:59:1753 std::unique_ptr<SampleCountIterator> ExtractingIterator() override;
Luc Nguyenbbaab292023-09-28 23:30:5754 bool IsDefinitelyEmpty() const override;
bcwhite3dd85c4f2016-03-17 13:21:5655
bcwhiteb0bb9192016-04-18 01:33:1056 // Uses a persistent-memory |iterator| to locate and return information about
Luc Nguyenf56cc822023-09-11 21:19:3557 // the next record holding information for a PersistentSampleMap (in
58 // particular, the reference and the sample |value| it holds). The record
bcwhiteb0bb9192016-04-18 01:33:1059 // could be for any Map so return the |sample_map_id| as well.
60 static PersistentMemoryAllocator::Reference GetNextPersistentRecord(
61 PersistentMemoryAllocator::Iterator& iterator,
Luc Nguyenf56cc822023-09-11 21:19:3562 uint64_t* sample_map_id,
Ramon Cano Aparicio79e06642025-01-09 19:10:2263 HistogramBase::Sample32* value);
bcwhiteb0bb9192016-04-18 01:33:1064
65 // Creates a new record in an |allocator| storing count information for a
66 // specific sample |value| of a histogram with the given |sample_map_id|.
67 static PersistentMemoryAllocator::Reference CreatePersistentRecord(
68 PersistentMemoryAllocator* allocator,
69 uint64_t sample_map_id,
Ramon Cano Aparicio79e06642025-01-09 19:10:2270 HistogramBase::Sample32 value);
bcwhiteb0bb9192016-04-18 01:33:1071
bcwhite3dd85c4f2016-03-17 13:21:5672 protected:
Ramon Cano Apariciob2cba0f2025-01-22 21:26:1073 // Performs arithmetic. |op| is ADD or SUBTRACT.
bcwhite3dd85c4f2016-03-17 13:21:5674 bool AddSubtractImpl(SampleCountIterator* iter, Operator op) override;
75
76 // Gets a pointer to a "count" corresponding to a given |value|. Returns NULL
77 // if sample does not exist.
Ramon Cano Apariciob2cba0f2025-01-22 21:26:1078 std::atomic<HistogramBase::Count32>* GetSampleCountStorage(
Ramon Cano Aparicio4a39d122025-01-20 13:00:1779 HistogramBase::Sample32 value) const;
bcwhite3dd85c4f2016-03-17 13:21:5680
81 // Gets a pointer to a "count" corresponding to a given |value|, creating
Peter Kastingc4639bb2025-01-07 18:34:1382 // the sample (initialized to zero) if it does not already exist.
Ramon Cano Apariciob2cba0f2025-01-22 21:26:1083 std::atomic<HistogramBase::Count32>* GetOrCreateSampleCountStorage(
Ramon Cano Aparicio4a39d122025-01-20 13:00:1784 HistogramBase::Sample32 value);
bcwhite3dd85c4f2016-03-17 13:21:5685
86 private:
bcwhite1d02f432016-04-28 18:59:5387 // Gets the object that manages persistent records. This returns the
88 // |records_| member after first initializing it if necessary.
Peter Kastingc4639bb2025-01-07 18:34:1389 PersistentSampleMapRecords* GetRecords() const;
bcwhite1d02f432016-04-28 18:59:5390
Luc Nguyen146f34f2023-08-31 18:07:1391 // Imports samples from persistent memory by iterating over all sample records
92 // found therein, adding them to the sample_counts_ map. If a count for the
93 // sample |until_value| is found, stop the import and return a pointer to that
94 // counter. If that value is not found, null will be returned after all
95 // currently available samples have been loaded. Pass a nullopt for
96 // |until_value| to force the importing of all available samples (null will
97 // always be returned in this case).
Ramon Cano Apariciob2cba0f2025-01-22 21:26:1098 std::atomic<HistogramBase::Count32>* ImportSamples(
Ramon Cano Aparicio79e06642025-01-09 19:10:2299 std::optional<HistogramBase::Sample32> until_value = std::nullopt) const;
bcwhite3dd85c4f2016-03-17 13:21:56100
101 // All created/loaded sample values and their associated counts. The storage
bcwhiteb0bb9192016-04-18 01:33:10102 // for the actual Count numbers is owned by the |records_| object and its
103 // underlying allocator.
Peter Kastingc4639bb2025-01-07 18:34:13104 mutable SampleToCountMap sample_counts_;
bcwhite3dd85c4f2016-03-17 13:21:56105
bcwhite1d02f432016-04-28 18:59:53106 // The allocator that manages histograms inside persistent memory. This is
107 // owned externally and is expected to live beyond the life of this object.
Peter Kastingc4639bb2025-01-07 18:34:13108 mutable raw_ptr<PersistentHistogramAllocator> allocator_;
bcwhite1d02f432016-04-28 18:59:53109
Luc Nguyenf56cc822023-09-11 21:19:35110 // The object that manages sample records inside persistent memory. The
111 // underlying data used is owned by the |allocator_| object (above). This
112 // value is lazily-initialized on first use via the GetRecords() accessor
113 // method.
Peter Kastingc4639bb2025-01-07 18:34:13114 mutable std::unique_ptr<PersistentSampleMapRecords> records_ = nullptr;
bcwhite3dd85c4f2016-03-17 13:21:56115};
116
117} // namespace base
118
119#endif // BASE_METRICS_PERSISTENT_SAMPLE_MAP_H_