xref: /aosp_15_r20/external/cronet/base/metrics/ranges_manager.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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