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