// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // This file contains a template for a Most Recently Used cache that allows // constant-time access to items using a key, but easy identification of the // least-recently-used items for removal. Each key can only be associated with // one payload item at a time. // // The key object will be stored twice, so it should support efficient copying. // // NOTE: While all operations are O(1), this code is written for // legibility rather than optimality. If future profiling identifies this as // a bottleneck, there is room for smaller values of 1 in the O(1). :] #ifndef ANGLEBASE_CONTAINERS_MRU_CACHE_H_ #define ANGLEBASE_CONTAINERS_MRU_CACHE_H_ #include <stddef.h> #include <algorithm> #include <functional> #include <list> #include <map> #include <unordered_map> #include <utility> #include "anglebase/logging.h" #include "anglebase/macros.h" namespace angle { namespace base { // MRUCacheBase ---------------------------------------------------------------- // This template is used to standardize map type containers that can be used // by MRUCacheBase. This level of indirection is necessary because of the way // that template template params and default template params interact. template <class KeyType, class ValueType, class CompareType> struct MRUCacheStandardMap { … }; // Base class for the MRU cache specializations defined below. template <class KeyType, class PayloadType, class HashOrCompareType, template <typename, typename, typename> class MapType = MRUCacheStandardMap> class MRUCacheBase { … }; // MRUCache -------------------------------------------------------------------- // A container that does not do anything to free its data. Use this when storing // value types (as opposed to pointers) in the list. template <class KeyType, class PayloadType, class CompareType = std::less<KeyType>> class MRUCache : public MRUCacheBase<KeyType, PayloadType, CompareType> { private: using ParentType = MRUCacheBase<KeyType, PayloadType, CompareType>; public: // See MRUCacheBase, noting the possibility of using NO_AUTO_EVICT. explicit MRUCache(typename ParentType::size_type max_size) : … { … } virtual ~MRUCache() { … } private: DISALLOW_COPY_AND_ASSIGN(MRUCache); }; // HashingMRUCache ------------------------------------------------------------ template <class KeyType, class ValueType, class HashType> struct MRUCacheHashMap { … }; // This class is similar to MRUCache, except that it uses std::unordered_map as // the map type instead of std::map. Note that your KeyType must be hashable to // use this cache or you need to provide a hashing class. template <class KeyType, class PayloadType, class HashType = std::hash<KeyType>> class HashingMRUCache : public MRUCacheBase<KeyType, PayloadType, HashType, MRUCacheHashMap> { private: using ParentType = MRUCacheBase<KeyType, PayloadType, HashType, MRUCacheHashMap>; public: // See MRUCacheBase, noting the possibility of using NO_AUTO_EVICT. explicit HashingMRUCache(typename ParentType::size_type max_size) : … { … } virtual ~HashingMRUCache() override { … } private: DISALLOW_COPY_AND_ASSIGN(HashingMRUCache); }; } // namespace base } // namespace angle #endif // ANGLEBASE_CONTAINERS_MRU_CACHE_H_