host_cache.h revision ddb351dbec246cf1fab5ec20d2d5520909041de1
1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NET_BASE_HOST_CACHE_H_ 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_BASE_HOST_CACHE_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <map> 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string> 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/gtest_prod_util.h" 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h" 143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/non_thread_safe.h" 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/time.h" 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/address_family.h" 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/address_list.h" 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Cache used by HostResolver to map hostnames to their resolved result. 223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenclass HostCache : public base::NonThreadSafe { 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Stores the latest address list that was looked up for a hostname. 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct Entry : public base::RefCounted<Entry> { 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Entry(int error, const AddressList& addrlist, base::TimeTicks expiration); 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The resolve results for this entry. 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int error; 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddressList addrlist; 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The time when this entry expires. 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeTicks expiration; 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott friend class base::RefCounted<Entry>; 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~Entry(); 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct Key { 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Key(const std::string& hostname, AddressFamily address_family, 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HostResolverFlags host_resolver_flags) 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : hostname(hostname), 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch address_family(address_family), 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch host_resolver_flags(host_resolver_flags) {} 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool operator==(const Key& other) const { 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |address_family| and |host_resolver_flags| are compared before 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |hostname| under assumption that integer comparisons are faster than 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // string comparisons. 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (other.address_family == address_family && 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch other.host_resolver_flags == host_resolver_flags && 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch other.hostname == hostname); 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool operator<(const Key& other) const { 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |address_family| and |host_resolver_flags| are compared before 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |hostname| under assumption that integer comparisons are faster than 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // string comparisons. 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (address_family != other.address_family) 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return address_family < other.address_family; 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (host_resolver_flags != other.host_resolver_flags) 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return host_resolver_flags < other.host_resolver_flags; 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return hostname < other.hostname; 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string hostname; 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddressFamily address_family; 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HostResolverFlags host_resolver_flags; 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef std::map<Key, scoped_refptr<Entry> > EntryMap; 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Constructs a HostCache that caches successful host resolves for 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |success_entry_ttl| time, and failed host resolves for 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |failure_entry_ttl|. The cache will store up to |max_entries|. 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HostCache(size_t max_entries, 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeDelta success_entry_ttl, 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeDelta failure_entry_ttl); 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~HostCache(); 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns a pointer to the entry for |key|, which is valid at time 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |now|. If there is no such entry, returns NULL. 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const Entry* Lookup(const Key& key, base::TimeTicks now) const; 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Overwrites or creates an entry for |key|. Returns the pointer to the 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // entry, or NULL on failure (fails if caching is disabled). 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // (|error|, |addrlist|) is the value to set, and |now| is the current 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // timestamp. 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Entry* Set(const Key& key, 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int error, 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const AddressList& addrlist, 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeTicks now); 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Empties the cache 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void clear(); 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns the number of entries in the cache. 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t size() const; 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Following are used by net_internals UI. 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t max_entries() const; 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::TimeDelta success_entry_ttl() const; 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::TimeDelta failure_entry_ttl() const; 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note that this map may contain expired entries. 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const EntryMap& entries() const; 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FRIEND_TEST_ALL_PREFIXES(HostCacheTest, Compact); 1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FRIEND_TEST_ALL_PREFIXES(HostCacheTest, NoCache); 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if this cache entry's result is valid at time |now|. 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static bool CanUseEntry(const Entry* entry, const base::TimeTicks now); 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Prunes entries from the cache to bring it below max entry bound. Entries 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // matching |pinned_entry| will NOT be pruned. 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Compact(base::TimeTicks now, const Entry* pinned_entry); 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns true if this HostCache can contain no entries. 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool caching_is_disabled() const { 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return max_entries_ == 0; 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Bound on total size of the cache. 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t max_entries_; 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Time to live for cache entries. 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeDelta success_entry_ttl_; 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeDelta failure_entry_ttl_; 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Map from hostname (presumably in lowercase canonicalized format) to 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // a resolved result entry. 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EntryMap entries_; 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(HostCache); 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NET_BASE_HOST_CACHE_H_ 146