1 // Copyright (c) 2011 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 // This class helps to remember what domains may be needed to be resolved when a 6 // navigation takes place to a given URL. This information is gathered when a 7 // navigation to a subresource identifies a referring URL. 8 // When future navigations take place to known referrer sites, then we 9 // speculatively either pre-warm a TCP/IP conneciton, or at a minimum, resolve 10 // the host name via DNS. 11 12 // All access to this class is performed via the Predictor class, which only 13 // operates on the IO thread. 14 15 #ifndef CHROME_BROWSER_NET_REFERRER_H_ 16 #define CHROME_BROWSER_NET_REFERRER_H_ 17 18 #include <map> 19 20 #include "base/basictypes.h" 21 #include "base/time/time.h" 22 #include "net/base/host_port_pair.h" 23 #include "url/gurl.h" 24 25 namespace base { 26 class Value; 27 } 28 29 namespace chrome_browser_net { 30 31 //------------------------------------------------------------------------------ 32 // For each hostname in a Referrer, we have a ReferrerValue. It indicates 33 // exactly how much value (re: latency reduction, or connection use) has 34 // resulted from having this entry. 35 class ReferrerValue { 36 public: 37 ReferrerValue(); 38 39 // Used during deserialization. 40 void SetSubresourceUseRate(double rate) { subresource_use_rate_ = rate; } 41 42 base::Time birth_time() const { return birth_time_; } 43 44 // Record the fact that we navigated to the associated subresource URL. This 45 // will increase the value of the expected subresource_use_rate_ 46 void SubresourceIsNeeded(); 47 48 // Record the fact that the referrer of this subresource was observed. This 49 // will diminish the expected subresource_use_rate_ (and will only be 50 // counteracted later if we really needed this subresource as a consequence 51 // of our associated referrer.) 52 void ReferrerWasObserved(); 53 54 int64 navigation_count() const { return navigation_count_; } 55 double subresource_use_rate() const { return subresource_use_rate_; } 56 57 int64 preconnection_count() const { return preconnection_count_; } 58 void IncrementPreconnectionCount() { ++preconnection_count_; } 59 60 int64 preresolution_count() const { return preresolution_count_; } 61 void preresolution_increment() { ++preresolution_count_; } 62 63 // Reduce the subresource_use_rate_ by the supplied factor, and return true 64 // if the result is still greater than the given threshold. 65 bool Trim(double reduce_rate, double threshold); 66 67 private: 68 const base::Time birth_time_; 69 70 // The number of times this item was navigated to with the fixed referrer. 71 int64 navigation_count_; 72 73 // The number of times this item was preconnected as a consequence of its 74 // referrer. 75 int64 preconnection_count_; 76 77 // The number of times this item was pre-resolved (via DNS) as a consequence 78 // of its referrer. 79 int64 preresolution_count_; 80 81 // A smoothed estimate of the expected number of connections that will be made 82 // to this subresource. 83 double subresource_use_rate_; 84 }; 85 86 //------------------------------------------------------------------------------ 87 // A list of domain names to pre-resolve. The names are the keys to this map, 88 // and the values indicate the amount of benefit derived from having each name 89 // around. 90 typedef std::map<GURL, ReferrerValue> SubresourceMap; 91 92 //------------------------------------------------------------------------------ 93 // There is one Referrer instance for each hostname that has acted as an HTTP 94 // referer (note mispelling is intentional) for a hostname that was otherwise 95 // unexpectedly navgated towards ("unexpected" in the sense that the hostname 96 // was probably needed as a subresource of a page, and was not otherwise 97 // predictable until the content with the reference arrived). Most typically, 98 // an outer page was a page fetched by the user, and this instance lists names 99 // in SubresourceMap which are subresources and that were needed to complete the 100 // rendering of the outer page. 101 class Referrer : public SubresourceMap { 102 public: 103 Referrer(); 104 void IncrementUseCount() { ++use_count_; } 105 int64 use_count() const { return use_count_; } 106 107 // Add the indicated url to the list that are resolved via DNS when the user 108 // navigates to this referrer. Note that if the list is long, an entry may be 109 // discarded to make room for this insertion. 110 void SuggestHost(const GURL& url); 111 112 // Trim the Referrer, by first diminishing (scaling down) the subresource 113 // use expectation for each ReferredValue. 114 // Returns true if expected use rate is greater than the threshold. 115 bool Trim(double reduce_rate, double threshold); 116 117 // Provide methods for persisting, and restoring contents into a Value class. 118 base::Value* Serialize() const; 119 void Deserialize(const base::Value& referrers); 120 121 private: 122 // Helper function for pruning list. Metric for usefulness is "large accrued 123 // value," in the form of latency_ savings associated with a host name. We 124 // also give credit for a name being newly added, by scalling latency per 125 // lifetime (time since birth). For instance, when two names have accrued 126 // the same latency_ savings, the older one is less valuable as it didn't 127 // accrue savings as quickly. 128 void DeleteLeastUseful(); 129 130 // The number of times this referer had its subresources scanned for possible 131 // preconnection or DNS preresolution. 132 int64 use_count_; 133 134 // We put these into a std::map<>, so we need copy constructors. 135 // DISALLOW_COPY_AND_ASSIGN(Referrer); 136 // TODO(jar): Consider optimization to use pointers to these instances, and 137 // avoid deep copies during re-alloc of the containing map. 138 }; 139 140 } // namespace chrome_browser_net 141 142 #endif // CHROME_BROWSER_NET_REFERRER_H_ 143