OLD | NEW |
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 #include "net/dns/host_cache.h" | 5 #include "net/dns/host_cache.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
9 #include "base/metrics/field_trial.h" | 9 #include "base/metrics/field_trial.h" |
10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 DCHECK(out); | 100 DCHECK(out); |
101 out->expired_by = now - expires_; | 101 out->expired_by = now - expires_; |
102 out->network_changes = network_changes - network_changes_; | 102 out->network_changes = network_changes - network_changes_; |
103 out->stale_hits = stale_hits_; | 103 out->stale_hits = stale_hits_; |
104 } | 104 } |
105 | 105 |
106 HostCache::HostCache(size_t max_entries) | 106 HostCache::HostCache(size_t max_entries) |
107 : max_entries_(max_entries), network_changes_(0) {} | 107 : max_entries_(max_entries), network_changes_(0) {} |
108 | 108 |
109 HostCache::~HostCache() { | 109 HostCache::~HostCache() { |
| 110 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
110 RecordEraseAll(ERASE_DESTRUCT, base::TimeTicks::Now()); | 111 RecordEraseAll(ERASE_DESTRUCT, base::TimeTicks::Now()); |
111 } | 112 } |
112 | 113 |
113 const HostCache::Entry* HostCache::Lookup(const Key& key, | 114 const HostCache::Entry* HostCache::Lookup(const Key& key, |
114 base::TimeTicks now) { | 115 base::TimeTicks now) { |
115 DCHECK(CalledOnValidThread()); | 116 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
116 if (caching_is_disabled()) | 117 if (caching_is_disabled()) |
117 return nullptr; | 118 return nullptr; |
118 | 119 |
119 HostCache::Entry* entry = LookupInternal(key); | 120 HostCache::Entry* entry = LookupInternal(key); |
120 if (!entry) { | 121 if (!entry) { |
121 RecordLookup(LOOKUP_MISS_ABSENT, now, nullptr); | 122 RecordLookup(LOOKUP_MISS_ABSENT, now, nullptr); |
122 return nullptr; | 123 return nullptr; |
123 } | 124 } |
124 if (entry->IsStale(now, network_changes_)) { | 125 if (entry->IsStale(now, network_changes_)) { |
125 RecordLookup(LOOKUP_MISS_STALE, now, entry); | 126 RecordLookup(LOOKUP_MISS_STALE, now, entry); |
126 return nullptr; | 127 return nullptr; |
127 } | 128 } |
128 | 129 |
129 entry->CountHit(/* hit_is_stale= */ false); | 130 entry->CountHit(/* hit_is_stale= */ false); |
130 RecordLookup(LOOKUP_HIT_VALID, now, entry); | 131 RecordLookup(LOOKUP_HIT_VALID, now, entry); |
131 return entry; | 132 return entry; |
132 } | 133 } |
133 | 134 |
134 const HostCache::Entry* HostCache::LookupStale( | 135 const HostCache::Entry* HostCache::LookupStale( |
135 const Key& key, | 136 const Key& key, |
136 base::TimeTicks now, | 137 base::TimeTicks now, |
137 HostCache::EntryStaleness* stale_out) { | 138 HostCache::EntryStaleness* stale_out) { |
138 DCHECK(CalledOnValidThread()); | 139 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
139 if (caching_is_disabled()) | 140 if (caching_is_disabled()) |
140 return nullptr; | 141 return nullptr; |
141 | 142 |
142 HostCache::Entry* entry = LookupInternal(key); | 143 HostCache::Entry* entry = LookupInternal(key); |
143 if (!entry) { | 144 if (!entry) { |
144 RecordLookup(LOOKUP_MISS_ABSENT, now, nullptr); | 145 RecordLookup(LOOKUP_MISS_ABSENT, now, nullptr); |
145 return nullptr; | 146 return nullptr; |
146 } | 147 } |
147 | 148 |
148 bool is_stale = entry->IsStale(now, network_changes_); | 149 bool is_stale = entry->IsStale(now, network_changes_); |
149 entry->CountHit(/* hit_is_stale= */ is_stale); | 150 entry->CountHit(/* hit_is_stale= */ is_stale); |
150 RecordLookup(is_stale ? LOOKUP_HIT_STALE : LOOKUP_HIT_VALID, now, entry); | 151 RecordLookup(is_stale ? LOOKUP_HIT_STALE : LOOKUP_HIT_VALID, now, entry); |
151 | 152 |
152 if (stale_out) | 153 if (stale_out) |
153 entry->GetStaleness(now, network_changes_, stale_out); | 154 entry->GetStaleness(now, network_changes_, stale_out); |
154 return entry; | 155 return entry; |
155 } | 156 } |
156 | 157 |
157 HostCache::Entry* HostCache::LookupInternal(const Key& key) { | 158 HostCache::Entry* HostCache::LookupInternal(const Key& key) { |
158 auto it = entries_.find(key); | 159 auto it = entries_.find(key); |
159 return (it != entries_.end()) ? &it->second : nullptr; | 160 return (it != entries_.end()) ? &it->second : nullptr; |
160 } | 161 } |
161 | 162 |
162 void HostCache::Set(const Key& key, | 163 void HostCache::Set(const Key& key, |
163 const Entry& entry, | 164 const Entry& entry, |
164 base::TimeTicks now, | 165 base::TimeTicks now, |
165 base::TimeDelta ttl) { | 166 base::TimeDelta ttl) { |
166 TRACE_EVENT0(kNetTracingCategory, "HostCache::Set"); | 167 TRACE_EVENT0(kNetTracingCategory, "HostCache::Set"); |
167 DCHECK(CalledOnValidThread()); | 168 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
168 if (caching_is_disabled()) | 169 if (caching_is_disabled()) |
169 return; | 170 return; |
170 | 171 |
171 auto it = entries_.find(key); | 172 auto it = entries_.find(key); |
172 if (it != entries_.end()) { | 173 if (it != entries_.end()) { |
173 bool is_stale = it->second.IsStale(now, network_changes_); | 174 bool is_stale = it->second.IsStale(now, network_changes_); |
174 RecordSet(is_stale ? SET_UPDATE_STALE : SET_UPDATE_VALID, now, &it->second, | 175 RecordSet(is_stale ? SET_UPDATE_STALE : SET_UPDATE_VALID, now, &it->second, |
175 entry); | 176 entry); |
176 // TODO(juliatuttle): Remember some old metadata (hit count or frequency or | 177 // TODO(juliatuttle): Remember some old metadata (hit count or frequency or |
177 // something like that) if it's useful for better eviction algorithms? | 178 // something like that) if it's useful for better eviction algorithms? |
178 entries_.erase(it); | 179 entries_.erase(it); |
179 } else { | 180 } else { |
180 if (size() == max_entries_) | 181 if (size() == max_entries_) |
181 EvictOneEntry(now); | 182 EvictOneEntry(now); |
182 RecordSet(SET_INSERT, now, nullptr, entry); | 183 RecordSet(SET_INSERT, now, nullptr, entry); |
183 } | 184 } |
184 | 185 |
185 DCHECK_GT(max_entries_, size()); | 186 DCHECK_GT(max_entries_, size()); |
186 DCHECK_EQ(0u, entries_.count(key)); | 187 DCHECK_EQ(0u, entries_.count(key)); |
187 entries_.insert( | 188 entries_.insert( |
188 std::make_pair(Key(key), Entry(entry, now, ttl, network_changes_))); | 189 std::make_pair(Key(key), Entry(entry, now, ttl, network_changes_))); |
189 DCHECK_GE(max_entries_, size()); | 190 DCHECK_GE(max_entries_, size()); |
190 } | 191 } |
191 | 192 |
192 void HostCache::OnNetworkChange() { | 193 void HostCache::OnNetworkChange() { |
193 ++network_changes_; | 194 ++network_changes_; |
194 } | 195 } |
195 | 196 |
196 void HostCache::clear() { | 197 void HostCache::clear() { |
197 DCHECK(CalledOnValidThread()); | 198 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
198 RecordEraseAll(ERASE_CLEAR, base::TimeTicks::Now()); | 199 RecordEraseAll(ERASE_CLEAR, base::TimeTicks::Now()); |
199 entries_.clear(); | 200 entries_.clear(); |
200 } | 201 } |
201 | 202 |
202 void HostCache::ClearForHosts( | 203 void HostCache::ClearForHosts( |
203 const base::Callback<bool(const std::string&)>& host_filter) { | 204 const base::Callback<bool(const std::string&)>& host_filter) { |
204 DCHECK(CalledOnValidThread()); | 205 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
205 | 206 |
206 if (host_filter.is_null()) { | 207 if (host_filter.is_null()) { |
207 clear(); | 208 clear(); |
208 return; | 209 return; |
209 } | 210 } |
210 | 211 |
211 base::TimeTicks now = base::TimeTicks::Now(); | 212 base::TimeTicks now = base::TimeTicks::Now(); |
212 for (EntryMap::iterator it = entries_.begin(); it != entries_.end();) { | 213 for (EntryMap::iterator it = entries_.begin(); it != entries_.end();) { |
213 EntryMap::iterator next_it = std::next(it); | 214 EntryMap::iterator next_it = std::next(it); |
214 | 215 |
215 if (host_filter.Run(it->first.hostname)) { | 216 if (host_filter.Run(it->first.hostname)) { |
216 RecordErase(ERASE_CLEAR, now, it->second); | 217 RecordErase(ERASE_CLEAR, now, it->second); |
217 entries_.erase(it); | 218 entries_.erase(it); |
218 } | 219 } |
219 | 220 |
220 it = next_it; | 221 it = next_it; |
221 } | 222 } |
222 } | 223 } |
223 | 224 |
224 size_t HostCache::size() const { | 225 size_t HostCache::size() const { |
225 DCHECK(CalledOnValidThread()); | 226 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
226 return entries_.size(); | 227 return entries_.size(); |
227 } | 228 } |
228 | 229 |
229 size_t HostCache::max_entries() const { | 230 size_t HostCache::max_entries() const { |
230 DCHECK(CalledOnValidThread()); | 231 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
231 return max_entries_; | 232 return max_entries_; |
232 } | 233 } |
233 | 234 |
234 // static | 235 // static |
235 std::unique_ptr<HostCache> HostCache::CreateDefaultCache() { | 236 std::unique_ptr<HostCache> HostCache::CreateDefaultCache() { |
236 // Cache capacity is determined by the field trial. | 237 // Cache capacity is determined by the field trial. |
237 #if defined(ENABLE_BUILT_IN_DNS) | 238 #if defined(ENABLE_BUILT_IN_DNS) |
238 const size_t kDefaultMaxEntries = 1000; | 239 const size_t kDefaultMaxEntries = 1000; |
239 #else | 240 #else |
240 const size_t kDefaultMaxEntries = 100; | 241 const size_t kDefaultMaxEntries = 100; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 CACHE_HISTOGRAM_TIME("EraseValid.ValidFor", -stale.expired_by); | 362 CACHE_HISTOGRAM_TIME("EraseValid.ValidFor", -stale.expired_by); |
362 } | 363 } |
363 } | 364 } |
364 | 365 |
365 void HostCache::RecordEraseAll(EraseReason reason, base::TimeTicks now) { | 366 void HostCache::RecordEraseAll(EraseReason reason, base::TimeTicks now) { |
366 for (const auto& it : entries_) | 367 for (const auto& it : entries_) |
367 RecordErase(reason, now, it.second); | 368 RecordErase(reason, now, it.second); |
368 } | 369 } |
369 | 370 |
370 } // namespace net | 371 } // namespace net |
OLD | NEW |