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 #ifndef NET_BASE_HOST_CACHE_H_ 6 #define NET_BASE_HOST_CACHE_H_ 7 8 #include <map> 9 #include <string> 10 11 #include "base/ref_counted.h" 12 #include "base/time.h" 13 #include "net/base/address_family.h" 14 #include "net/base/address_list.h" 15 #include "testing/gtest/include/gtest/gtest_prod.h" 16 17 namespace net { 18 19 // Cache used by HostResolver to map hostnames to their resolved result. 20 class HostCache { 21 public: 22 // Stores the latest address list that was looked up for a hostname. 23 struct Entry : public base::RefCounted<Entry> { 24 Entry(int error, const AddressList& addrlist, base::TimeTicks expiration); 25 26 // The resolve results for this entry. 27 int error; 28 AddressList addrlist; 29 30 // The time when this entry expires. 31 base::TimeTicks expiration; 32 33 private: 34 friend class base::RefCounted<Entry>; 35 36 ~Entry(); 37 }; 38 39 struct Key { 40 Key(const std::string& hostname, AddressFamily address_family) 41 : hostname(hostname), address_family(address_family) {} 42 43 bool operator==(const Key& other) const { 44 return other.hostname == hostname && 45 other.address_family == address_family; 46 } 47 48 bool operator<(const Key& other) const { 49 if (address_family == other.address_family) 50 return hostname < other.hostname; 51 return address_family < other.address_family; 52 } 53 54 std::string hostname; 55 AddressFamily address_family; 56 }; 57 58 typedef std::map<Key, scoped_refptr<Entry> > EntryMap; 59 60 // Constructs a HostCache that caches successful host resolves for 61 // |success_entry_ttl| time, and failed host resolves for 62 // |failure_entry_ttl|. The cache will store up to |max_entries|. 63 HostCache(size_t max_entries, 64 base::TimeDelta success_entry_ttl, 65 base::TimeDelta failure_entry_ttl); 66 67 ~HostCache(); 68 69 // Returns a pointer to the entry for |key|, which is valid at time 70 // |now|. If there is no such entry, returns NULL. 71 const Entry* Lookup(const Key& key, base::TimeTicks now) const; 72 73 // Overwrites or creates an entry for |key|. Returns the pointer to the 74 // entry, or NULL on failure (fails if caching is disabled). 75 // (|error|, |addrlist|) is the value to set, and |now| is the current 76 // timestamp. 77 Entry* Set(const Key& key, 78 int error, 79 const AddressList addrlist, 80 base::TimeTicks now); 81 82 // Empties the cache. 83 void clear() { 84 entries_.clear(); 85 } 86 87 // Returns true if this HostCache can contain no entries. 88 bool caching_is_disabled() const { 89 return max_entries_ == 0; 90 } 91 92 // Returns the number of entries in the cache. 93 size_t size() const { 94 return entries_.size(); 95 } 96 97 size_t max_entries() const { 98 return max_entries_; 99 } 100 101 base::TimeDelta success_entry_ttl() const { 102 return success_entry_ttl_; 103 } 104 105 base::TimeDelta failure_entry_ttl() const { 106 return failure_entry_ttl_; 107 } 108 109 // Note that this map may contain expired entries. 110 const EntryMap& entries() const { 111 return entries_; 112 } 113 114 private: 115 FRIEND_TEST(HostCacheTest, Compact); 116 FRIEND_TEST(HostCacheTest, NoCache); 117 118 // Returns true if this cache entry's result is valid at time |now|. 119 static bool CanUseEntry(const Entry* entry, const base::TimeTicks now); 120 121 // Prunes entries from the cache to bring it below max entry bound. Entries 122 // matching |pinned_entry| will NOT be pruned. 123 void Compact(base::TimeTicks now, const Entry* pinned_entry); 124 125 // Bound on total size of the cache. 126 size_t max_entries_; 127 128 // Time to live for cache entries. 129 base::TimeDelta success_entry_ttl_; 130 base::TimeDelta failure_entry_ttl_; 131 132 // Map from hostname (presumably in lowercase canonicalized format) to 133 // a resolved result entry. 134 EntryMap entries_; 135 136 DISALLOW_COPY_AND_ASSIGN(HostCache); 137 }; 138 139 } // namespace net 140 141 #endif // NET_BASE_HOST_CACHE_H_ 142