summaryrefslogtreecommitdiffstats
path: root/net/base/host_cache.cc
diff options
context:
space:
mode:
authorfischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-24 23:04:05 +0000
committerfischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-24 23:04:05 +0000
commite388313b2b6ffb83e7a21bcd187fed5dad9a125e (patch)
treee4e51894211779324f03f7191e649ba9b87857d7 /net/base/host_cache.cc
parent5c47775ab01603c6884eca0acdf867beda1f2c38 (diff)
downloadchromium_src-e388313b2b6ffb83e7a21bcd187fed5dad9a125e.zip
chromium_src-e388313b2b6ffb83e7a21bcd187fed5dad9a125e.tar.gz
chromium_src-e388313b2b6ffb83e7a21bcd187fed5dad9a125e.tar.bz2
Revert 123565 - Broke the "ASAN Tests (1)" bot: http://build.chromium.org/p/chromium.memory/buildstatus?builder=ASAN%20Tests%20%281%29&number=6260
Have the HostCache and CertVerifier cache use the common ExpiringCache. BUG=114343 TEST=net_unittests:CertVerifier*, net_unittests:HostCache* Review URL: http://codereview.chromium.org/9436003 TBR=rsleevi@chromium.org Review URL: https://chromiumcodereview.appspot.com/9463028 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@123571 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/host_cache.cc')
-rw-r--r--net/base/host_cache.cc95
1 files changed, 80 insertions, 15 deletions
diff --git a/net/base/host_cache.cc b/net/base/host_cache.cc
index 352513b..731e5f5 100644
--- a/net/base/host_cache.cc
+++ b/net/base/host_cache.cc
@@ -11,9 +11,10 @@ namespace net {
//-----------------------------------------------------------------------------
-HostCache::Entry::Entry(int error, const AddressList& addrlist)
- : error(error),
- addrlist(addrlist) {
+HostCache::Entry::Entry(int error,
+ const AddressList& addrlist,
+ base::TimeTicks expiration)
+ : error(error), addrlist(addrlist), expiration(expiration) {
}
HostCache::Entry::~Entry() {
@@ -22,36 +23,63 @@ HostCache::Entry::~Entry() {
//-----------------------------------------------------------------------------
HostCache::HostCache(size_t max_entries)
- : entries_(max_entries) {
+ : max_entries_(max_entries) {
}
HostCache::~HostCache() {
}
const HostCache::Entry* HostCache::Lookup(const Key& key,
- base::TimeTicks now) {
+ base::TimeTicks now) const {
DCHECK(CalledOnValidThread());
if (caching_is_disabled())
return NULL;
- return entries_.Get(key, now);
+ EntryMap::const_iterator it = entries_.find(key);
+ if (it == entries_.end())
+ return NULL; // Not found.
+
+ Entry* entry = it->second.get();
+ if (CanUseEntry(entry, now))
+ return entry;
+
+ return NULL;
}
-void HostCache::Set(const Key& key,
- int error,
- const AddressList& addrlist,
- base::TimeTicks now,
- base::TimeDelta ttl) {
+HostCache::Entry* HostCache::Set(const Key& key,
+ int error,
+ const AddressList& addrlist,
+ base::TimeTicks now,
+ base::TimeDelta ttl) {
DCHECK(CalledOnValidThread());
if (caching_is_disabled())
- return;
+ return NULL;
- entries_.Put(key, Entry(error, addrlist), now, ttl);
+ base::TimeTicks expiration = now + ttl;
+
+ scoped_refptr<Entry>& entry = entries_[key];
+ if (!entry) {
+ // Entry didn't exist, creating one now.
+ Entry* ptr = new Entry(error, addrlist, expiration);
+ entry = ptr;
+
+ // Compact the cache if we grew it beyond limit -- exclude |entry| from
+ // being pruned though!
+ if (entries_.size() > max_entries_)
+ Compact(now, ptr);
+ return ptr;
+ } else {
+ // Update an existing cache entry.
+ entry->error = error;
+ entry->addrlist = addrlist;
+ entry->expiration = expiration;
+ return entry.get();
+ }
}
void HostCache::clear() {
DCHECK(CalledOnValidThread());
- entries_.Clear();
+ entries_.clear();
}
size_t HostCache::size() const {
@@ -61,7 +89,7 @@ size_t HostCache::size() const {
size_t HostCache::max_entries() const {
DCHECK(CalledOnValidThread());
- return entries_.max_entries();
+ return max_entries_;
}
// Note that this map may contain expired entries.
@@ -71,9 +99,46 @@ const HostCache::EntryMap& HostCache::entries() const {
}
// static
+bool HostCache::CanUseEntry(const Entry* entry, const base::TimeTicks now) {
+ return entry->expiration > now;
+}
+
+// static
HostCache* HostCache::CreateDefaultCache() {
static const size_t kMaxHostCacheEntries = 100;
return new HostCache(kMaxHostCacheEntries);
}
+void HostCache::Compact(base::TimeTicks now, const Entry* pinned_entry) {
+ // Clear out expired entries.
+ for (EntryMap::iterator it = entries_.begin(); it != entries_.end(); ) {
+ Entry* entry = (it->second).get();
+ if (entry != pinned_entry && !CanUseEntry(entry, now)) {
+ entries_.erase(it++);
+ } else {
+ ++it;
+ }
+ }
+
+ if (entries_.size() <= max_entries_)
+ return;
+
+ // If we still have too many entries, start removing unexpired entries
+ // at random.
+ // TODO(eroman): this eviction policy could be better (access count FIFO
+ // or whatever).
+ for (EntryMap::iterator it = entries_.begin();
+ it != entries_.end() && entries_.size() > max_entries_; ) {
+ Entry* entry = (it->second).get();
+ if (entry != pinned_entry) {
+ entries_.erase(it++);
+ } else {
+ ++it;
+ }
+ }
+
+ if (entries_.size() > max_entries_)
+ DLOG(WARNING) << "Still above max entries limit";
+}
+
} // namespace net