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