| 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 <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 DCHECK(out); | 141 DCHECK(out); |
| 142 out->expired_by = now - expires_; | 142 out->expired_by = now - expires_; |
| 143 out->network_changes = network_changes - network_changes_; | 143 out->network_changes = network_changes - network_changes_; |
| 144 out->stale_hits = stale_hits_; | 144 out->stale_hits = stale_hits_; |
| 145 } | 145 } |
| 146 | 146 |
| 147 HostCache::HostCache(size_t max_entries) | 147 HostCache::HostCache(size_t max_entries) |
| 148 : max_entries_(max_entries), network_changes_(0) {} | 148 : max_entries_(max_entries), network_changes_(0) {} |
| 149 | 149 |
| 150 HostCache::~HostCache() { | 150 HostCache::~HostCache() { |
| 151 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 151 RecordEraseAll(ERASE_DESTRUCT, base::TimeTicks::Now()); | 152 RecordEraseAll(ERASE_DESTRUCT, base::TimeTicks::Now()); |
| 152 } | 153 } |
| 153 | 154 |
| 154 const HostCache::Entry* HostCache::Lookup(const Key& key, | 155 const HostCache::Entry* HostCache::Lookup(const Key& key, |
| 155 base::TimeTicks now) { | 156 base::TimeTicks now) { |
| 156 DCHECK(CalledOnValidThread()); | 157 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 157 if (caching_is_disabled()) | 158 if (caching_is_disabled()) |
| 158 return nullptr; | 159 return nullptr; |
| 159 | 160 |
| 160 HostCache::Entry* entry = LookupInternal(key); | 161 HostCache::Entry* entry = LookupInternal(key); |
| 161 if (!entry) { | 162 if (!entry) { |
| 162 RecordLookup(LOOKUP_MISS_ABSENT, now, nullptr); | 163 RecordLookup(LOOKUP_MISS_ABSENT, now, nullptr); |
| 163 return nullptr; | 164 return nullptr; |
| 164 } | 165 } |
| 165 if (entry->IsStale(now, network_changes_)) { | 166 if (entry->IsStale(now, network_changes_)) { |
| 166 RecordLookup(LOOKUP_MISS_STALE, now, entry); | 167 RecordLookup(LOOKUP_MISS_STALE, now, entry); |
| 167 return nullptr; | 168 return nullptr; |
| 168 } | 169 } |
| 169 | 170 |
| 170 entry->CountHit(/* hit_is_stale= */ false); | 171 entry->CountHit(/* hit_is_stale= */ false); |
| 171 RecordLookup(LOOKUP_HIT_VALID, now, entry); | 172 RecordLookup(LOOKUP_HIT_VALID, now, entry); |
| 172 return entry; | 173 return entry; |
| 173 } | 174 } |
| 174 | 175 |
| 175 const HostCache::Entry* HostCache::LookupStale( | 176 const HostCache::Entry* HostCache::LookupStale( |
| 176 const Key& key, | 177 const Key& key, |
| 177 base::TimeTicks now, | 178 base::TimeTicks now, |
| 178 HostCache::EntryStaleness* stale_out) { | 179 HostCache::EntryStaleness* stale_out) { |
| 179 DCHECK(CalledOnValidThread()); | 180 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 180 if (caching_is_disabled()) | 181 if (caching_is_disabled()) |
| 181 return nullptr; | 182 return nullptr; |
| 182 | 183 |
| 183 HostCache::Entry* entry = LookupInternal(key); | 184 HostCache::Entry* entry = LookupInternal(key); |
| 184 if (!entry) { | 185 if (!entry) { |
| 185 RecordLookup(LOOKUP_MISS_ABSENT, now, nullptr); | 186 RecordLookup(LOOKUP_MISS_ABSENT, now, nullptr); |
| 186 return nullptr; | 187 return nullptr; |
| 187 } | 188 } |
| 188 | 189 |
| 189 bool is_stale = entry->IsStale(now, network_changes_); | 190 bool is_stale = entry->IsStale(now, network_changes_); |
| 190 entry->CountHit(/* hit_is_stale= */ is_stale); | 191 entry->CountHit(/* hit_is_stale= */ is_stale); |
| 191 RecordLookup(is_stale ? LOOKUP_HIT_STALE : LOOKUP_HIT_VALID, now, entry); | 192 RecordLookup(is_stale ? LOOKUP_HIT_STALE : LOOKUP_HIT_VALID, now, entry); |
| 192 | 193 |
| 193 if (stale_out) | 194 if (stale_out) |
| 194 entry->GetStaleness(now, network_changes_, stale_out); | 195 entry->GetStaleness(now, network_changes_, stale_out); |
| 195 return entry; | 196 return entry; |
| 196 } | 197 } |
| 197 | 198 |
| 198 HostCache::Entry* HostCache::LookupInternal(const Key& key) { | 199 HostCache::Entry* HostCache::LookupInternal(const Key& key) { |
| 199 auto it = entries_.find(key); | 200 auto it = entries_.find(key); |
| 200 return (it != entries_.end()) ? &it->second : nullptr; | 201 return (it != entries_.end()) ? &it->second : nullptr; |
| 201 } | 202 } |
| 202 | 203 |
| 203 void HostCache::Set(const Key& key, | 204 void HostCache::Set(const Key& key, |
| 204 const Entry& entry, | 205 const Entry& entry, |
| 205 base::TimeTicks now, | 206 base::TimeTicks now, |
| 206 base::TimeDelta ttl) { | 207 base::TimeDelta ttl) { |
| 207 TRACE_EVENT0(kNetTracingCategory, "HostCache::Set"); | 208 TRACE_EVENT0(kNetTracingCategory, "HostCache::Set"); |
| 208 DCHECK(CalledOnValidThread()); | 209 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 209 if (caching_is_disabled()) | 210 if (caching_is_disabled()) |
| 210 return; | 211 return; |
| 211 | 212 |
| 212 auto it = entries_.find(key); | 213 auto it = entries_.find(key); |
| 213 if (it != entries_.end()) { | 214 if (it != entries_.end()) { |
| 214 bool is_stale = it->second.IsStale(now, network_changes_); | 215 bool is_stale = it->second.IsStale(now, network_changes_); |
| 215 RecordSet(is_stale ? SET_UPDATE_STALE : SET_UPDATE_VALID, now, &it->second, | 216 RecordSet(is_stale ? SET_UPDATE_STALE : SET_UPDATE_VALID, now, &it->second, |
| 216 entry); | 217 entry); |
| 217 // TODO(juliatuttle): Remember some old metadata (hit count or frequency or | 218 // TODO(juliatuttle): Remember some old metadata (hit count or frequency or |
| 218 // something like that) if it's useful for better eviction algorithms? | 219 // something like that) if it's useful for better eviction algorithms? |
| (...skipping 12 matching lines...) Expand all Loading... |
| 231 DCHECK_EQ(0u, entries_.count(key)); | 232 DCHECK_EQ(0u, entries_.count(key)); |
| 232 entries_.insert(std::make_pair(key, entry)); | 233 entries_.insert(std::make_pair(key, entry)); |
| 233 DCHECK_GE(max_entries_, size()); | 234 DCHECK_GE(max_entries_, size()); |
| 234 } | 235 } |
| 235 | 236 |
| 236 void HostCache::OnNetworkChange() { | 237 void HostCache::OnNetworkChange() { |
| 237 ++network_changes_; | 238 ++network_changes_; |
| 238 } | 239 } |
| 239 | 240 |
| 240 void HostCache::clear() { | 241 void HostCache::clear() { |
| 241 DCHECK(CalledOnValidThread()); | 242 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 242 RecordEraseAll(ERASE_CLEAR, base::TimeTicks::Now()); | 243 RecordEraseAll(ERASE_CLEAR, base::TimeTicks::Now()); |
| 243 entries_.clear(); | 244 entries_.clear(); |
| 244 } | 245 } |
| 245 | 246 |
| 246 void HostCache::ClearForHosts( | 247 void HostCache::ClearForHosts( |
| 247 const base::Callback<bool(const std::string&)>& host_filter) { | 248 const base::Callback<bool(const std::string&)>& host_filter) { |
| 248 DCHECK(CalledOnValidThread()); | 249 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 249 | 250 |
| 250 if (host_filter.is_null()) { | 251 if (host_filter.is_null()) { |
| 251 clear(); | 252 clear(); |
| 252 return; | 253 return; |
| 253 } | 254 } |
| 254 | 255 |
| 255 base::TimeTicks now = base::TimeTicks::Now(); | 256 base::TimeTicks now = base::TimeTicks::Now(); |
| 256 for (EntryMap::iterator it = entries_.begin(); it != entries_.end();) { | 257 for (EntryMap::iterator it = entries_.begin(); it != entries_.end();) { |
| 257 EntryMap::iterator next_it = std::next(it); | 258 EntryMap::iterator next_it = std::next(it); |
| 258 | 259 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 auto found = entries_.find(key); | 364 auto found = entries_.find(key); |
| 364 if (found == entries_.end() && size() < max_entries_) { | 365 if (found == entries_.end() && size() < max_entries_) { |
| 365 AddEntry(key, Entry(error, address_list, expiration_time, | 366 AddEntry(key, Entry(error, address_list, expiration_time, |
| 366 network_changes_ - 1)); | 367 network_changes_ - 1)); |
| 367 } | 368 } |
| 368 } | 369 } |
| 369 return true; | 370 return true; |
| 370 } | 371 } |
| 371 | 372 |
| 372 size_t HostCache::size() const { | 373 size_t HostCache::size() const { |
| 373 DCHECK(CalledOnValidThread()); | 374 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 374 return entries_.size(); | 375 return entries_.size(); |
| 375 } | 376 } |
| 376 | 377 |
| 377 size_t HostCache::max_entries() const { | 378 size_t HostCache::max_entries() const { |
| 378 DCHECK(CalledOnValidThread()); | 379 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 379 return max_entries_; | 380 return max_entries_; |
| 380 } | 381 } |
| 381 | 382 |
| 382 // static | 383 // static |
| 383 std::unique_ptr<HostCache> HostCache::CreateDefaultCache() { | 384 std::unique_ptr<HostCache> HostCache::CreateDefaultCache() { |
| 384 // Cache capacity is determined by the field trial. | 385 // Cache capacity is determined by the field trial. |
| 385 #if defined(ENABLE_BUILT_IN_DNS) | 386 #if defined(ENABLE_BUILT_IN_DNS) |
| 386 const size_t kDefaultMaxEntries = 1000; | 387 const size_t kDefaultMaxEntries = 1000; |
| 387 #else | 388 #else |
| 388 const size_t kDefaultMaxEntries = 100; | 389 const size_t kDefaultMaxEntries = 100; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 CACHE_HISTOGRAM_TIME("EraseValid.ValidFor", -stale.expired_by); | 510 CACHE_HISTOGRAM_TIME("EraseValid.ValidFor", -stale.expired_by); |
| 510 } | 511 } |
| 511 } | 512 } |
| 512 | 513 |
| 513 void HostCache::RecordEraseAll(EraseReason reason, base::TimeTicks now) { | 514 void HostCache::RecordEraseAll(EraseReason reason, base::TimeTicks now) { |
| 514 for (const auto& it : entries_) | 515 for (const auto& it : entries_) |
| 515 RecordErase(reason, now, it.second); | 516 RecordErase(reason, now, it.second); |
| 516 } | 517 } |
| 517 | 518 |
| 518 } // namespace net | 519 } // namespace net |
| OLD | NEW |