Home | History | Annotate | Download | only in net
      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