| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // This file contains a template for a Most Recently Used cache that allows | 5 // This file contains a template for a Most Recently Used cache that allows |
| 6 // constant-time access to items using a key, but easy identification of the | 6 // constant-time access to items using a key, but easy identification of the |
| 7 // least-recently-used items for removal. Each key can only be associated with | 7 // least-recently-used items for removal. Each key can only be associated with |
| 8 // one payload item at a time. | 8 // one payload item at a time. |
| 9 // | 9 // |
| 10 // The key object will be stored twice, so it should support efficient copying. | 10 // The key object will be stored twice, so it should support efficient copying. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 } | 63 } |
| 64 | 64 |
| 65 // Inserts a payload item with the given key. If an existing item has | 65 // Inserts a payload item with the given key. If an existing item has |
| 66 // the same key, it is removed prior to insertion. An iterator indicating the | 66 // the same key, it is removed prior to insertion. An iterator indicating the |
| 67 // inserted item will be returned (this will always be the front of the list). | 67 // inserted item will be returned (this will always be the front of the list). |
| 68 // | 68 // |
| 69 // The payload will be copied. In the case of an OwningMRUCache, this function | 69 // The payload will be copied. In the case of an OwningMRUCache, this function |
| 70 // will take ownership of the pointer. | 70 // will take ownership of the pointer. |
| 71 iterator Put(const KeyType& key, const PayloadType& payload) { | 71 iterator Put(const KeyType& key, const PayloadType& payload) { |
| 72 // Remove any existing payload with that key. | 72 // Remove any existing payload with that key. |
| 73 KeyIndex::iterator index_iter = index_.find(key); | 73 typename KeyIndex::iterator index_iter = index_.find(key); |
| 74 if (index_iter != index_.end()) { | 74 if (index_iter != index_.end()) { |
| 75 // Erase the reference to it. This will call the deletor on the removed | 75 // Erase the reference to it. This will call the deletor on the removed |
| 76 // element. The index reference will be replaced in the code below. | 76 // element. The index reference will be replaced in the code below. |
| 77 Erase(index_iter->second); | 77 Erase(index_iter->second); |
| 78 } else if (max_size_ != NO_AUTO_EVICT) { | 78 } else if (max_size_ != NO_AUTO_EVICT) { |
| 79 // New item is being inserted which might make it larger than the maximum | 79 // New item is being inserted which might make it larger than the maximum |
| 80 // size: kick the oldest thing out if necessary. | 80 // size: kick the oldest thing out if necessary. |
| 81 ShrinkToSize(max_size_ - 1); | 81 ShrinkToSize(max_size_ - 1); |
| 82 } | 82 } |
| 83 | 83 |
| 84 ordering_.push_front(value_type(key, payload)); | 84 ordering_.push_front(value_type(key, payload)); |
| 85 index_[key] = ordering_.begin(); | 85 index_[key] = ordering_.begin(); |
| 86 return ordering_.begin(); | 86 return ordering_.begin(); |
| 87 } | 87 } |
| 88 | 88 |
| 89 // Retrieves the contents of the given key, or end() if not found. This method | 89 // Retrieves the contents of the given key, or end() if not found. This method |
| 90 // has the side effect of moving the requested item to the front of the | 90 // has the side effect of moving the requested item to the front of the |
| 91 // recency list. | 91 // recency list. |
| 92 // | 92 // |
| 93 // TODO(brettw) We may want a const version of this function in the future. | 93 // TODO(brettw) We may want a const version of this function in the future. |
| 94 iterator Get(const KeyType& key) { | 94 iterator Get(const KeyType& key) { |
| 95 KeyIndex::iterator index_iter = index_.find(key); | 95 typename KeyIndex::iterator index_iter = index_.find(key); |
| 96 if (index_iter == index_.end()) | 96 if (index_iter == index_.end()) |
| 97 return end(); | 97 return end(); |
| 98 PayloadList::iterator iter = index_iter->second; | 98 typename PayloadList::iterator iter = index_iter->second; |
| 99 | 99 |
| 100 // Move the touched item to the front of the recency ordering. | 100 // Move the touched item to the front of the recency ordering. |
| 101 ordering_.splice(ordering_.begin(), ordering_, iter); | 101 ordering_.splice(ordering_.begin(), ordering_, iter); |
| 102 return ordering_.begin(); | 102 return ordering_.begin(); |
| 103 } | 103 } |
| 104 | 104 |
| 105 // Retrieves the payload associated with a given key and returns it via | 105 // Retrieves the payload associated with a given key and returns it via |
| 106 // result without affecting the ordering (unlike Get). | 106 // result without affecting the ordering (unlike Get). |
| 107 // | 107 // |
| 108 // TODO(brettw) We may want a const version of this function in the future. | 108 // TODO(brettw) We may want a const version of this function in the future. |
| 109 iterator Peek(const KeyType& key) { | 109 iterator Peek(const KeyType& key) { |
| 110 KeyIndex::const_iterator index_iter = index_.find(key); | 110 typename KeyIndex::const_iterator index_iter = index_.find(key); |
| 111 if (index_iter == index_.end()) | 111 if (index_iter == index_.end()) |
| 112 return end(); | 112 return end(); |
| 113 return index_iter->second; | 113 return index_iter->second; |
| 114 } | 114 } |
| 115 | 115 |
| 116 // Erases the item referenced by the given iterator. An iterator to the item | 116 // Erases the item referenced by the given iterator. An iterator to the item |
| 117 // following it will be returned. The iterator must be valid. | 117 // following it will be returned. The iterator must be valid. |
| 118 iterator Erase(iterator pos) { | 118 iterator Erase(iterator pos) { |
| 119 deletor_(pos->second); | 119 deletor_(pos->second); |
| 120 index_.erase(pos->first); | 120 index_.erase(pos->first); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 void operator()(PayloadType& payload) { | 183 void operator()(PayloadType& payload) { |
| 184 } | 184 } |
| 185 }; | 185 }; |
| 186 | 186 |
| 187 // A container that does not do anything to free its data. Use this when storing | 187 // A container that does not do anything to free its data. Use this when storing |
| 188 // value types (as opposed to pointers) in the list. | 188 // value types (as opposed to pointers) in the list. |
| 189 template <class KeyType, class PayloadType> | 189 template <class KeyType, class PayloadType> |
| 190 class MRUCache : public MRUCacheBase<KeyType, | 190 class MRUCache : public MRUCacheBase<KeyType, |
| 191 PayloadType, | 191 PayloadType, |
| 192 MRUCacheNullDeletor<PayloadType> > { | 192 MRUCacheNullDeletor<PayloadType> > { |
| 193 private: |
| 194 typedef MRUCacheBase<KeyType, PayloadType, |
| 195 MRUCacheNullDeletor<PayloadType> > ParentType; |
| 196 |
| 193 public: | 197 public: |
| 194 // See MRUCacheBase, noting the possibility of using NO_AUTO_EVICT. | 198 // See MRUCacheBase, noting the possibility of using NO_AUTO_EVICT. |
| 195 MRUCache(size_type max_size) : MRUCacheBase(max_size) { | 199 MRUCache(typename ParentType::size_type max_size) |
| 200 : ParentType(max_size) { |
| 196 } | 201 } |
| 197 virtual ~MRUCache() { | 202 virtual ~MRUCache() { |
| 198 } | 203 } |
| 199 | 204 |
| 200 private: | 205 private: |
| 201 DISALLOW_EVIL_CONSTRUCTORS(MRUCache); | 206 DISALLOW_COPY_AND_ASSIGN(MRUCache); |
| 202 }; | 207 }; |
| 203 | 208 |
| 204 // OwningMRUCache -------------------------------------------------------------- | 209 // OwningMRUCache -------------------------------------------------------------- |
| 205 | 210 |
| 206 template<class PayloadType> | 211 template<class PayloadType> |
| 207 class MRUCachePointerDeletor { | 212 class MRUCachePointerDeletor { |
| 208 public: | 213 public: |
| 209 void operator()(PayloadType& payload) { | 214 void operator()(PayloadType& payload) { |
| 210 delete payload; | 215 delete payload; |
| 211 } | 216 } |
| 212 }; | 217 }; |
| 213 | 218 |
| 214 // A cache that owns the payload type, which must be a non-const pointer type. | 219 // A cache that owns the payload type, which must be a non-const pointer type. |
| 215 // The pointers will be deleted when they are removed, replaced, or when the | 220 // The pointers will be deleted when they are removed, replaced, or when the |
| 216 // cache is destroyed. | 221 // cache is destroyed. |
| 217 template <class KeyType, class PayloadType> | 222 template <class KeyType, class PayloadType> |
| 218 class OwningMRUCache | 223 class OwningMRUCache |
| 219 : public MRUCacheBase<KeyType, | 224 : public MRUCacheBase<KeyType, |
| 220 PayloadType, | 225 PayloadType, |
| 221 MRUCachePointerDeletor<PayloadType> > { | 226 MRUCachePointerDeletor<PayloadType> > { |
| 227 private: |
| 228 typedef MRUCacheBase<KeyType, PayloadType, |
| 229 MRUCachePointerDeletor<PayloadType> > ParentType; |
| 230 |
| 222 public: | 231 public: |
| 223 // See MRUCacheBase, noting the possibility of using NO_AUTO_EVICT. | 232 // See MRUCacheBase, noting the possibility of using NO_AUTO_EVICT. |
| 224 OwningMRUCache(size_type max_size) : MRUCacheBase(max_size) { | 233 OwningMRUCache(typename ParentType::size_type max_size) |
| 234 : ParentType(max_size) { |
| 225 } | 235 } |
| 226 virtual ~OwningMRUCache() { | 236 virtual ~OwningMRUCache() { |
| 227 } | 237 } |
| 228 | 238 |
| 229 private: | 239 private: |
| 230 DISALLOW_EVIL_CONSTRUCTORS(OwningMRUCache); | 240 DISALLOW_COPY_AND_ASSIGN(OwningMRUCache); |
| 231 }; | 241 }; |
| 232 | 242 |
| 233 #endif // CHROME_COMMON_MRU_CACHE_H__ | 243 #endif // CHROME_COMMON_MRU_CACHE_H__ |
| 234 | 244 |
| OLD | NEW |