OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // A Predictor object is instantiated once in the browser process, and manages | 5 // A Predictor object is instantiated once in the browser process, and manages |
6 // both preresolution of hostnames, as well as TCP/IP preconnection to expected | 6 // both preresolution of hostnames, as well as TCP/IP preconnection to expected |
7 // subresources. | 7 // subresources. |
8 // Most hostname lists are provided by the renderer processes, and include URLs | 8 // Most hostname lists are provided by the renderer processes, and include URLs |
9 // that *might* be used in the near future by the browsing user. One goal of | 9 // that *might* be used in the near future by the browsing user. One goal of |
10 // this class is to cause the underlying DNS structure to lookup a hostname | 10 // this class is to cause the underlying DNS structure to lookup a hostname |
11 // before it is really needed, and hence reduce latency in the standard lookup | 11 // before it is really needed, and hence reduce latency in the standard lookup |
12 // paths. | 12 // paths. |
13 // Subresource relationships are usually acquired from the referrer field in a | 13 // Subresource relationships are usually acquired from the referrer field in a |
14 // navigation. A subresource URL may be associated with a referrer URL. Later | 14 // navigation. A subresource URL may be associated with a referrer URL. Later |
15 // navigations may, if the likelihood of needing the subresource is high enough, | 15 // navigations may, if the likelihood of needing the subresource is high enough, |
16 // cause this module to speculatively create a TCP/IP connection. If there is | 16 // cause this module to speculatively create a TCP/IP connection. If there is |
17 // only a low likelihood, then a DNS pre-resolution operation may be performed. | 17 // only a low likelihood, then a DNS pre-resolution operation may be performed. |
18 | 18 |
19 #ifndef CHROME_BROWSER_NET_PREDICTOR_H_ | 19 #ifndef CHROME_BROWSER_NET_PREDICTOR_H_ |
20 #define CHROME_BROWSER_NET_PREDICTOR_H_ | 20 #define CHROME_BROWSER_NET_PREDICTOR_H_ |
21 #pragma once | 21 #pragma once |
22 | 22 |
23 #include <map> | 23 #include <map> |
24 #include <queue> | 24 #include <queue> |
25 #include <set> | 25 #include <set> |
26 #include <string> | 26 #include <string> |
27 #include <vector> | 27 #include <vector> |
28 | 28 |
29 #include "base/gtest_prod_util.h" | 29 #include "base/gtest_prod_util.h" |
30 #include "base/memory/ref_counted.h" | 30 #include "base/memory/scoped_ptr.h" |
31 #include "chrome/browser/net/url_info.h" | 31 #include "chrome/browser/net/url_info.h" |
32 #include "chrome/browser/net/referrer.h" | 32 #include "chrome/browser/net/referrer.h" |
33 #include "chrome/common/net/predictor_common.h" | 33 #include "chrome/common/net/predictor_common.h" |
34 #include "net/base/host_port_pair.h" | 34 #include "net/base/host_port_pair.h" |
35 | 35 |
36 namespace base { | 36 namespace base { |
37 class ListValue; | 37 class ListValue; |
38 } | 38 } |
39 | 39 |
| 40 namespace base { |
| 41 class WaitableEvent; |
| 42 } |
| 43 |
40 namespace net { | 44 namespace net { |
41 class HostResolver; | 45 class HostResolver; |
42 } // namespace net | 46 } // namespace net |
43 | 47 |
| 48 class IOThread; |
| 49 class PrefService; |
| 50 class Profile; |
| 51 |
44 namespace chrome_browser_net { | 52 namespace chrome_browser_net { |
45 | 53 |
46 typedef chrome_common_net::UrlList UrlList; | 54 typedef chrome_common_net::UrlList UrlList; |
47 typedef chrome_common_net::NameList NameList; | 55 typedef chrome_common_net::NameList NameList; |
48 typedef std::map<GURL, UrlInfo> Results; | 56 typedef std::map<GURL, UrlInfo> Results; |
49 | 57 |
50 // Note that Predictor is not thread safe, and must only be called from | 58 // Predictor is constructed during Profile construction (on the UI thread), |
51 // the IO thread. Failure to do so will result in a DCHECK at runtime. | 59 // but it is destroyed on the IO thread when ProfileIOData goes away. All of |
52 class Predictor : public base::RefCountedThreadSafe<Predictor> { | 60 // its core state and functionality happens on the IO thread. The only UI |
| 61 // methods are initialization / shutdown related (including preconnect |
| 62 // initialization), or convenience methods that internally forward calls to |
| 63 // the IO thread. |
| 64 class Predictor { |
53 public: | 65 public: |
54 // A version number for prefs that are saved. This should be incremented when | 66 // A version number for prefs that are saved. This should be incremented when |
55 // we change the format so that we discard old data. | 67 // we change the format so that we discard old data. |
56 static const int kPredictorReferrerVersion; | 68 static const int kPredictorReferrerVersion; |
57 | 69 |
| 70 // Given that the underlying Chromium resolver defaults to a total maximum of |
| 71 // 8 paralell resolutions, we will avoid any chance of starving navigational |
| 72 // resolutions by limiting the number of paralell speculative resolutions. |
| 73 // This is used in the field trials and testing. |
| 74 // TODO(jar): Move this limitation into the resolver. |
| 75 static const size_t kMaxSpeculativeParallelResolves; |
| 76 |
| 77 // To control the congestion avoidance system, we need an estimate of how |
| 78 // many speculative requests may arrive at once. Since we currently only |
| 79 // keep 8 subresource names for each frame, we'll use that as our basis. |
| 80 // Note that when scanning search results lists, we might actually get 10 at |
| 81 // a time, and wikipedia can often supply (during a page scan) upwards of 50. |
| 82 // In those odd cases, we may discard some of the later speculative requests |
| 83 // mistakenly assuming that the resolutions took too long. |
| 84 static const int kTypicalSpeculativeGroupSize; |
| 85 |
| 86 // The next constant specifies an amount of queueing delay that is |
| 87 // "too large," and indicative of problems with resolutions (perhaps due to |
| 88 // an overloaded router, or such). When we exceed this delay, congestion |
| 89 // avoidance will kick in and all speculations in the queue will be discarded. |
| 90 static const int kMaxSpeculativeResolveQueueDelayMs; |
| 91 |
58 // |max_concurrent| specifies how many concurrent (parallel) prefetches will | 92 // |max_concurrent| specifies how many concurrent (parallel) prefetches will |
59 // be performed. Host lookups will be issued through |host_resolver|. | 93 // be performed. Host lookups will be issued through |host_resolver|. |
60 Predictor(net::HostResolver* host_resolver, | 94 explicit Predictor(bool preconnect_enabled); |
61 base::TimeDelta max_queue_delay_ms, size_t max_concurrent, | 95 |
62 bool preconnect_enabled); | 96 virtual ~Predictor(); |
| 97 |
| 98 // This function is used to create a predictor. For testing, we can create |
| 99 // a version which does a simpler shutdown. |
| 100 static Predictor* CreatePredictor(bool preconnect_enabled, |
| 101 bool simple_shutdown); |
| 102 |
| 103 static void RegisterUserPrefs(PrefService* user_prefs); |
| 104 |
| 105 // ------------- Start UI thread methods. |
| 106 |
| 107 virtual void InitNetworkPredictor(PrefService* user_prefs, |
| 108 PrefService* local_state, |
| 109 IOThread* io_thread); |
| 110 |
| 111 // The Omnibox has proposed a given url to the user, and if it is a search |
| 112 // URL, then it also indicates that this is preconnectable (i.e., we could |
| 113 // preconnect to the search server). |
| 114 void AnticipateOmniboxUrl(const GURL& url, bool preconnectable); |
| 115 |
| 116 // Preconnect a URL and all of its subresource domains. |
| 117 void PreconnectUrlAndSubresources(const GURL& url); |
| 118 |
| 119 static UrlList GetPredictedUrlListAtStartup(PrefService* user_prefs, |
| 120 PrefService* local_state); |
| 121 |
| 122 static void set_max_queueing_delay(int max_queueing_delay_ms); |
| 123 |
| 124 static void set_max_parallel_resolves(size_t max_parallel_resolves); |
| 125 |
| 126 virtual void ShutdownOnUIThread(PrefService* user_prefs); |
| 127 |
| 128 // ------------- End UI thread methods. |
| 129 |
| 130 // ------------- Start IO thread methods. |
63 | 131 |
64 // Cancel pending requests and prevent new ones from being made. | 132 // Cancel pending requests and prevent new ones from being made. |
65 void Shutdown(); | 133 void Shutdown(); |
66 | 134 |
67 // In some circumstances, for privacy reasons, all results should be | 135 // In some circumstances, for privacy reasons, all results should be |
68 // discarded. This method gracefully handles that activity. | 136 // discarded. This method gracefully handles that activity. |
69 // Destroy all our internal state, which shows what names we've looked up, and | 137 // Destroy all our internal state, which shows what names we've looked up, and |
70 // how long each has taken, etc. etc. We also destroy records of suggesses | 138 // how long each has taken, etc. etc. We also destroy records of suggesses |
71 // (cache hits etc.). | 139 // (cache hits etc.). |
72 void DiscardAllResults(); | 140 void DiscardAllResults(); |
73 | 141 |
74 // Add hostname(s) to the queue for processing. | 142 // Add hostname(s) to the queue for processing. |
75 void ResolveList(const UrlList& urls, | 143 void ResolveList(const UrlList& urls, |
76 UrlInfo::ResolutionMotivation motivation); | 144 UrlInfo::ResolutionMotivation motivation); |
77 void Resolve(const GURL& url, | |
78 UrlInfo::ResolutionMotivation motivation); | |
79 | 145 |
80 // Instigate pre-connection to any URLs, or pre-resolution of related host, | 146 void Resolve(const GURL& url, UrlInfo::ResolutionMotivation motivation); |
81 // that we predict will be needed after this navigation (typically | |
82 // more-embedded resources on a page). This method will actually post a task | |
83 // to do the actual work, so as not to jump ahead of the frame navigation that | |
84 // instigated this activity. | |
85 void PredictFrameSubresources(const GURL& url); | |
86 | |
87 // The Omnibox has proposed a given url to the user, and if it is a search | |
88 // URL, then it also indicates that this is preconnectable (i.e., we could | |
89 // preconnect to the search server). | |
90 void AnticipateOmniboxUrl(const GURL& url, bool preconnectable); | |
91 | |
92 // Preconnect a URL and all of its subresource domains. | |
93 void PreconnectUrlAndSubresources(const GURL& url); | |
94 | 147 |
95 // Record details of a navigation so that we can preresolve the host name | 148 // Record details of a navigation so that we can preresolve the host name |
96 // ahead of time the next time the users navigates to the indicated host. | 149 // ahead of time the next time the users navigates to the indicated host. |
97 // Should only be called when urls are distinct, and they should already be | 150 // Should only be called when urls are distinct, and they should already be |
98 // canonicalized to not have a path. | 151 // canonicalized to not have a path. |
99 void LearnFromNavigation(const GURL& referring_url, const GURL& target_url); | 152 void LearnFromNavigation(const GURL& referring_url, const GURL& target_url); |
100 | 153 |
| 154 // When displaying info in about:dns, the following API is called. |
| 155 static void PredictorGetHtmlInfo(Predictor* predictor, std::string* output); |
| 156 |
101 // Dump HTML table containing list of referrers for about:dns. | 157 // Dump HTML table containing list of referrers for about:dns. |
102 void GetHtmlReferrerLists(std::string* output); | 158 void GetHtmlReferrerLists(std::string* output); |
103 | 159 |
104 // Dump the list of currently known referrer domains and related prefetchable | 160 // Dump the list of currently known referrer domains and related prefetchable |
105 // domains. | 161 // domains for about:dns. |
106 void GetHtmlInfo(std::string* output); | 162 void GetHtmlInfo(std::string* output); |
107 | 163 |
108 // Discards any referrer for which all the suggested host names are currently | 164 // Discards any referrer for which all the suggested host names are currently |
109 // annotated with negligible expected-use. Scales down (diminishes) the | 165 // annotated with negligible expected-use. Scales down (diminishes) the |
110 // expected-use of those that remain, so that their use will go down by a | 166 // expected-use of those that remain, so that their use will go down by a |
111 // factor each time we trim (moving the referrer closer to being discarded in | 167 // factor each time we trim (moving the referrer closer to being discarded in |
112 // a future call). | 168 // a future call). |
113 // The task is performed synchronously and completes before returing. | 169 // The task is performed synchronously and completes before returing. |
114 void TrimReferrersNow(); | 170 void TrimReferrersNow(); |
115 | 171 |
116 // Construct a ListValue object that contains all the data in the referrers_ | 172 // Construct a ListValue object that contains all the data in the referrers_ |
117 // so that it can be persisted in a pref. | 173 // so that it can be persisted in a pref. |
118 void SerializeReferrers(base::ListValue* referral_list); | 174 void SerializeReferrers(base::ListValue* referral_list); |
119 | 175 |
120 // Process a ListValue that contains all the data from a previous reference | 176 // Process a ListValue that contains all the data from a previous reference |
121 // list, as constructed by SerializeReferrers(), and add all the identified | 177 // list, as constructed by SerializeReferrers(), and add all the identified |
122 // values into the current referrer list. | 178 // values into the current referrer list. |
123 void DeserializeReferrers(const base::ListValue& referral_list); | 179 void DeserializeReferrers(const base::ListValue& referral_list); |
124 | 180 |
125 void DeserializeReferrersThenDelete(base::ListValue* referral_list); | 181 void DeserializeReferrersThenDelete(base::ListValue* referral_list); |
126 | 182 |
127 // For unit test code only. | 183 void DiscardInitialNavigationHistory(); |
128 size_t max_concurrent_dns_lookups() const { | |
129 return max_concurrent_dns_lookups_; | |
130 } | |
131 | 184 |
132 // Flag setting to use preconnection instead of just DNS pre-fetching. | 185 void FinalizeInitializationOnIOThread( |
133 bool preconnect_enabled() const { return preconnect_enabled_; } | 186 const std::vector<GURL>& urls_to_prefetch, |
| 187 base::ListValue* referral_list, |
| 188 IOThread* io_thread, |
| 189 bool predictor_enabled); |
| 190 |
| 191 // During startup, we learn what the first N urls visited are, and then |
| 192 // resolve the associated hosts ASAP during our next startup. |
| 193 void LearnAboutInitialNavigation(const GURL& url); |
| 194 |
| 195 // Renderer bundles up list and sends to this browser API via IPC. |
| 196 // TODO(jar): Use UrlList instead to include port and scheme. |
| 197 void DnsPrefetchList(const NameList& hostnames); |
| 198 |
| 199 // May be called from either the IO or UI thread and will PostTask |
| 200 // to the IO thread if necessary. |
| 201 void DnsPrefetchMotivatedList(const UrlList& urls, |
| 202 UrlInfo::ResolutionMotivation motivation); |
| 203 |
| 204 // May be called from either the IO or UI thread and will PostTask |
| 205 // to the IO thread if necessary. |
| 206 void SaveStateForNextStartupAndTrim(PrefService* prefs); |
| 207 |
| 208 void SaveDnsPrefetchStateForNextStartupAndTrim( |
| 209 base::ListValue* startup_list, |
| 210 base::ListValue* referral_list, |
| 211 base::WaitableEvent* completion); |
| 212 |
| 213 // May be called from either the IO or UI thread and will PostTask |
| 214 // to the IO thread if necessary. |
| 215 void EnablePredictor(bool enable); |
| 216 |
| 217 void EnablePredictorOnIOThread(bool enable); |
| 218 |
| 219 // ------------- End IO thread methods. |
| 220 |
| 221 // The following methods may be called on either the IO or UI threads. |
| 222 |
| 223 // Instigate pre-connection to any URLs, or pre-resolution of related host, |
| 224 // that we predict will be needed after this navigation (typically |
| 225 // more-embedded resources on a page). This method will actually post a task |
| 226 // to do the actual work, so as not to jump ahead of the frame navigation that |
| 227 // instigated this activity. |
| 228 void PredictFrameSubresources(const GURL& url); |
134 | 229 |
135 // Put URL in canonical form, including a scheme, host, and port. | 230 // Put URL in canonical form, including a scheme, host, and port. |
136 // Returns GURL::EmptyGURL() if the scheme is not http/https or if the url | 231 // Returns GURL::EmptyGURL() if the scheme is not http/https or if the url |
137 // cannot be otherwise canonicalized. | 232 // cannot be otherwise canonicalized. |
138 static GURL CanonicalizeUrl(const GURL& url); | 233 static GURL CanonicalizeUrl(const GURL& url); |
139 | 234 |
| 235 // Used for testing. |
| 236 void SetHostResolver(net::HostResolver* host_resolver) { |
| 237 host_resolver_ = host_resolver; |
| 238 } |
| 239 // Used for testing. |
| 240 size_t max_concurrent_dns_lookups() const { |
| 241 return max_concurrent_dns_lookups_; |
| 242 } |
| 243 // Used for testing. |
| 244 void SetShutdown(bool shutdown) { |
| 245 shutdown_ = shutdown; |
| 246 } |
| 247 |
| 248 // Flag setting to use preconnection instead of just DNS pre-fetching. |
| 249 bool preconnect_enabled() const { |
| 250 return preconnect_enabled_; |
| 251 } |
| 252 |
| 253 // Flag setting for whether we are prefetching dns lookups. |
| 254 bool predictor_enabled() const { |
| 255 return predictor_enabled_; |
| 256 } |
| 257 |
| 258 |
140 private: | 259 private: |
141 friend class base::RefCountedThreadSafe<Predictor>; | |
142 FRIEND_TEST_ALL_PREFIXES(PredictorTest, BenefitLookupTest); | 260 FRIEND_TEST_ALL_PREFIXES(PredictorTest, BenefitLookupTest); |
143 FRIEND_TEST_ALL_PREFIXES(PredictorTest, ShutdownWhenResolutionIsPendingTest); | 261 FRIEND_TEST_ALL_PREFIXES(PredictorTest, ShutdownWhenResolutionIsPendingTest); |
144 FRIEND_TEST_ALL_PREFIXES(PredictorTest, SingleLookupTest); | 262 FRIEND_TEST_ALL_PREFIXES(PredictorTest, SingleLookupTest); |
145 FRIEND_TEST_ALL_PREFIXES(PredictorTest, ConcurrentLookupTest); | 263 FRIEND_TEST_ALL_PREFIXES(PredictorTest, ConcurrentLookupTest); |
146 FRIEND_TEST_ALL_PREFIXES(PredictorTest, MassiveConcurrentLookupTest); | 264 FRIEND_TEST_ALL_PREFIXES(PredictorTest, MassiveConcurrentLookupTest); |
147 FRIEND_TEST_ALL_PREFIXES(PredictorTest, PriorityQueuePushPopTest); | 265 FRIEND_TEST_ALL_PREFIXES(PredictorTest, PriorityQueuePushPopTest); |
148 FRIEND_TEST_ALL_PREFIXES(PredictorTest, PriorityQueueReorderTest); | 266 FRIEND_TEST_ALL_PREFIXES(PredictorTest, PriorityQueueReorderTest); |
149 FRIEND_TEST_ALL_PREFIXES(PredictorTest, ReferrerSerializationTrimTest); | 267 FRIEND_TEST_ALL_PREFIXES(PredictorTest, ReferrerSerializationTrimTest); |
150 friend class WaitForResolutionHelper; // For testing. | 268 friend class WaitForResolutionHelper; // For testing. |
151 | 269 |
(...skipping 19 matching lines...) Expand all Loading... |
171 private: | 289 private: |
172 // The names in the queue that should be serviced (popped) ASAP. | 290 // The names in the queue that should be serviced (popped) ASAP. |
173 std::queue<GURL> rush_queue_; | 291 std::queue<GURL> rush_queue_; |
174 // The names in the queue that should only be serviced when rush_queue is | 292 // The names in the queue that should only be serviced when rush_queue is |
175 // empty. | 293 // empty. |
176 std::queue<GURL> background_queue_; | 294 std::queue<GURL> background_queue_; |
177 | 295 |
178 DISALLOW_COPY_AND_ASSIGN(HostNameQueue); | 296 DISALLOW_COPY_AND_ASSIGN(HostNameQueue); |
179 }; | 297 }; |
180 | 298 |
| 299 // The InitialObserver monitors navigations made by the network stack. This |
| 300 // is only used to identify startup time resolutions (for re-resolution |
| 301 // during our next process startup). |
| 302 // TODO(jar): Consider preconnecting at startup, which may be faster than |
| 303 // waiting for render process to start and request a connection. |
| 304 class InitialObserver { |
| 305 public: |
| 306 InitialObserver(); |
| 307 ~InitialObserver(); |
| 308 // Recording of when we observed each navigation. |
| 309 typedef std::map<GURL, base::TimeTicks> FirstNavigations; |
| 310 |
| 311 // Potentially add a new URL to our startup list. |
| 312 void Append(const GURL& url, Predictor* predictor); |
| 313 |
| 314 // Get an HTML version of our current planned first_navigations_. |
| 315 void GetFirstResolutionsHtml(std::string* output); |
| 316 |
| 317 // Persist the current first_navigations_ for storage in a list. |
| 318 void GetInitialDnsResolutionList(base::ListValue* startup_list); |
| 319 |
| 320 // Discards all initial loading history. |
| 321 void DiscardInitialNavigationHistory() { first_navigations_.clear(); } |
| 322 |
| 323 private: |
| 324 // List of the first N URL resolutions observed in this run. |
| 325 FirstNavigations first_navigations_; |
| 326 |
| 327 // The number of URLs we'll save for pre-resolving at next startup. |
| 328 static const size_t kStartupResolutionCount = 10; |
| 329 }; |
| 330 |
181 // A map that is keyed with the host/port that we've learned were the cause | 331 // A map that is keyed with the host/port that we've learned were the cause |
182 // of loading additional URLs. The list of additional targets is held | 332 // of loading additional URLs. The list of additional targets is held |
183 // in a Referrer instance, which is a value in this map. | 333 // in a Referrer instance, which is a value in this map. |
184 typedef std::map<GURL, Referrer> Referrers; | 334 typedef std::map<GURL, Referrer> Referrers; |
185 | 335 |
186 // Depending on the expected_subresource_use_, we may either make a TCP/IP | 336 // Depending on the expected_subresource_use_, we may either make a TCP/IP |
187 // preconnection, or merely pre-resolve the hostname via DNS (or even do | 337 // preconnection, or merely pre-resolve the hostname via DNS (or even do |
188 // nothing). The following are the threasholds for taking those actions. | 338 // nothing). The following are the threasholds for taking those actions. |
189 static const double kPreconnectWorthyExpectedValue; | 339 static const double kPreconnectWorthyExpectedValue; |
190 static const double kDNSPreresolutionWorthyExpectedValue; | 340 static const double kDNSPreresolutionWorthyExpectedValue; |
191 // Referred hosts with a subresource_use_rate_ that are less than the | 341 // Referred hosts with a subresource_use_rate_ that are less than the |
192 // following threshold will be discarded when we Trim() the list. | 342 // following threshold will be discarded when we Trim() the list. |
193 static const double kDiscardableExpectedValue; | 343 static const double kDiscardableExpectedValue; |
194 // During trimming operation to discard hosts for which we don't have likely | 344 // During trimming operation to discard hosts for which we don't have likely |
195 // subresources, we multiply the expected_subresource_use_ value by the | 345 // subresources, we multiply the expected_subresource_use_ value by the |
196 // following ratio until that value is less than kDiscardableExpectedValue. | 346 // following ratio until that value is less than kDiscardableExpectedValue. |
197 // This number should always be less than 1, an more than 0. | 347 // This number should always be less than 1, an more than 0. |
198 static const double kReferrerTrimRatio; | 348 static const double kReferrerTrimRatio; |
199 | 349 |
200 // Interval between periodic trimming of our whole referrer list. | 350 // Interval between periodic trimming of our whole referrer list. |
201 // We only do a major trimming about once an hour, and then only when the user | 351 // We only do a major trimming about once an hour, and then only when the user |
202 // is actively browsing. | 352 // is actively browsing. |
203 static const base::TimeDelta kDurationBetweenTrimmings; | 353 static const base::TimeDelta kDurationBetweenTrimmings; |
204 // Interval between incremental trimmings (to avoid inducing Jank). | 354 // Interval between incremental trimmings (to avoid inducing Jank). |
205 static const base::TimeDelta kDurationBetweenTrimmingIncrements; | 355 static const base::TimeDelta kDurationBetweenTrimmingIncrements; |
206 // Number of referring URLs processed in an incremental trimming. | 356 // Number of referring URLs processed in an incremental trimming. |
207 static const size_t kUrlsTrimmedPerIncrement; | 357 static const size_t kUrlsTrimmedPerIncrement; |
208 | 358 |
209 ~Predictor(); | |
210 | |
211 // Perform actual resolution or preconnection to subresources now. This is | |
212 // an internal worker method that is reached via a post task from | |
213 // PredictFrameSubresources(). | |
214 void PrepareFrameSubresources(const GURL& url); | |
215 | |
216 // Only for testing. Returns true if hostname has been successfully resolved | 359 // Only for testing. Returns true if hostname has been successfully resolved |
217 // (name found). | 360 // (name found). |
218 bool WasFound(const GURL& url) const { | 361 bool WasFound(const GURL& url) const { |
219 Results::const_iterator it(results_.find(url)); | 362 Results::const_iterator it(results_.find(url)); |
220 return (it != results_.end()) && | 363 return (it != results_.end()) && |
221 it->second.was_found(); | 364 it->second.was_found(); |
222 } | 365 } |
223 | 366 |
224 // Only for testing. Return how long was the resolution | 367 // Only for testing. Return how long was the resolution |
225 // or UrlInfo::kNullDuration if it hasn't been resolved yet. | 368 // or UrlInfo::kNullDuration if it hasn't been resolved yet. |
226 base::TimeDelta GetResolutionDuration(const GURL& url) { | 369 base::TimeDelta GetResolutionDuration(const GURL& url) { |
227 if (results_.find(url) == results_.end()) | 370 if (results_.find(url) == results_.end()) |
228 return UrlInfo::kNullDuration; | 371 return UrlInfo::kNullDuration; |
229 return results_[url].resolve_duration(); | 372 return results_[url].resolve_duration(); |
230 } | 373 } |
231 | 374 |
232 // Only for testing; | 375 // Only for testing; |
233 size_t peak_pending_lookups() const { return peak_pending_lookups_; } | 376 size_t peak_pending_lookups() const { return peak_pending_lookups_; } |
234 | 377 |
| 378 // ------------- Start IO thread methods. |
| 379 |
| 380 // Perform actual resolution or preconnection to subresources now. This is |
| 381 // an internal worker method that is reached via a post task from |
| 382 // PredictFrameSubresources(). |
| 383 void PrepareFrameSubresources(const GURL& url); |
| 384 |
235 // Access method for use by async lookup request to pass resolution result. | 385 // Access method for use by async lookup request to pass resolution result. |
236 void OnLookupFinished(LookupRequest* request, const GURL& url, bool found); | 386 void OnLookupFinished(LookupRequest* request, const GURL& url, bool found); |
237 | 387 |
238 // Underlying method for both async and synchronous lookup to update state. | 388 // Underlying method for both async and synchronous lookup to update state. |
239 void LookupFinished(LookupRequest* request, | 389 void LookupFinished(LookupRequest* request, |
240 const GURL& url, bool found); | 390 const GURL& url, bool found); |
241 | 391 |
242 // Queue hostname for resolution. If queueing was done, return the pointer | 392 // Queue hostname for resolution. If queueing was done, return the pointer |
243 // to the queued instance, otherwise return NULL. | 393 // to the queued instance, otherwise return NULL. |
244 UrlInfo* AppendToResolutionQueue(const GURL& url, | 394 UrlInfo* AppendToResolutionQueue(const GURL& url, |
(...skipping 25 matching lines...) Expand all Loading... |
270 void LoadUrlsForTrimming(); | 420 void LoadUrlsForTrimming(); |
271 | 421 |
272 // Posts a task to do additional incremental trimming of referrers_. | 422 // Posts a task to do additional incremental trimming of referrers_. |
273 void PostIncrementalTrimTask(); | 423 void PostIncrementalTrimTask(); |
274 | 424 |
275 // Calls Trim() on some or all of urls_being_trimmed_. | 425 // Calls Trim() on some or all of urls_being_trimmed_. |
276 // If it does not process all the URLs in that vector, it posts a task to | 426 // If it does not process all the URLs in that vector, it posts a task to |
277 // continue with them shortly (i.e., it yeilds and continues). | 427 // continue with them shortly (i.e., it yeilds and continues). |
278 void IncrementalTrimReferrers(bool trim_all_now); | 428 void IncrementalTrimReferrers(bool trim_all_now); |
279 | 429 |
| 430 // ------------- End IO thread methods. |
| 431 |
| 432 scoped_ptr<InitialObserver> initial_observer_; |
| 433 |
| 434 // Status of speculative DNS resolution and speculative TCP/IP connection |
| 435 // feature. |
| 436 bool predictor_enabled_; |
| 437 |
280 // work_queue_ holds a list of names we need to look up. | 438 // work_queue_ holds a list of names we need to look up. |
281 HostNameQueue work_queue_; | 439 HostNameQueue work_queue_; |
282 | 440 |
283 // results_ contains information for existing/prior prefetches. | 441 // results_ contains information for existing/prior prefetches. |
284 Results results_; | 442 Results results_; |
285 | 443 |
286 std::set<LookupRequest*> pending_lookups_; | 444 std::set<LookupRequest*> pending_lookups_; |
287 | 445 |
288 // For testing, to verify that we don't exceed the limit. | 446 // For testing, to verify that we don't exceed the limit. |
289 size_t peak_pending_lookups_; | 447 size_t peak_pending_lookups_; |
290 | 448 |
291 // When true, we don't make new lookup requests. | 449 // When true, we don't make new lookup requests. |
292 bool shutdown_; | 450 bool shutdown_; |
293 | 451 |
294 // The number of concurrent speculative lookups currently allowed to be sent | 452 // The number of concurrent speculative lookups currently allowed to be sent |
295 // to the resolver. Any additional lookups will be queued to avoid exceeding | 453 // to the resolver. Any additional lookups will be queued to avoid exceeding |
296 // this value. The queue is a priority queue that will accelerate | 454 // this value. The queue is a priority queue that will accelerate |
297 // sub-resource speculation, and retard resolutions suggested by page scans. | 455 // sub-resource speculation, and retard resolutions suggested by page scans. |
298 const size_t max_concurrent_dns_lookups_; | 456 const size_t max_concurrent_dns_lookups_; |
299 | 457 |
300 // The maximum queueing delay that is acceptable before we enter congestion | 458 // The maximum queueing delay that is acceptable before we enter congestion |
301 // reduction mode, and discard all queued (but not yet assigned) resolutions. | 459 // reduction mode, and discard all queued (but not yet assigned) resolutions. |
302 const base::TimeDelta max_dns_queue_delay_; | 460 const base::TimeDelta max_dns_queue_delay_; |
303 | 461 |
304 // The host resolver we warm DNS entries for. | 462 // The host resolver we warm DNS entries for. |
305 net::HostResolver* const host_resolver_; | 463 net::HostResolver* host_resolver_; |
306 | 464 |
307 // Are we currently using preconnection, rather than just DNS resolution, for | 465 // Are we currently using preconnection, rather than just DNS resolution, for |
308 // subresources and omni-box search URLs. | 466 // subresources and omni-box search URLs. |
309 bool preconnect_enabled_; | 467 bool preconnect_enabled_; |
310 | 468 |
311 // Most recent suggestion from Omnibox provided via AnticipateOmniboxUrl(). | 469 // Most recent suggestion from Omnibox provided via AnticipateOmniboxUrl(). |
312 std::string last_omnibox_host_; | 470 std::string last_omnibox_host_; |
313 | 471 |
314 // The time when the last preresolve was done for last_omnibox_host_. | 472 // The time when the last preresolve was done for last_omnibox_host_. |
315 base::TimeTicks last_omnibox_preresolve_; | 473 base::TimeTicks last_omnibox_preresolve_; |
(...skipping 11 matching lines...) Expand all Loading... |
327 // orginial hostname. | 485 // orginial hostname. |
328 Referrers referrers_; | 486 Referrers referrers_; |
329 | 487 |
330 // List of URLs in referrers_ currently being trimmed (scaled down to | 488 // List of URLs in referrers_ currently being trimmed (scaled down to |
331 // eventually be aged out of use). | 489 // eventually be aged out of use). |
332 std::vector<GURL> urls_being_trimmed_; | 490 std::vector<GURL> urls_being_trimmed_; |
333 | 491 |
334 // A time after which we need to do more trimming of referrers. | 492 // A time after which we need to do more trimming of referrers. |
335 base::TimeTicks next_trim_time_; | 493 base::TimeTicks next_trim_time_; |
336 | 494 |
337 ScopedRunnableMethodFactory<Predictor> trim_task_factory_; | 495 scoped_ptr<ScopedRunnableMethodFactory<Predictor> > trim_task_factory_; |
338 | 496 |
339 DISALLOW_COPY_AND_ASSIGN(Predictor); | 497 DISALLOW_COPY_AND_ASSIGN(Predictor); |
340 }; | 498 }; |
341 | 499 |
| 500 // This version of the predictor is used for testing. |
| 501 class SimplePredictor : public Predictor { |
| 502 public: |
| 503 explicit SimplePredictor(bool preconnect_enabled) |
| 504 : Predictor(preconnect_enabled) {} |
| 505 virtual ~SimplePredictor() {} |
| 506 virtual void InitNetworkPredictor(PrefService* user_prefs, |
| 507 PrefService* local_state, |
| 508 IOThread* io_thread); |
| 509 virtual void ShutdownOnUIThread(PrefService* user_prefs); |
| 510 }; |
| 511 |
342 } // namespace chrome_browser_net | 512 } // namespace chrome_browser_net |
343 | 513 |
344 #endif // CHROME_BROWSER_NET_PREDICTOR_H_ | 514 #endif // CHROME_BROWSER_NET_PREDICTOR_H_ |
OLD | NEW |