summaryrefslogtreecommitdiffstats
path: root/chrome/browser/net/referrer.h
blob: 27dd7865cc52dd30140ea15746c9e2c841d3e572 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Copyright (c) 2011 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.

// This class helps to remember what domains may be needed to be resolved when a
// navigation takes place to a given URL.  This information is gathered when a
// navigation to a subresource identifies a referring URL.
// When future navigations take place to known referrer sites, then we
// speculatively either pre-warm a TCP/IP conneciton, or at a minimum, resolve
// the host name via DNS.

// All access to this class is performed via the Predictor class, which only
// operates on the IO thread.

#ifndef CHROME_BROWSER_NET_REFERRER_H_
#define CHROME_BROWSER_NET_REFERRER_H_

#include <map>

#include <stdint.h>

#include "base/macros.h"
#include "base/time/time.h"
#include "net/base/host_port_pair.h"
#include "url/gurl.h"

namespace base {
class Value;
}

namespace chrome_browser_net {

//------------------------------------------------------------------------------
// For each hostname in a Referrer, we have a ReferrerValue.  It indicates
// exactly how much value (re: latency reduction, or connection use) has
// resulted from having this entry.
class ReferrerValue {
 public:
  ReferrerValue();

  // Used during deserialization.
  void SetSubresourceUseRate(double rate) { subresource_use_rate_ = rate; }

  base::Time birth_time() const { return birth_time_; }

  // Record the fact that we navigated to the associated subresource URL.  This
  // will increase the value of the expected subresource_use_rate_
  void SubresourceIsNeeded();

  // Record the fact that the referrer of this subresource was observed. This
  // will diminish the expected subresource_use_rate_ (and will only be
  // counteracted later if we really needed this subresource as a consequence
  // of our associated referrer.)
  void ReferrerWasObserved();

  int64_t navigation_count() const { return navigation_count_; }
  double subresource_use_rate() const { return subresource_use_rate_; }

  int64_t preconnection_count() const { return preconnection_count_; }
  void IncrementPreconnectionCount() { ++preconnection_count_; }

  int64_t preresolution_count() const { return preresolution_count_; }
  void preresolution_increment() { ++preresolution_count_; }

  // Reduce the subresource_use_rate_ by the supplied factor, and return true
  // if the result is still greater than the given threshold.
  bool Trim(double reduce_rate, double threshold);

 private:
  const base::Time birth_time_;

  // The number of times this item was navigated to with the fixed referrer.
  int64_t navigation_count_;

  // The number of times this item was preconnected as a consequence of its
  // referrer.
  int64_t preconnection_count_;

  // The number of times this item was pre-resolved (via DNS) as a consequence
  // of its referrer.
  int64_t preresolution_count_;

  // A smoothed estimate of the expected number of connections that will be made
  // to this subresource.
  double subresource_use_rate_;
};

//------------------------------------------------------------------------------
// A list of domain names to pre-resolve. The names are the keys to this map,
// and the values indicate the amount of benefit derived from having each name
// around.
typedef std::map<GURL, ReferrerValue> SubresourceMap;

//------------------------------------------------------------------------------
// There is one Referrer instance for each hostname that has acted as an HTTP
// referer (note mispelling is intentional) for a hostname that was otherwise
// unexpectedly navgated towards ("unexpected" in the sense that the hostname
// was probably needed as a subresource of a page, and was not otherwise
// predictable until the content with the reference arrived).  Most typically,
// an outer page was a page fetched by the user, and this instance lists names
// in SubresourceMap which are subresources and that were needed to complete the
// rendering of the outer page.
class Referrer : public SubresourceMap {
 public:
  Referrer();
  void IncrementUseCount() { ++use_count_; }
  int64_t use_count() const { return use_count_; }

  // Add the indicated url to the list that are resolved via DNS when the user
  // navigates to this referrer.  Note that if the list is long, an entry may be
  // discarded to make room for this insertion.
  void SuggestHost(const GURL& url);

  // Trim the Referrer, by first diminishing (scaling down) the subresource
  // use expectation for each ReferredValue.
  // Returns true if expected use rate is greater than the threshold.
  bool Trim(double reduce_rate, double threshold);

  // Provide methods for persisting, and restoring contents into a Value class.
  base::Value* Serialize() const;
  void Deserialize(const base::Value& referrers);

 private:
  // Helper function for pruning list.  Metric for usefulness is "large accrued
  // value," in the form of latency_ savings associated with a host name.  We
  // also give credit for a name being newly added, by scalling latency per
  // lifetime (time since birth).  For instance, when two names have accrued
  // the same latency_ savings, the older one is less valuable as it didn't
  // accrue savings as quickly.
  void DeleteLeastUseful();

  // The number of times this referer had its subresources scanned for possible
  // preconnection or DNS preresolution.
  int64_t use_count_;

  // We put these into a std::map<>, so we need copy constructors.
  // DISALLOW_COPY_AND_ASSIGN(Referrer);
  // TODO(jar): Consider optimization to use pointers to these instances, and
  // avoid deep copies during re-alloc of the containing map.
};

}  // namespace chrome_browser_net

#endif  // CHROME_BROWSER_NET_REFERRER_H_