Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: net/base/host_cache.cc

Issue 118100: Avoid doing concurrent DNS resolves of the same hostname (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Get compiling on mac Created 11 years, 6 months 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 | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/base/host_cache.h"
6
7 #include "base/logging.h"
8 #include "net/base/net_errors.h"
9
10 namespace net {
11
12 //-----------------------------------------------------------------------------
13
14 HostCache::Entry::Entry(int error,
15 const AddressList& addrlist,
16 base::TimeTicks expiration)
17 : error(error), addrlist(addrlist), expiration(expiration) {
18 }
19
20 HostCache::Entry::~Entry() {
21 }
22
23 //-----------------------------------------------------------------------------
24
25 HostCache::HostCache(size_t max_entries, size_t cache_duration_ms)
26 : max_entries_(max_entries), cache_duration_ms_(cache_duration_ms) {
27 }
28
29 HostCache::~HostCache() {
30 }
31
32 const HostCache::Entry* HostCache::Lookup(const std::string& hostname,
33 base::TimeTicks now) const {
34 if (caching_is_disabled())
35 return NULL;
36
37 EntryMap::const_iterator it = entries_.find(hostname);
38 if (it == entries_.end())
39 return NULL; // Not found.
40
41 Entry* entry = it->second.get();
42 if (CanUseEntry(entry, now))
43 return entry;
44
45 return NULL;
46 }
47
48 HostCache::Entry* HostCache::Set(const std::string& hostname,
49 int error,
50 const AddressList addrlist,
51 base::TimeTicks now) {
52 if (caching_is_disabled())
53 return NULL;
54
55 base::TimeTicks expiration = now +
56 base::TimeDelta::FromMilliseconds(cache_duration_ms_);
57
58 scoped_refptr<Entry>& entry = entries_[hostname];
59 if (!entry) {
60 // Entry didn't exist, creating one now.
61 Entry* ptr = new Entry(error, addrlist, expiration);
62 entry = ptr;
63
64 // Compact the cache if we grew it beyond limit -- exclude |entry| from
65 // being pruned though!
66 if (entries_.size() > max_entries_)
67 Compact(now, ptr);
68 return ptr;
69 } else {
70 // Update an existing cache entry.
71 entry->error = error;
72 entry->addrlist = addrlist;
73 entry->expiration = expiration;
74 return entry.get();
75 }
76 }
77
78 // static
79 bool HostCache::CanUseEntry(const Entry* entry, const base::TimeTicks now) {
80 return entry->error == OK && entry->expiration > now;
81 }
82
83 void HostCache::Compact(base::TimeTicks now, const Entry* pinned_entry) {
84 // Clear out expired entries.
85 for (EntryMap::iterator it = entries_.begin(); it != entries_.end(); ) {
86 Entry* entry = (it->second).get();
87 if (entry != pinned_entry && !CanUseEntry(entry, now)) {
88 entries_.erase(it++);
89 } else {
90 ++it;
91 }
92 }
93
94 if (entries_.size() <= max_entries_)
95 return;
96
97 // If we still have too many entries, start removing unexpired entries
98 // at random.
99 // TODO(eroman): this eviction policy could be better (access count FIFO
100 // or whatever).
101 for (EntryMap::iterator it = entries_.begin();
102 it != entries_.end() && entries_.size() > max_entries_; ) {
103 Entry* entry = (it->second).get();
104 if (entry != pinned_entry) {
105 entries_.erase(it++);
106 } else {
107 ++it;
108 }
109 }
110
111 if (entries_.size() > max_entries_)
112 DLOG(WARNING) << "Still above max entries limit";
113 }
114
115 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698