// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "net/dns/host_cache.h" #include "base/logging.h" #include "base/metrics/field_trial.h" #include "base/metrics/histogram.h" #include "base/string_number_conversions.h" #include "net/base/net_errors.h" namespace net { //----------------------------------------------------------------------------- HostCache::Entry::Entry(int error, const AddressList& addrlist, base::TimeDelta ttl) : error(error), addrlist(addrlist), ttl(ttl) { DCHECK(ttl >= base::TimeDelta()); } HostCache::Entry::Entry(int error, const AddressList& addrlist) : error(error), addrlist(addrlist), ttl(base::TimeDelta::FromSeconds(-1)) { } HostCache::Entry::~Entry() { } //----------------------------------------------------------------------------- HostCache::HostCache(size_t max_entries) : entries_(max_entries) { } HostCache::~HostCache() { } const HostCache::Entry* HostCache::Lookup(const Key& key, base::TimeTicks now) { DCHECK(CalledOnValidThread()); if (caching_is_disabled()) return NULL; return entries_.Get(key, now); } void HostCache::Set(const Key& key, const Entry& entry, base::TimeTicks now, base::TimeDelta ttl) { DCHECK(CalledOnValidThread()); if (caching_is_disabled()) return; entries_.Put(key, entry, now, now + ttl); } void HostCache::clear() { DCHECK(CalledOnValidThread()); entries_.Clear(); } size_t HostCache::size() const { DCHECK(CalledOnValidThread()); return entries_.size(); } size_t HostCache::max_entries() const { DCHECK(CalledOnValidThread()); return entries_.max_entries(); } // Note that this map may contain expired entries. const HostCache::EntryMap& HostCache::entries() const { DCHECK(CalledOnValidThread()); return entries_; } // static scoped_ptr HostCache::CreateDefaultCache() { // Cache capacity is determined by the field trial. #if defined(ENABLE_BUILT_IN_DNS) const size_t kDefaultMaxEntries = 1000; #else const size_t kDefaultMaxEntries = 100; #endif const size_t kSaneMaxEntries = 1 << 20; size_t max_entries = 0; base::StringToSizeT(base::FieldTrialList::FindFullName("HostCacheSize"), &max_entries); if ((max_entries == 0) || (max_entries > kSaneMaxEntries)) max_entries = kDefaultMaxEntries; return make_scoped_ptr(new HostCache(max_entries)); } void HostCache::EvictionHandler::Handle( const Key& key, const Entry& entry, const base::TimeTicks& expiration, const base::TimeTicks& now, bool on_get) const { if (on_get) { DCHECK(now >= expiration); UMA_HISTOGRAM_CUSTOM_TIMES("DNS.CacheExpiredOnGet", now - expiration, base::TimeDelta::FromSeconds(1), base::TimeDelta::FromDays(1), 100); return; } if (expiration > now) { UMA_HISTOGRAM_CUSTOM_TIMES("DNS.CacheEvicted", expiration - now, base::TimeDelta::FromSeconds(1), base::TimeDelta::FromDays(1), 100); } else { UMA_HISTOGRAM_CUSTOM_TIMES("DNS.CacheExpired", now - expiration, base::TimeDelta::FromSeconds(1), base::TimeDelta::FromDays(1), 100); } } } // namespace net