Chromium Code Reviews
[email protected] (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(266)

Side by Side Diff: net/base/expiring_cache.h

Issue 11359053: [net] Measure DNS.CacheEvicted and DNS.CacheExpired. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: distinguish evictions on Get and Put Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | net/base/host_cache.h » ('j') | net/base/host_cache.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #ifndef NET_BASE_EXPIRING_CACHE_H_ 5 #ifndef NET_BASE_EXPIRING_CACHE_H_
6 #define NET_BASE_EXPIRING_CACHE_H_ 6 #define NET_BASE_EXPIRING_CACHE_H_
7 7
8 #include <map> 8 #include <map>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/basictypes.h" 11 #include "base/basictypes.h"
12 #include "base/gtest_prod_util.h" 12 #include "base/gtest_prod_util.h"
13 #include "base/time.h" 13 #include "base/time.h"
14 14
15 namespace net { 15 namespace net {
16 16
17 template <typename KeyType,
18 typename ValueType,
19 typename ExpirationType>
20 class NoopEvictionHandler {
21 public:
22 void handle(const KeyType& key,
cbentzel 2012/11/07 10:40:22 Nit: Should be Handle rather than handle.
23 const ValueType& value,
24 const ExpirationType& expiration,
25 const ExpirationType& now,
26 bool onGet) const {
cbentzel 2012/11/07 10:40:22 Nit: on_get instead of onGet.
27 }
28 };
29
17 // Cache implementation where all entries have an explicit expiration policy. As 30 // Cache implementation where all entries have an explicit expiration policy. As
18 // new items are added, expired items will be removed first. 31 // new items are added, expired items will be removed first.
19 // The template types have the following requirements: 32 // The template types have the following requirements:
20 // KeyType must be LessThanComparable, Assignable, and CopyConstructible. 33 // KeyType must be LessThanComparable, Assignable, and CopyConstructible.
21 // ValueType must be CopyConstructible and Assignable. 34 // ValueType must be CopyConstructible and Assignable.
22 // ExpirationType must be CopyConstructible and Assignable. 35 // ExpirationType must be CopyConstructible and Assignable.
23 // ExpirationCompare is a function class that takes two arguments of the 36 // ExpirationCompare is a function class that takes two arguments of the
24 // type ExpirationType and returns a bool. If |comp| is an instance of 37 // type ExpirationType and returns a bool. If |comp| is an instance of
25 // ExpirationCompare, then the expression |comp(current, expiration)| shall 38 // ExpirationCompare, then the expression |comp(current, expiration)| shall
26 // return true iff |current| is still valid within |expiration|. 39 // return true iff |current| is still valid within |expiration|.
27 // 40 //
28 // A simple use of this class may use base::TimeTicks, which provides a 41 // A simple use of this class may use base::TimeTicks, which provides a
29 // monotonically increasing clock, for the expiration type. Because it's always 42 // monotonically increasing clock, for the expiration type. Because it's always
30 // increasing, std::less<> can be used, which will simply ensure that |now| is 43 // increasing, std::less<> can be used, which will simply ensure that |now| is
31 // sorted before |expiration|: 44 // sorted before |expiration|:
32 // 45 //
33 // ExpiringCache<std::string, std::string, base::TimeTicks, 46 // ExpiringCache<std::string, std::string, base::TimeTicks,
34 // std::less<base::TimeTicks> > cache(0); 47 // std::less<base::TimeTicks> > cache(0);
jar (doing other things) 2012/11/05 17:44:56 This looks like it tries to create a cache with ze
35 // // Add a value that expires in 5 minutes 48 // // Add a value that expires in 5 minutes
36 // cache.Put("key1", "value1", base::TimeTicks::Now(), 49 // cache.Put("key1", "value1", base::TimeTicks::Now(),
37 // base::TimeTicks::Now() + base::TimeDelta::FromMinutes(5)); 50 // base::TimeTicks::Now() + base::TimeDelta::FromMinutes(5));
38 // // Add another value that expires in 10 minutes. 51 // // Add another value that expires in 10 minutes.
jar (doing other things) 2012/11/05 17:44:56 Given the cache size of zero, this appear to repla
39 // cache.Put("key2", "value2", base::TimeTicks::Now(), 52 // cache.Put("key2", "value2", base::TimeTicks::Now(),
40 // base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10)); 53 // base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10));
41 // 54 //
42 // Alternatively, there may be some more complex expiration criteria, at which 55 // Alternatively, there may be some more complex expiration criteria, at which
43 // point a custom functor may be used: 56 // point a custom functor may be used:
44 // 57 //
45 // struct ComplexExpirationFunctor { 58 // struct ComplexExpirationFunctor {
46 // bool operator()(const ComplexExpiration& now, 59 // bool operator()(const ComplexExpiration& now,
47 // const ComplexExpiration& expiration) const; 60 // const ComplexExpiration& expiration) const;
48 // }; 61 // };
49 // ExpiringCache<std::string, std::string, ComplexExpiration, 62 // ExpiringCache<std::string, std::string, ComplexExpiration,
50 // ComplexExpirationFunctor> cache(15); 63 // ComplexExpirationFunctor> cache(15);
51 // // Add a value that expires once the 'sprocket' has 'cog'-ified. 64 // // Add a value that expires once the 'sprocket' has 'cog'-ified.
52 // cache.Put("key1", "value1", ComplexExpiration("sprocket"), 65 // cache.Put("key1", "value1", ComplexExpiration("sprocket"),
53 // ComplexExpiration("cog")); 66 // ComplexExpiration("cog"));
54 template <typename KeyType, 67 template <typename KeyType,
55 typename ValueType, 68 typename ValueType,
56 typename ExpirationType, 69 typename ExpirationType,
57 typename ExpirationCompare> 70 typename ExpirationCompare,
71 typename EvictionHandler = NoopEvictionHandler<KeyType,
72 ValueType,
73 ExpirationType> >
58 class ExpiringCache { 74 class ExpiringCache {
59 private: 75 private:
60 // Intentionally violate the C++ Style Guide so that EntryMap is known to be 76 // Intentionally violate the C++ Style Guide so that EntryMap is known to be
61 // a dependent type. Without this, Clang's two-phase lookup complains when 77 // a dependent type. Without this, Clang's two-phase lookup complains when
62 // using EntryMap::const_iterator, while GCC and MSVC happily resolve the 78 // using EntryMap::const_iterator, while GCC and MSVC happily resolve the
63 // typename. 79 // typename.
64 80
65 // Tuple to represent the value and when it expires. 81 // Tuple to represent the value and when it expires.
66 typedef std::pair<ValueType, ExpirationType> Entry; 82 typedef std::pair<ValueType, ExpirationType> Entry;
67 typedef std::map<KeyType, Entry> EntryMap; 83 typedef std::map<KeyType, Entry> EntryMap;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 // expired, it is immediately removed from the cache. 122 // expired, it is immediately removed from the cache.
107 // Note: The returned pointer remains owned by the ExpiringCache and is 123 // Note: The returned pointer remains owned by the ExpiringCache and is
108 // invalidated by a call to a non-const method. 124 // invalidated by a call to a non-const method.
109 const ValueType* Get(const KeyType& key, const ExpirationType& now) { 125 const ValueType* Get(const KeyType& key, const ExpirationType& now) {
110 typename EntryMap::iterator it = entries_.find(key); 126 typename EntryMap::iterator it = entries_.find(key);
111 if (it == entries_.end()) 127 if (it == entries_.end())
112 return NULL; 128 return NULL;
113 129
114 // Immediately remove expired entries. 130 // Immediately remove expired entries.
115 if (!expiration_comp_(now, it->second.second)) { 131 if (!expiration_comp_(now, it->second.second)) {
116 entries_.erase(it); 132 Evict(it, now, true);
117 return NULL; 133 return NULL;
118 } 134 }
119 135
120 return &it->second.first; 136 return &it->second.first;
121 } 137 }
122 138
123 // Updates or replaces the value associated with |key|. 139 // Updates or replaces the value associated with |key|.
124 void Put(const KeyType& key, 140 void Put(const KeyType& key,
125 const ValueType& value, 141 const ValueType& value,
126 const ExpirationType& now, 142 const ExpirationType& now,
(...skipping 29 matching lines...) Expand all
156 private: 172 private:
157 FRIEND_TEST_ALL_PREFIXES(ExpiringCacheTest, Compact); 173 FRIEND_TEST_ALL_PREFIXES(ExpiringCacheTest, Compact);
158 FRIEND_TEST_ALL_PREFIXES(ExpiringCacheTest, CustomFunctor); 174 FRIEND_TEST_ALL_PREFIXES(ExpiringCacheTest, CustomFunctor);
159 175
160 // Prunes entries from the cache to bring it below |max_entries()|. 176 // Prunes entries from the cache to bring it below |max_entries()|.
161 void Compact(const ExpirationType& now) { 177 void Compact(const ExpirationType& now) {
162 // Clear out expired entries. 178 // Clear out expired entries.
163 typename EntryMap::iterator it; 179 typename EntryMap::iterator it;
164 for (it = entries_.begin(); it != entries_.end(); ) { 180 for (it = entries_.begin(); it != entries_.end(); ) {
165 if (!expiration_comp_(now, it->second.second)) { 181 if (!expiration_comp_(now, it->second.second)) {
166 entries_.erase(it++); 182 Evict(it++, now, false);
167 } else { 183 } else {
168 ++it; 184 ++it;
169 } 185 }
170 } 186 }
171 187
172 if (entries_.size() < max_entries_) 188 if (entries_.size() < max_entries_)
173 return; 189 return;
174 190
175 // If the cache is still too full, start deleting items 'randomly'. 191 // If the cache is still too full, start deleting items 'randomly'.
176 for (it = entries_.begin(); 192 for (it = entries_.begin();
177 it != entries_.end() && entries_.size() >= max_entries_;) { 193 it != entries_.end() && entries_.size() >= max_entries_;) {
178 entries_.erase(it++); 194 Evict(it++, now, false);
179 } 195 }
180 } 196 }
181 197
198 void Evict(typename EntryMap::iterator it,
199 const ExpirationType& now,
200 bool onGet) {
201 eviction_handler_.handle(it->first, it->second.first, it->second.second,
202 now, onGet);
203 entries_.erase(it);
204 }
205
182 // Bound on total size of the cache. 206 // Bound on total size of the cache.
183 size_t max_entries_; 207 size_t max_entries_;
184 208
185 EntryMap entries_; 209 EntryMap entries_;
186 ExpirationCompare expiration_comp_; 210 ExpirationCompare expiration_comp_;
211 EvictionHandler eviction_handler_;
187 212
188 DISALLOW_COPY_AND_ASSIGN(ExpiringCache); 213 DISALLOW_COPY_AND_ASSIGN(ExpiringCache);
189 }; 214 };
190 215
191 } // namespace net 216 } // namespace net
192 217
193 #endif // NET_BASE_EXPIRING_CACHE_H_ 218 #endif // NET_BASE_EXPIRING_CACHE_H_
OLDNEW
« no previous file with comments | « no previous file | net/base/host_cache.h » ('j') | net/base/host_cache.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698