1 // Copyright 2022 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 #ifndef BASE_METRICS_RANGES_MANAGER_H_ 6 #define BASE_METRICS_RANGES_MANAGER_H_ 7 8 #include <unordered_set> 9 #include <vector> 10 11 #include "base/base_export.h" 12 #include "base/memory/raw_ptr.h" 13 #include "base/metrics/bucket_ranges.h" 14 #include "base/synchronization/lock.h" 15 16 namespace base { 17 18 // Manages BucketRanges and their lifetime. When registering a BucketRanges 19 // to a RangesManager instance, if an equivalent one already exists (one with 20 // the exact same ranges), the passed BucketRanges is deleted. This is useful to 21 // prevent duplicate instances of equivalent BucketRanges. Upon the destruction 22 // of a RangesManager instance, all BucketRanges managed by it are destroyed. A 23 // BucketRanges instance should not be registered to multiple RangesManagers. 24 class BASE_EXPORT RangesManager { 25 public: 26 RangesManager(); 27 28 RangesManager(const RangesManager&) = delete; 29 RangesManager& operator=(const RangesManager&) = delete; 30 31 virtual ~RangesManager(); 32 33 // Gets the canonical BucketRanges object corresponding to `ranges`. If one 34 // does not exist, then `ranges` will be registered with this object, which 35 // will take ownership of it. Returns a pointer to the canonical ranges 36 // object. If it's different than `ranges`, the caller is responsible for 37 // deleting `ranges`. 38 virtual const BucketRanges* GetOrRegisterCanonicalRanges( 39 const BucketRanges* ranges); 40 41 // Gets all registered BucketRanges. The order of returned BucketRanges is not 42 // guaranteed. 43 virtual std::vector<const BucketRanges*> GetBucketRanges() const; 44 45 // Some tests may instantiate temporary StatisticsRecorders, each having their 46 // own RangesManager. During the tests, ranges may get registered with a 47 // recorder that later gets released, which would release the ranges as well. 48 // Calling this method prevents this, as the tests may not expect them to be 49 // deleted. 50 void DoNotReleaseRangesOnDestroyForTesting(); 51 52 protected: 53 // Used to get the hash of a BucketRanges, which is simply its checksum. 54 struct BucketRangesHash { 55 size_t operator()(const BucketRanges* a) const; 56 }; 57 58 // Comparator for BucketRanges. See `BucketRanges::Equals()`. 59 struct BucketRangesEqual { 60 bool operator()(const BucketRanges* a, const BucketRanges* b) const; 61 }; 62 63 // Type for a set of unique RangesBucket, with their hash and equivalence 64 // defined by `BucketRangesHash` and `BucketRangesEqual`. 65 typedef std::unordered_set<raw_ptr<const BucketRanges, CtnExperimental>, 66 BucketRangesHash, 67 BucketRangesEqual> 68 RangesMap; 69 70 // Removes all registered BucketRanges and destroys them. This is called in 71 // the destructor. 72 virtual void ReleaseBucketRanges(); 73 74 virtual RangesMap& GetRanges(); 75 virtual const RangesMap& GetRanges() const; 76 77 private: 78 // The set of unique BucketRanges registered to the RangesManager. 79 RangesMap ranges_; 80 81 // Whether or not to release the registered BucketRanges when this 82 // RangesManager is destroyed. See `DoNotReleaseRangesOnDestroyForTesting()`. 83 bool do_not_release_ranges_on_destroy_for_testing_ = false; 84 }; 85 86 class BASE_EXPORT ThreadSafeRangesManager final : public RangesManager { 87 public: 88 ThreadSafeRangesManager(); 89 90 ThreadSafeRangesManager(const RangesManager&) = delete; 91 ThreadSafeRangesManager& operator=(const ThreadSafeRangesManager&) = delete; 92 93 ~ThreadSafeRangesManager() override; 94 95 // RangesManager: 96 const BucketRanges* GetOrRegisterCanonicalRanges( 97 const BucketRanges* ranges) override; 98 std::vector<const BucketRanges*> GetBucketRanges() const override; 99 100 protected: 101 // RangesManager: 102 void ReleaseBucketRanges() override; 103 RangesMap& GetRanges() override; 104 const RangesMap& GetRanges() const override; 105 106 private: 107 // Used to protect access to |ranges_|. 108 mutable base::Lock lock_; 109 }; 110 111 } // namespace base 112 113 #endif // BASE_METRICS_RANGES_MANAGER_H_ 114