| 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 |