xref: /aosp_15_r20/external/cronet/base/containers/lru_cache.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2011 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 // This file contains a template for a Least Recently Used cache that allows
6*6777b538SAndroid Build Coastguard Worker // constant-time access to items, but easy identification of the
7*6777b538SAndroid Build Coastguard Worker // least-recently-used items for removal. Variations exist to support use as a
8*6777b538SAndroid Build Coastguard Worker // Map (`base::LRUCache`), HashMap (`base::HashingLRUCache`), Set
9*6777b538SAndroid Build Coastguard Worker // (`base::LRUCacheSet`), or HashSet (`base::HashingLRUCacheSet`). These are
10*6777b538SAndroid Build Coastguard Worker // implemented as aliases of `base::internal::LRUCacheBase`, defined at the
11*6777b538SAndroid Build Coastguard Worker // bottom of this file.
12*6777b538SAndroid Build Coastguard Worker //
13*6777b538SAndroid Build Coastguard Worker // The key object (which is identical to the value, in the Set variations) will
14*6777b538SAndroid Build Coastguard Worker // be stored twice, so it should support efficient copying.
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker #ifndef BASE_CONTAINERS_LRU_CACHE_H_
17*6777b538SAndroid Build Coastguard Worker #define BASE_CONTAINERS_LRU_CACHE_H_
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
20*6777b538SAndroid Build Coastguard Worker 
21*6777b538SAndroid Build Coastguard Worker #include <algorithm>
22*6777b538SAndroid Build Coastguard Worker #include <functional>
23*6777b538SAndroid Build Coastguard Worker #include <list>
24*6777b538SAndroid Build Coastguard Worker #include <map>
25*6777b538SAndroid Build Coastguard Worker #include <type_traits>
26*6777b538SAndroid Build Coastguard Worker #include <unordered_map>
27*6777b538SAndroid Build Coastguard Worker #include <utility>
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker #include "base/check.h"
30*6777b538SAndroid Build Coastguard Worker 
31*6777b538SAndroid Build Coastguard Worker namespace base {
32*6777b538SAndroid Build Coastguard Worker namespace trace_event::internal {
33*6777b538SAndroid Build Coastguard Worker 
34*6777b538SAndroid Build Coastguard Worker template <class LruCacheType>
35*6777b538SAndroid Build Coastguard Worker size_t DoEstimateMemoryUsageForLruCache(const LruCacheType&);
36*6777b538SAndroid Build Coastguard Worker 
37*6777b538SAndroid Build Coastguard Worker }  // namespace trace_event::internal
38*6777b538SAndroid Build Coastguard Worker 
39*6777b538SAndroid Build Coastguard Worker namespace internal {
40*6777b538SAndroid Build Coastguard Worker 
41*6777b538SAndroid Build Coastguard Worker struct GetKeyFromKVPair {
42*6777b538SAndroid Build Coastguard Worker   template <typename T1, typename T2>
operatorGetKeyFromKVPair43*6777b538SAndroid Build Coastguard Worker   constexpr const T1& operator()(const std::pair<T1, T2>& pair) {
44*6777b538SAndroid Build Coastguard Worker     return pair.first;
45*6777b538SAndroid Build Coastguard Worker   }
46*6777b538SAndroid Build Coastguard Worker };
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker // Base class for the LRU cache specializations defined below.
49*6777b538SAndroid Build Coastguard Worker template <class ValueType, class GetKeyFromValue, class KeyIndexTemplate>
50*6777b538SAndroid Build Coastguard Worker class LRUCacheBase {
51*6777b538SAndroid Build Coastguard Worker  public:
52*6777b538SAndroid Build Coastguard Worker   // The contents of the list. This must contain a copy of the key (that may be
53*6777b538SAndroid Build Coastguard Worker   // extracted via `GetKeyFromValue()(value)` so we can efficiently delete
54*6777b538SAndroid Build Coastguard Worker   // things given an element of the list.
55*6777b538SAndroid Build Coastguard Worker   using value_type = ValueType;
56*6777b538SAndroid Build Coastguard Worker 
57*6777b538SAndroid Build Coastguard Worker  private:
58*6777b538SAndroid Build Coastguard Worker   using ValueList = std::list<value_type>;
59*6777b538SAndroid Build Coastguard Worker   using KeyIndex =
60*6777b538SAndroid Build Coastguard Worker       typename KeyIndexTemplate::template Type<typename ValueList::iterator>;
61*6777b538SAndroid Build Coastguard Worker 
62*6777b538SAndroid Build Coastguard Worker  public:
63*6777b538SAndroid Build Coastguard Worker   using size_type = typename ValueList::size_type;
64*6777b538SAndroid Build Coastguard Worker   using key_type = typename KeyIndex::key_type;
65*6777b538SAndroid Build Coastguard Worker 
66*6777b538SAndroid Build Coastguard Worker   using iterator = typename ValueList::iterator;
67*6777b538SAndroid Build Coastguard Worker   using const_iterator = typename ValueList::const_iterator;
68*6777b538SAndroid Build Coastguard Worker   using reverse_iterator = typename ValueList::reverse_iterator;
69*6777b538SAndroid Build Coastguard Worker   using const_reverse_iterator = typename ValueList::const_reverse_iterator;
70*6777b538SAndroid Build Coastguard Worker 
71*6777b538SAndroid Build Coastguard Worker   enum { NO_AUTO_EVICT = 0 };
72*6777b538SAndroid Build Coastguard Worker 
73*6777b538SAndroid Build Coastguard Worker   // The max_size is the size at which the cache will prune its members to when
74*6777b538SAndroid Build Coastguard Worker   // a new item is inserted. If the caller wants to manage this itself (for
75*6777b538SAndroid Build Coastguard Worker   // example, maybe it has special work to do when something is evicted), it
76*6777b538SAndroid Build Coastguard Worker   // can pass NO_AUTO_EVICT to not restrict the cache size.
LRUCacheBase(size_type max_size)77*6777b538SAndroid Build Coastguard Worker   explicit LRUCacheBase(size_type max_size) : max_size_(max_size) {}
78*6777b538SAndroid Build Coastguard Worker 
79*6777b538SAndroid Build Coastguard Worker   // In theory, LRUCacheBase could be copyable, but since copying `ValueList`
80*6777b538SAndroid Build Coastguard Worker   // might be costly, it's currently move-only to ensure users don't
81*6777b538SAndroid Build Coastguard Worker   // accidentally incur performance penalties. If you need this to become
82*6777b538SAndroid Build Coastguard Worker   // copyable, talk to base/ OWNERS.
83*6777b538SAndroid Build Coastguard Worker   LRUCacheBase(LRUCacheBase&&) noexcept = default;
84*6777b538SAndroid Build Coastguard Worker   LRUCacheBase& operator=(LRUCacheBase&&) noexcept = default;
85*6777b538SAndroid Build Coastguard Worker 
86*6777b538SAndroid Build Coastguard Worker   ~LRUCacheBase() = default;
87*6777b538SAndroid Build Coastguard Worker 
max_size()88*6777b538SAndroid Build Coastguard Worker   size_type max_size() const { return max_size_; }
89*6777b538SAndroid Build Coastguard Worker 
90*6777b538SAndroid Build Coastguard Worker   // Inserts an item into the list. If an existing item has the same key, it is
91*6777b538SAndroid Build Coastguard Worker   // removed prior to insertion. An iterator indicating the inserted item will
92*6777b538SAndroid Build Coastguard Worker   // be returned (this will always be the front of the list).
93*6777b538SAndroid Build Coastguard Worker   // In the map variations of this container, `value_type` is a `std::pair` and
94*6777b538SAndroid Build Coastguard Worker   // it's preferred to use the `Put(k, v)` overload of this method.
Put(value_type && value)95*6777b538SAndroid Build Coastguard Worker   iterator Put(value_type&& value) {
96*6777b538SAndroid Build Coastguard Worker     // Remove any existing item with that key.
97*6777b538SAndroid Build Coastguard Worker     key_type key = GetKeyFromValue{}(value);
98*6777b538SAndroid Build Coastguard Worker     typename KeyIndex::iterator index_iter = index_.find(key);
99*6777b538SAndroid Build Coastguard Worker     if (index_iter != index_.end()) {
100*6777b538SAndroid Build Coastguard Worker       // Erase the reference to it. The index reference will be replaced in the
101*6777b538SAndroid Build Coastguard Worker       // code below.
102*6777b538SAndroid Build Coastguard Worker       Erase(index_iter->second);
103*6777b538SAndroid Build Coastguard Worker     } else if (max_size_ != NO_AUTO_EVICT) {
104*6777b538SAndroid Build Coastguard Worker       // New item is being inserted which might make it larger than the maximum
105*6777b538SAndroid Build Coastguard Worker       // size: kick the oldest thing out if necessary.
106*6777b538SAndroid Build Coastguard Worker       ShrinkToSize(max_size_ - 1);
107*6777b538SAndroid Build Coastguard Worker     }
108*6777b538SAndroid Build Coastguard Worker 
109*6777b538SAndroid Build Coastguard Worker     ordering_.push_front(std::move(value));
110*6777b538SAndroid Build Coastguard Worker     index_.emplace(std::move(key), ordering_.begin());
111*6777b538SAndroid Build Coastguard Worker     return ordering_.begin();
112*6777b538SAndroid Build Coastguard Worker   }
113*6777b538SAndroid Build Coastguard Worker 
114*6777b538SAndroid Build Coastguard Worker   // Inserts an item into the list. If an existing item has the same key, it is
115*6777b538SAndroid Build Coastguard Worker   // removed prior to insertion. An iterator indicating the inserted item will
116*6777b538SAndroid Build Coastguard Worker   // be returned (this will always be the front of the list).
117*6777b538SAndroid Build Coastguard Worker   template <
118*6777b538SAndroid Build Coastguard Worker       class K,
119*6777b538SAndroid Build Coastguard Worker       class V,
120*6777b538SAndroid Build Coastguard Worker       class MapKeyGetter = GetKeyFromKVPair,
121*6777b538SAndroid Build Coastguard Worker       class = std::enable_if_t<std::is_same_v<MapKeyGetter, GetKeyFromValue>>>
Put(K && key,V && value)122*6777b538SAndroid Build Coastguard Worker   iterator Put(K&& key, V&& value) {
123*6777b538SAndroid Build Coastguard Worker     return Put(value_type{std::forward<K>(key), std::forward<V>(value)});
124*6777b538SAndroid Build Coastguard Worker   }
125*6777b538SAndroid Build Coastguard Worker 
126*6777b538SAndroid Build Coastguard Worker   // Retrieves the contents of the given key, or end() if not found. This method
127*6777b538SAndroid Build Coastguard Worker   // has the side effect of moving the requested item to the front of the
128*6777b538SAndroid Build Coastguard Worker   // recency list.
Get(const key_type & key)129*6777b538SAndroid Build Coastguard Worker   iterator Get(const key_type& key) {
130*6777b538SAndroid Build Coastguard Worker     typename KeyIndex::iterator index_iter = index_.find(key);
131*6777b538SAndroid Build Coastguard Worker     if (index_iter == index_.end())
132*6777b538SAndroid Build Coastguard Worker       return end();
133*6777b538SAndroid Build Coastguard Worker     typename ValueList::iterator iter = index_iter->second;
134*6777b538SAndroid Build Coastguard Worker 
135*6777b538SAndroid Build Coastguard Worker     // Move the touched item to the front of the recency ordering.
136*6777b538SAndroid Build Coastguard Worker     ordering_.splice(ordering_.begin(), ordering_, iter);
137*6777b538SAndroid Build Coastguard Worker     return ordering_.begin();
138*6777b538SAndroid Build Coastguard Worker   }
139*6777b538SAndroid Build Coastguard Worker 
140*6777b538SAndroid Build Coastguard Worker   // Retrieves the item associated with a given key and returns it via
141*6777b538SAndroid Build Coastguard Worker   // result without affecting the ordering (unlike Get()).
Peek(const key_type & key)142*6777b538SAndroid Build Coastguard Worker   iterator Peek(const key_type& key) {
143*6777b538SAndroid Build Coastguard Worker     typename KeyIndex::const_iterator index_iter = index_.find(key);
144*6777b538SAndroid Build Coastguard Worker     if (index_iter == index_.end())
145*6777b538SAndroid Build Coastguard Worker       return end();
146*6777b538SAndroid Build Coastguard Worker     return index_iter->second;
147*6777b538SAndroid Build Coastguard Worker   }
148*6777b538SAndroid Build Coastguard Worker 
Peek(const key_type & key)149*6777b538SAndroid Build Coastguard Worker   const_iterator Peek(const key_type& key) const {
150*6777b538SAndroid Build Coastguard Worker     typename KeyIndex::const_iterator index_iter = index_.find(key);
151*6777b538SAndroid Build Coastguard Worker     if (index_iter == index_.end())
152*6777b538SAndroid Build Coastguard Worker       return end();
153*6777b538SAndroid Build Coastguard Worker     return index_iter->second;
154*6777b538SAndroid Build Coastguard Worker   }
155*6777b538SAndroid Build Coastguard Worker 
156*6777b538SAndroid Build Coastguard Worker   // Exchanges the contents of |this| by the contents of the |other|.
Swap(LRUCacheBase & other)157*6777b538SAndroid Build Coastguard Worker   void Swap(LRUCacheBase& other) {
158*6777b538SAndroid Build Coastguard Worker     ordering_.swap(other.ordering_);
159*6777b538SAndroid Build Coastguard Worker     index_.swap(other.index_);
160*6777b538SAndroid Build Coastguard Worker     std::swap(max_size_, other.max_size_);
161*6777b538SAndroid Build Coastguard Worker   }
162*6777b538SAndroid Build Coastguard Worker 
163*6777b538SAndroid Build Coastguard Worker   // Erases the item referenced by the given iterator. An iterator to the item
164*6777b538SAndroid Build Coastguard Worker   // following it will be returned. The iterator must be valid.
Erase(iterator pos)165*6777b538SAndroid Build Coastguard Worker   iterator Erase(iterator pos) {
166*6777b538SAndroid Build Coastguard Worker     index_.erase(GetKeyFromValue()(*pos));
167*6777b538SAndroid Build Coastguard Worker     return ordering_.erase(pos);
168*6777b538SAndroid Build Coastguard Worker   }
169*6777b538SAndroid Build Coastguard Worker 
170*6777b538SAndroid Build Coastguard Worker   // LRUCache entries are often processed in reverse order, so we add this
171*6777b538SAndroid Build Coastguard Worker   // convenience function (not typically defined by STL containers).
Erase(reverse_iterator pos)172*6777b538SAndroid Build Coastguard Worker   reverse_iterator Erase(reverse_iterator pos) {
173*6777b538SAndroid Build Coastguard Worker     // We have to actually give it the incremented iterator to delete, since
174*6777b538SAndroid Build Coastguard Worker     // the forward iterator that base() returns is actually one past the item
175*6777b538SAndroid Build Coastguard Worker     // being iterated over.
176*6777b538SAndroid Build Coastguard Worker     return reverse_iterator(Erase((++pos).base()));
177*6777b538SAndroid Build Coastguard Worker   }
178*6777b538SAndroid Build Coastguard Worker 
179*6777b538SAndroid Build Coastguard Worker   // Shrinks the cache so it only holds |new_size| items. If |new_size| is
180*6777b538SAndroid Build Coastguard Worker   // bigger or equal to the current number of items, this will do nothing.
ShrinkToSize(size_type new_size)181*6777b538SAndroid Build Coastguard Worker   void ShrinkToSize(size_type new_size) {
182*6777b538SAndroid Build Coastguard Worker     for (size_type i = size(); i > new_size; i--)
183*6777b538SAndroid Build Coastguard Worker       Erase(rbegin());
184*6777b538SAndroid Build Coastguard Worker   }
185*6777b538SAndroid Build Coastguard Worker 
186*6777b538SAndroid Build Coastguard Worker   // Deletes everything from the cache.
Clear()187*6777b538SAndroid Build Coastguard Worker   void Clear() {
188*6777b538SAndroid Build Coastguard Worker     index_.clear();
189*6777b538SAndroid Build Coastguard Worker     ordering_.clear();
190*6777b538SAndroid Build Coastguard Worker   }
191*6777b538SAndroid Build Coastguard Worker 
192*6777b538SAndroid Build Coastguard Worker   // Returns the number of elements in the cache.
size()193*6777b538SAndroid Build Coastguard Worker   size_type size() const {
194*6777b538SAndroid Build Coastguard Worker     // We don't use ordering_.size() for the return value because
195*6777b538SAndroid Build Coastguard Worker     // (as a linked list) it can be O(n).
196*6777b538SAndroid Build Coastguard Worker     DCHECK(index_.size() == ordering_.size());
197*6777b538SAndroid Build Coastguard Worker     return index_.size();
198*6777b538SAndroid Build Coastguard Worker   }
199*6777b538SAndroid Build Coastguard Worker 
200*6777b538SAndroid Build Coastguard Worker   // Allows iteration over the list. Forward iteration starts with the most
201*6777b538SAndroid Build Coastguard Worker   // recent item and works backwards.
202*6777b538SAndroid Build Coastguard Worker   //
203*6777b538SAndroid Build Coastguard Worker   // Note that since these iterators are actually iterators over a list, you
204*6777b538SAndroid Build Coastguard Worker   // can keep them as you insert or delete things (as long as you don't delete
205*6777b538SAndroid Build Coastguard Worker   // the one you are pointing to) and they will still be valid.
begin()206*6777b538SAndroid Build Coastguard Worker   iterator begin() { return ordering_.begin(); }
begin()207*6777b538SAndroid Build Coastguard Worker   const_iterator begin() const { return ordering_.begin(); }
end()208*6777b538SAndroid Build Coastguard Worker   iterator end() { return ordering_.end(); }
end()209*6777b538SAndroid Build Coastguard Worker   const_iterator end() const { return ordering_.end(); }
210*6777b538SAndroid Build Coastguard Worker 
rbegin()211*6777b538SAndroid Build Coastguard Worker   reverse_iterator rbegin() { return ordering_.rbegin(); }
rbegin()212*6777b538SAndroid Build Coastguard Worker   const_reverse_iterator rbegin() const { return ordering_.rbegin(); }
rend()213*6777b538SAndroid Build Coastguard Worker   reverse_iterator rend() { return ordering_.rend(); }
rend()214*6777b538SAndroid Build Coastguard Worker   const_reverse_iterator rend() const { return ordering_.rend(); }
215*6777b538SAndroid Build Coastguard Worker 
empty()216*6777b538SAndroid Build Coastguard Worker   bool empty() const { return ordering_.empty(); }
217*6777b538SAndroid Build Coastguard Worker 
218*6777b538SAndroid Build Coastguard Worker  private:
219*6777b538SAndroid Build Coastguard Worker   template <class LruCacheType>
220*6777b538SAndroid Build Coastguard Worker   friend size_t trace_event::internal::DoEstimateMemoryUsageForLruCache(
221*6777b538SAndroid Build Coastguard Worker       const LruCacheType&);
222*6777b538SAndroid Build Coastguard Worker 
223*6777b538SAndroid Build Coastguard Worker   ValueList ordering_;
224*6777b538SAndroid Build Coastguard Worker   // TODO(crbug.com/1472363): Remove annotation once crbug.com/1472363 is fixed.
225*6777b538SAndroid Build Coastguard Worker   __attribute__((annotate("blink_gc_plugin_ignore"))) KeyIndex index_;
226*6777b538SAndroid Build Coastguard Worker 
227*6777b538SAndroid Build Coastguard Worker   size_type max_size_;
228*6777b538SAndroid Build Coastguard Worker };
229*6777b538SAndroid Build Coastguard Worker 
230*6777b538SAndroid Build Coastguard Worker template <class KeyType, class KeyCompare>
231*6777b538SAndroid Build Coastguard Worker struct LRUCacheKeyIndex {
232*6777b538SAndroid Build Coastguard Worker   template <class ValueType>
233*6777b538SAndroid Build Coastguard Worker   using Type = std::map<KeyType, ValueType, KeyCompare>;
234*6777b538SAndroid Build Coastguard Worker };
235*6777b538SAndroid Build Coastguard Worker 
236*6777b538SAndroid Build Coastguard Worker template <class KeyType, class KeyHash, class KeyEqual>
237*6777b538SAndroid Build Coastguard Worker struct HashingLRUCacheKeyIndex {
238*6777b538SAndroid Build Coastguard Worker   template <class ValueType>
239*6777b538SAndroid Build Coastguard Worker   using Type = std::unordered_map<KeyType, ValueType, KeyHash, KeyEqual>;
240*6777b538SAndroid Build Coastguard Worker };
241*6777b538SAndroid Build Coastguard Worker 
242*6777b538SAndroid Build Coastguard Worker }  // namespace internal
243*6777b538SAndroid Build Coastguard Worker 
244*6777b538SAndroid Build Coastguard Worker // Implements an LRU cache of `ValueType`, where each value can be uniquely
245*6777b538SAndroid Build Coastguard Worker // referenced by `KeyType`. Entries can be iterated in order of
246*6777b538SAndroid Build Coastguard Worker // least-recently-used to most-recently-used by iterating from `rbegin()` to
247*6777b538SAndroid Build Coastguard Worker // `rend()`, where a "use" is defined as a call to `Put(k, v)` or `Get(k)`.
248*6777b538SAndroid Build Coastguard Worker template <class KeyType, class ValueType, class KeyCompare = std::less<KeyType>>
249*6777b538SAndroid Build Coastguard Worker using LRUCache =
250*6777b538SAndroid Build Coastguard Worker     internal::LRUCacheBase<std::pair<KeyType, ValueType>,
251*6777b538SAndroid Build Coastguard Worker                            internal::GetKeyFromKVPair,
252*6777b538SAndroid Build Coastguard Worker                            internal::LRUCacheKeyIndex<KeyType, KeyCompare>>;
253*6777b538SAndroid Build Coastguard Worker 
254*6777b538SAndroid Build Coastguard Worker // Implements an LRU cache of `ValueType`, where each value can be uniquely
255*6777b538SAndroid Build Coastguard Worker // referenced by `KeyType`, and `KeyType` may be hashed for O(1) insertion,
256*6777b538SAndroid Build Coastguard Worker // removal, and lookup. Entries can be iterated in order of least-recently-used
257*6777b538SAndroid Build Coastguard Worker // to most-recently-used by iterating from `rbegin()` to `rend()`, where a "use"
258*6777b538SAndroid Build Coastguard Worker // is defined as a call to `Put(k, v)` or `Get(k)`.
259*6777b538SAndroid Build Coastguard Worker template <class KeyType,
260*6777b538SAndroid Build Coastguard Worker           class ValueType,
261*6777b538SAndroid Build Coastguard Worker           class KeyHash = std::hash<KeyType>,
262*6777b538SAndroid Build Coastguard Worker           class KeyEqual = std::equal_to<KeyType>>
263*6777b538SAndroid Build Coastguard Worker using HashingLRUCache = internal::LRUCacheBase<
264*6777b538SAndroid Build Coastguard Worker     std::pair<KeyType, ValueType>,
265*6777b538SAndroid Build Coastguard Worker     internal::GetKeyFromKVPair,
266*6777b538SAndroid Build Coastguard Worker     internal::HashingLRUCacheKeyIndex<KeyType, KeyHash, KeyEqual>>;
267*6777b538SAndroid Build Coastguard Worker 
268*6777b538SAndroid Build Coastguard Worker // Implements an LRU cache of `ValueType`, where each value is unique. Entries
269*6777b538SAndroid Build Coastguard Worker // can be iterated in order of least-recently-used to most-recently-used by
270*6777b538SAndroid Build Coastguard Worker // iterating from `rbegin()` to `rend()`, where a "use" is defined as a call to
271*6777b538SAndroid Build Coastguard Worker // `Put(v)` or `Get(v)`.
272*6777b538SAndroid Build Coastguard Worker template <class ValueType, class Compare = std::less<ValueType>>
273*6777b538SAndroid Build Coastguard Worker using LRUCacheSet =
274*6777b538SAndroid Build Coastguard Worker     internal::LRUCacheBase<ValueType,
275*6777b538SAndroid Build Coastguard Worker                            std::identity,
276*6777b538SAndroid Build Coastguard Worker                            internal::LRUCacheKeyIndex<ValueType, Compare>>;
277*6777b538SAndroid Build Coastguard Worker 
278*6777b538SAndroid Build Coastguard Worker // Implements an LRU cache of `ValueType`, where is value is unique, and may be
279*6777b538SAndroid Build Coastguard Worker // hashed for O(1) insertion, removal, and lookup. Entries can be iterated in
280*6777b538SAndroid Build Coastguard Worker // order of least-recently-used to most-recently-used by iterating from
281*6777b538SAndroid Build Coastguard Worker // `rbegin()` to `rend()`, where a "use" is defined as a call to `Put(v)` or
282*6777b538SAndroid Build Coastguard Worker // `Get(v)`.
283*6777b538SAndroid Build Coastguard Worker template <class ValueType,
284*6777b538SAndroid Build Coastguard Worker           class Hash = std::hash<ValueType>,
285*6777b538SAndroid Build Coastguard Worker           class Equal = std::equal_to<ValueType>>
286*6777b538SAndroid Build Coastguard Worker using HashingLRUCacheSet = internal::LRUCacheBase<
287*6777b538SAndroid Build Coastguard Worker     ValueType,
288*6777b538SAndroid Build Coastguard Worker     std::identity,
289*6777b538SAndroid Build Coastguard Worker     internal::HashingLRUCacheKeyIndex<ValueType, Hash, Equal>>;
290*6777b538SAndroid Build Coastguard Worker 
291*6777b538SAndroid Build Coastguard Worker }  // namespace base
292*6777b538SAndroid Build Coastguard Worker 
293*6777b538SAndroid Build Coastguard Worker #endif  // BASE_CONTAINERS_LRU_CACHE_H_
294