Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(500)

Side by Side Diff: chrome/browser/predictors/resource_prefetch_predictor.cc

Issue 2937623007: predictors: Move more methods from ResourcePrefetchPredictor into LoadingDataCollector. (Closed)
Patch Set: Address alexilin feedback. Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 #include "chrome/browser/predictors/resource_prefetch_predictor.h" 5 #include "chrome/browser/predictors/resource_prefetch_predictor.h"
6 6
7 #include <map> 7 #include <map>
8 #include <set> 8 #include <set>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/memory/ptr_util.h" 12 #include "base/memory/ptr_util.h"
13 #include "base/metrics/histogram_macros.h" 13 #include "base/metrics/histogram_macros.h"
14 #include "base/rand_util.h" 14 #include "base/rand_util.h"
15 #include "base/time/time.h" 15 #include "base/time/time.h"
16 #include "base/trace_event/trace_event.h" 16 #include "base/trace_event/trace_event.h"
17 #include "chrome/browser/history/history_service_factory.h" 17 #include "chrome/browser/history/history_service_factory.h"
18 #include "chrome/browser/predictors/loading_data_collector.h"
18 #include "chrome/browser/predictors/loading_stats_collector.h" 19 #include "chrome/browser/predictors/loading_stats_collector.h"
19 #include "chrome/browser/predictors/predictor_database.h" 20 #include "chrome/browser/predictors/predictor_database.h"
20 #include "chrome/browser/predictors/predictor_database_factory.h" 21 #include "chrome/browser/predictors/predictor_database_factory.h"
21 #include "chrome/browser/predictors/resource_prefetcher_manager.h" 22 #include "chrome/browser/predictors/resource_prefetcher_manager.h"
22 #include "chrome/browser/profiles/profile.h" 23 #include "chrome/browser/profiles/profile.h"
23 #include "components/history/core/browser/history_database.h" 24 #include "components/history/core/browser/history_database.h"
24 #include "components/history/core/browser/history_service.h" 25 #include "components/history/core/browser/history_service.h"
25 #include "components/history/core/browser/url_utils.h" 26 #include "components/history/core/browser/url_utils.h"
26 #include "components/mime_util/mime_util.h" 27 #include "components/mime_util/mime_util.h"
27 #include "components/precache/core/precache_manifest_util.h" 28 #include "components/precache/core/precache_manifest_util.h"
28 #include "content/public/browser/browser_thread.h" 29 #include "content/public/browser/browser_thread.h"
29 #include "content/public/browser/resource_request_info.h" 30 #include "content/public/browser/resource_request_info.h"
30 #include "content/public/browser/web_contents.h" 31 #include "content/public/browser/web_contents.h"
31 #include "net/http/http_response_headers.h"
32 #include "net/url_request/url_request.h"
33 32
34 using content::BrowserThread; 33 using content::BrowserThread;
35 34
36 namespace predictors { 35 namespace predictors {
37 36
38 namespace { 37 namespace {
39 38
40 // Sorted by decreasing likelihood according to HTTP archive.
41 const char* kFontMimeTypes[] = {"font/woff2",
42 "application/x-font-woff",
43 "application/font-woff",
44 "application/font-woff2",
45 "font/x-woff",
46 "application/x-font-ttf",
47 "font/woff",
48 "font/ttf",
49 "application/x-font-otf",
50 "x-font/woff",
51 "application/font-sfnt",
52 "application/font-ttf"};
53
54 const size_t kMaxManifestByteSize = 16 * 1024; 39 const size_t kMaxManifestByteSize = 16 * 1024;
55 const size_t kNumSampleHosts = 50; 40 const size_t kNumSampleHosts = 50;
56 const size_t kReportReadinessThreshold = 50; 41 const size_t kReportReadinessThreshold = 50;
57 const float kMinOriginConfidenceToTriggerPreconnect = 0.75; 42 const float kMinOriginConfidenceToTriggerPreconnect = 0.75;
58 const float kMinOriginConfidenceToTriggerPreresolve = 0.2; 43 const float kMinOriginConfidenceToTriggerPreresolve = 0.2;
59 44
60 // For reporting events of interest that are not tied to any navigation. 45 // For reporting events of interest that are not tied to any navigation.
61 enum ReportingEvent { 46 enum ReportingEvent {
62 REPORTING_EVENT_ALL_HISTORY_CLEARED = 0, 47 REPORTING_EVENT_ALL_HISTORY_CLEARED = 0,
63 REPORTING_EVENT_PARTIAL_HISTORY_CLEARED = 1, 48 REPORTING_EVENT_PARTIAL_HISTORY_CLEARED = 1,
64 REPORTING_EVENT_COUNT = 2 49 REPORTING_EVENT_COUNT = 2
65 }; 50 };
66 51
67 float ComputeRedirectConfidence(const predictors::RedirectStat& redirect) { 52 float ComputeRedirectConfidence(const predictors::RedirectStat& redirect) {
68 return (redirect.number_of_hits() + 0.0) / 53 return (redirect.number_of_hits() + 0.0) /
69 (redirect.number_of_hits() + redirect.number_of_misses()); 54 (redirect.number_of_hits() + redirect.number_of_misses());
70 } 55 }
71 56
72 void UpdateOrAddToOrigins(
73 std::map<GURL, ResourcePrefetchPredictor::OriginRequestSummary>* summaries,
74 const ResourcePrefetchPredictor::URLRequestSummary& request_summary) {
75 const GURL& request_url = request_summary.request_url;
76 DCHECK(request_url.is_valid());
77 if (!request_url.is_valid())
78 return;
79
80 GURL origin = request_url.GetOrigin();
81 auto it = summaries->find(origin);
82 if (it == summaries->end()) {
83 ResourcePrefetchPredictor::OriginRequestSummary summary;
84 summary.origin = origin;
85 summary.first_occurrence = summaries->size();
86 it = summaries->insert({origin, summary}).first;
87 }
88
89 it->second.always_access_network |=
90 request_summary.always_revalidate || request_summary.is_no_store;
91 it->second.accessed_network |= request_summary.network_accessed;
92 }
93
94 void InitializeOriginStatFromOriginRequestSummary( 57 void InitializeOriginStatFromOriginRequestSummary(
95 OriginStat* origin, 58 OriginStat* origin,
96 const ResourcePrefetchPredictor::OriginRequestSummary& summary) { 59 const OriginRequestSummary& summary) {
97 origin->set_origin(summary.origin.spec()); 60 origin->set_origin(summary.origin.spec());
98 origin->set_number_of_hits(1); 61 origin->set_number_of_hits(1);
99 origin->set_average_position(summary.first_occurrence + 1); 62 origin->set_average_position(summary.first_occurrence + 1);
100 origin->set_always_access_network(summary.always_access_network); 63 origin->set_always_access_network(summary.always_access_network);
101 origin->set_accessed_network(summary.accessed_network); 64 origin->set_accessed_network(summary.accessed_network);
102 } 65 }
103 66
104 bool IsManifestTooOld(const precache::PrecacheManifest& manifest) { 67 bool IsManifestTooOld(const precache::PrecacheManifest& manifest) {
105 const base::TimeDelta kMaxManifestAge = base::TimeDelta::FromDays(5); 68 const base::TimeDelta kMaxManifestAge = base::TimeDelta::FromDays(5);
106 return base::Time::Now() - base::Time::FromDoubleT(manifest.id().id()) > 69 return base::Time::Now() - base::Time::FromDoubleT(manifest.id().id()) >
107 kMaxManifestAge; 70 kMaxManifestAge;
108 } 71 }
109 72
110 // Used to fetch the visit count for a URL from the History database. 73 // Used to fetch the visit count for a URL from the History database.
111 class GetUrlVisitCountTask : public history::HistoryDBTask { 74 class GetUrlVisitCountTask : public history::HistoryDBTask {
112 public: 75 public:
113 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary;
114 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary;
115 typedef base::OnceCallback<void(size_t, // URL visit count. 76 typedef base::OnceCallback<void(size_t, // URL visit count.
116 const PageRequestSummary&)> 77 const PageRequestSummary&)>
117 VisitInfoCallback; 78 VisitInfoCallback;
118 79
119 GetUrlVisitCountTask(std::unique_ptr<PageRequestSummary> summary, 80 GetUrlVisitCountTask(std::unique_ptr<PageRequestSummary> summary,
120 VisitInfoCallback callback); 81 VisitInfoCallback callback);
121 82
122 bool RunOnDBThread(history::HistoryBackend* backend, 83 bool RunOnDBThread(history::HistoryBackend* backend,
123 history::HistoryDatabase* db) override; 84 history::HistoryDatabase* db) override;
124 85
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 } // namespace internal 145 } // namespace internal
185 146
186 PreconnectPrediction::PreconnectPrediction() = default; 147 PreconnectPrediction::PreconnectPrediction() = default;
187 PreconnectPrediction::PreconnectPrediction( 148 PreconnectPrediction::PreconnectPrediction(
188 const PreconnectPrediction& prediction) = default; 149 const PreconnectPrediction& prediction) = default;
189 PreconnectPrediction::~PreconnectPrediction() = default; 150 PreconnectPrediction::~PreconnectPrediction() = default;
190 151
191 //////////////////////////////////////////////////////////////////////////////// 152 ////////////////////////////////////////////////////////////////////////////////
192 // ResourcePrefetchPredictor static functions. 153 // ResourcePrefetchPredictor static functions.
193 154
194 // static
195 content::ResourceType ResourcePrefetchPredictor::GetResourceType(
196 content::ResourceType resource_type,
197 const std::string& mime_type) {
198 // Restricts content::RESOURCE_TYPE_{PREFETCH,SUB_RESOURCE,XHR} to a small set
199 // of mime types, because these resource types don't communicate how the
200 // resources will be used.
201 if (resource_type == content::RESOURCE_TYPE_PREFETCH ||
202 resource_type == content::RESOURCE_TYPE_SUB_RESOURCE ||
203 resource_type == content::RESOURCE_TYPE_XHR) {
204 return GetResourceTypeFromMimeType(mime_type,
205 content::RESOURCE_TYPE_LAST_TYPE);
206 }
207 return resource_type;
208 }
209
210 // static
211 bool ResourcePrefetchPredictor::IsNoStore(const net::URLRequest& response) {
212 if (response.was_cached())
213 return false;
214
215 const net::HttpResponseInfo& response_info = response.response_info();
216 if (!response_info.headers.get())
217 return false;
218 return response_info.headers->HasHeaderValue("cache-control", "no-store");
219 }
220
221 // static
222 content::ResourceType ResourcePrefetchPredictor::GetResourceTypeFromMimeType(
223 const std::string& mime_type,
224 content::ResourceType fallback) {
225 if (mime_type.empty()) {
226 return fallback;
227 } else if (mime_util::IsSupportedImageMimeType(mime_type)) {
228 return content::RESOURCE_TYPE_IMAGE;
229 } else if (mime_util::IsSupportedJavascriptMimeType(mime_type)) {
230 return content::RESOURCE_TYPE_SCRIPT;
231 } else if (net::MatchesMimeType("text/css", mime_type)) {
232 return content::RESOURCE_TYPE_STYLESHEET;
233 } else {
234 bool found =
235 std::any_of(std::begin(kFontMimeTypes), std::end(kFontMimeTypes),
236 [&mime_type](const std::string& mime) {
237 return net::MatchesMimeType(mime, mime_type);
238 });
239 if (found)
240 return content::RESOURCE_TYPE_FONT_RESOURCE;
241 }
242 return fallback;
243 }
244
245 bool ResourcePrefetchPredictor::GetRedirectEndpoint( 155 bool ResourcePrefetchPredictor::GetRedirectEndpoint(
246 const std::string& entry_point, 156 const std::string& entry_point,
247 const RedirectDataMap& redirect_data, 157 const RedirectDataMap& redirect_data,
248 std::string* redirect_endpoint) const { 158 std::string* redirect_endpoint) const {
249 DCHECK(redirect_endpoint); 159 DCHECK(redirect_endpoint);
250 160
251 RedirectData data; 161 RedirectData data;
252 bool exists = redirect_data.TryGetData(entry_point, &data); 162 bool exists = redirect_data.TryGetData(entry_point, &data);
253 if (!exists) { 163 if (!exists) {
254 // Fallback to fetching URLs based on the incoming URL/host. By default 164 // Fallback to fetching URLs based on the incoming URL/host. By default
(...skipping 26 matching lines...) Expand all
281 return false; 191 return false;
282 } 192 }
283 193
284 *redirect_endpoint = redirect.url(); 194 *redirect_endpoint = redirect.url();
285 return true; 195 return true;
286 } 196 }
287 197
288 //////////////////////////////////////////////////////////////////////////////// 198 ////////////////////////////////////////////////////////////////////////////////
289 // ResourcePrefetchPredictor nested types. 199 // ResourcePrefetchPredictor nested types.
290 200
291 ResourcePrefetchPredictor::OriginRequestSummary::OriginRequestSummary()
292 : origin(),
293 always_access_network(false),
294 accessed_network(false),
295 first_occurrence(0) {}
296
297 ResourcePrefetchPredictor::OriginRequestSummary::OriginRequestSummary(
298 const OriginRequestSummary& other) = default;
299
300 ResourcePrefetchPredictor::OriginRequestSummary::~OriginRequestSummary() {}
301
302 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary()
303 : resource_type(content::RESOURCE_TYPE_LAST_TYPE),
304 priority(net::IDLE),
305 before_first_contentful_paint(false),
306 was_cached(false),
307 has_validators(false),
308 always_revalidate(false),
309 is_no_store(false),
310 network_accessed(false) {}
311
312 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary(
313 const URLRequestSummary& other) = default;
314
315 ResourcePrefetchPredictor::URLRequestSummary::~URLRequestSummary() {
316 }
317
318 // static
319 bool ResourcePrefetchPredictor::URLRequestSummary::SummarizeResponse(
320 const net::URLRequest& request,
321 URLRequestSummary* summary) {
322 const content::ResourceRequestInfo* request_info =
323 content::ResourceRequestInfo::ForRequest(&request);
324 if (!request_info)
325 return false;
326
327 // This method is called when the response is started, so this field reflects
328 // the time at which the response began, not when it finished, as would
329 // arguably be ideal. This means if firstContentfulPaint happens after the
330 // response has started, but before it's finished, we will erroneously mark
331 // the resource as having been loaded before firstContentfulPaint. This is
332 // a rare and insignificant enough occurrence that we opt to record the time
333 // here for the sake of simplicity.
334 summary->response_time = base::TimeTicks::Now();
335 summary->resource_url = request.original_url();
336 summary->request_url = request.url();
337 content::ResourceType resource_type_from_request =
338 request_info->GetResourceType();
339 summary->priority = request.priority();
340 request.GetMimeType(&summary->mime_type);
341 summary->was_cached = request.was_cached();
342 summary->resource_type =
343 GetResourceType(resource_type_from_request, summary->mime_type);
344
345 scoped_refptr<net::HttpResponseHeaders> headers =
346 request.response_info().headers;
347 if (headers.get()) {
348 summary->has_validators = headers->HasValidators();
349 // RFC 2616, section 14.9.
350 summary->always_revalidate =
351 headers->HasHeaderValue("cache-control", "no-cache") ||
352 headers->HasHeaderValue("pragma", "no-cache") ||
353 headers->HasHeaderValue("vary", "*");
354 summary->is_no_store = IsNoStore(request);
355 }
356 summary->network_accessed = request.response_info().network_accessed;
357 return true;
358 }
359
360 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary(
361 const GURL& i_main_frame_url)
362 : main_frame_url(i_main_frame_url),
363 initial_url(i_main_frame_url),
364 first_contentful_paint(base::TimeTicks::Max()) {}
365
366 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary(
367 const PageRequestSummary& other) = default;
368
369 ResourcePrefetchPredictor::PageRequestSummary::~PageRequestSummary() {}
370
371 ResourcePrefetchPredictor::Prediction::Prediction() = default; 201 ResourcePrefetchPredictor::Prediction::Prediction() = default;
372 202
373 ResourcePrefetchPredictor::Prediction::Prediction( 203 ResourcePrefetchPredictor::Prediction::Prediction(
374 const ResourcePrefetchPredictor::Prediction& other) = default; 204 const ResourcePrefetchPredictor::Prediction& other) = default;
375 205
376 ResourcePrefetchPredictor::Prediction::~Prediction() = default; 206 ResourcePrefetchPredictor::Prediction::~Prediction() = default;
377 207
378 //////////////////////////////////////////////////////////////////////////////// 208 ////////////////////////////////////////////////////////////////////////////////
379 // ResourcePrefetchPredictor. 209 // ResourcePrefetchPredictor.
380 210
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 auto reply = base::BindOnce( 258 auto reply = base::BindOnce(
429 &ResourcePrefetchPredictor::CreateCaches, weak_factory_.GetWeakPtr(), 259 &ResourcePrefetchPredictor::CreateCaches, weak_factory_.GetWeakPtr(),
430 std::move(url_resource_data), std::move(host_resource_data), 260 std::move(url_resource_data), std::move(host_resource_data),
431 std::move(url_redirect_data), std::move(host_redirect_data), 261 std::move(url_redirect_data), std::move(host_redirect_data),
432 std::move(manifest_data), std::move(origin_data)); 262 std::move(manifest_data), std::move(origin_data));
433 263
434 tables_->GetTaskRunner()->PostTaskAndReply(FROM_HERE, std::move(task), 264 tables_->GetTaskRunner()->PostTaskAndReply(FROM_HERE, std::move(task),
435 std::move(reply)); 265 std::move(reply));
436 } 266 }
437 267
438 void ResourcePrefetchPredictor::RecordURLRequest(
439 const URLRequestSummary& request) {
440 DCHECK_CURRENTLY_ON(BrowserThread::UI);
441 if (initialization_state_ != INITIALIZED)
442 return;
443
444 DCHECK_EQ(request.resource_type, content::RESOURCE_TYPE_MAIN_FRAME);
445 OnMainFrameRequest(request);
446 }
447
448 void ResourcePrefetchPredictor::RecordURLResponse(
449 const URLRequestSummary& response) {
450 DCHECK_CURRENTLY_ON(BrowserThread::UI);
451 if (initialization_state_ != INITIALIZED)
452 return;
453
454 if (response.resource_type != content::RESOURCE_TYPE_MAIN_FRAME)
455 OnSubresourceResponse(response);
456 }
457
458 void ResourcePrefetchPredictor::RecordURLRedirect(
459 const URLRequestSummary& response) {
460 DCHECK_CURRENTLY_ON(BrowserThread::UI);
461 if (initialization_state_ != INITIALIZED)
462 return;
463
464 if (response.resource_type == content::RESOURCE_TYPE_MAIN_FRAME)
465 OnMainFrameRedirect(response);
466 else
467 OnSubresourceRedirect(response);
468 }
469
470 void ResourcePrefetchPredictor::RecordMainFrameLoadComplete(
471 const NavigationID& navigation_id) {
472 switch (initialization_state_) {
473 case NOT_INITIALIZED:
474 StartInitialization();
475 break;
476 case INITIALIZING:
477 break;
478 case INITIALIZED:
479 // WebContents can return an empty URL if the navigation entry
480 // corresponding to the navigation has not been created yet.
481 if (!navigation_id.main_frame_url.is_empty())
482 OnNavigationComplete(navigation_id);
483 break;
484 default:
485 NOTREACHED() << "Unexpected initialization_state_: "
486 << initialization_state_;
487 }
488 }
489
490 void ResourcePrefetchPredictor::RecordFirstContentfulPaint(
491 const NavigationID& navigation_id,
492 const base::TimeTicks& first_contentful_paint) {
493 DCHECK_CURRENTLY_ON(BrowserThread::UI);
494 if (initialization_state_ != INITIALIZED)
495 return;
496
497 NavigationMap::iterator nav_it = inflight_navigations_.find(navigation_id);
498 if (nav_it != inflight_navigations_.end())
499 nav_it->second->first_contentful_paint = first_contentful_paint;
500 }
501
502 void ResourcePrefetchPredictor::OnPrefetchingFinished( 268 void ResourcePrefetchPredictor::OnPrefetchingFinished(
503 const GURL& main_frame_url, 269 const GURL& main_frame_url,
504 std::unique_ptr<ResourcePrefetcher::PrefetcherStats> stats) { 270 std::unique_ptr<ResourcePrefetcher::PrefetcherStats> stats) {
505 if (observer_) 271 if (observer_)
506 observer_->OnPrefetchingFinished(main_frame_url); 272 observer_->OnPrefetchingFinished(main_frame_url);
507 273
508 if (stats_collector_) 274 if (stats_collector_)
509 stats_collector_->RecordPrefetcherStats(std::move(stats)); 275 stats_collector_->RecordPrefetcherStats(std::move(stats));
510 } 276 }
511 277
(...skipping 21 matching lines...) Expand all
533 } 299 }
534 300
535 void ResourcePrefetchPredictor::Shutdown() { 301 void ResourcePrefetchPredictor::Shutdown() {
536 if (prefetch_manager_.get()) { 302 if (prefetch_manager_.get()) {
537 prefetch_manager_->ShutdownOnUIThread(); 303 prefetch_manager_->ShutdownOnUIThread();
538 prefetch_manager_ = nullptr; 304 prefetch_manager_ = nullptr;
539 } 305 }
540 history_service_observer_.RemoveAll(); 306 history_service_observer_.RemoveAll();
541 } 307 }
542 308
543 void ResourcePrefetchPredictor::OnMainFrameRequest( 309 void ResourcePrefetchPredictor::RecordPageRequestSummary(
544 const URLRequestSummary& request) { 310 std::unique_ptr<PageRequestSummary> summary) {
545 DCHECK_CURRENTLY_ON(BrowserThread::UI); 311 // Make sure initialization is done or start initialization if necessary.
546 DCHECK_EQ(INITIALIZED, initialization_state_); 312 if (initialization_state_ == NOT_INITIALIZED) {
547 313 StartInitialization();
548 CleanupAbandonedNavigations(request.navigation_id); 314 return;
549 315 } else if (initialization_state_ == INITIALIZING) {
550 // New empty navigation entry. 316 return;
551 const GURL& main_frame_url = request.navigation_id.main_frame_url; 317 } else if (initialization_state_ != INITIALIZED) {
552 inflight_navigations_.emplace( 318 NOTREACHED() << "Unexpected initialization_state_: "
553 request.navigation_id, 319 << initialization_state_;
554 base::MakeUnique<PageRequestSummary>(main_frame_url)); 320 return;
555 }
556
557 void ResourcePrefetchPredictor::OnMainFrameRedirect(
558 const URLRequestSummary& response) {
559 DCHECK_CURRENTLY_ON(BrowserThread::UI);
560 DCHECK_EQ(INITIALIZED, initialization_state_);
561
562 const GURL& main_frame_url = response.navigation_id.main_frame_url;
563 std::unique_ptr<PageRequestSummary> summary;
564 NavigationMap::iterator nav_it =
565 inflight_navigations_.find(response.navigation_id);
566 if (nav_it != inflight_navigations_.end()) {
567 summary = std::move(nav_it->second);
568 inflight_navigations_.erase(nav_it);
569 } 321 }
570 322
571 // The redirect url may be empty if the URL was invalid.
572 if (response.redirect_url.is_empty())
573 return;
574
575 // If we lost the information about the first hop for some reason.
576 if (!summary) {
577 summary = base::MakeUnique<PageRequestSummary>(main_frame_url);
578 }
579
580 // A redirect will not lead to another OnMainFrameRequest call, so record the
581 // redirect url as a new navigation id and save the initial url.
582 NavigationID navigation_id(response.navigation_id);
583 navigation_id.main_frame_url = response.redirect_url;
584 summary->main_frame_url = response.redirect_url;
585 inflight_navigations_.emplace(navigation_id, std::move(summary));
586 }
587
588 void ResourcePrefetchPredictor::OnSubresourceResponse(
589 const URLRequestSummary& response) {
590 DCHECK_CURRENTLY_ON(BrowserThread::UI);
591 DCHECK_EQ(INITIALIZED, initialization_state_);
592
593 NavigationMap::const_iterator nav_it =
594 inflight_navigations_.find(response.navigation_id);
595 if (nav_it == inflight_navigations_.end())
596 return;
597 auto& page_request_summary = *nav_it->second;
598
599 if (!response.is_no_store)
600 page_request_summary.subresource_requests.push_back(response);
601
602 if (config_.is_origin_learning_enabled)
603 UpdateOrAddToOrigins(&page_request_summary.origins, response);
604 }
605
606 void ResourcePrefetchPredictor::OnSubresourceRedirect(
607 const URLRequestSummary& response) {
608 DCHECK_CURRENTLY_ON(BrowserThread::UI);
609 DCHECK_EQ(INITIALIZED, initialization_state_);
610
611 if (!config_.is_origin_learning_enabled)
612 return;
613
614 NavigationMap::const_iterator nav_it =
615 inflight_navigations_.find(response.navigation_id);
616 if (nav_it == inflight_navigations_.end())
617 return;
618 auto& page_request_summary = *nav_it->second;
619 UpdateOrAddToOrigins(&page_request_summary.origins, response);
620 }
621
622 void ResourcePrefetchPredictor::OnNavigationComplete(
623 const NavigationID& nav_id_without_timing_info) {
624 DCHECK_CURRENTLY_ON(BrowserThread::UI);
625 DCHECK_EQ(INITIALIZED, initialization_state_);
626
627 NavigationMap::iterator nav_it =
628 inflight_navigations_.find(nav_id_without_timing_info);
629 if (nav_it == inflight_navigations_.end())
630 return;
631
632 // Remove the navigation from the inflight navigations.
633 std::unique_ptr<PageRequestSummary> summary = std::move(nav_it->second);
634 inflight_navigations_.erase(nav_it);
635
636 // Set before_first_contentful paint for each resource.
637 for (auto& request_summary : summary->subresource_requests) {
638 request_summary.before_first_contentful_paint =
639 request_summary.response_time < summary->first_contentful_paint;
640 }
641
642 if (stats_collector_)
643 stats_collector_->RecordPageRequestSummary(*summary);
644
645 // Kick off history lookup to determine if we should record the URL. 323 // Kick off history lookup to determine if we should record the URL.
646 history::HistoryService* history_service = 324 history::HistoryService* history_service =
647 HistoryServiceFactory::GetForProfile(profile_, 325 HistoryServiceFactory::GetForProfile(profile_,
648 ServiceAccessType::EXPLICIT_ACCESS); 326 ServiceAccessType::EXPLICIT_ACCESS);
649 DCHECK(history_service); 327 DCHECK(history_service);
650 history_service->ScheduleDBTask( 328 history_service->ScheduleDBTask(
651 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( 329 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask(
652 std::move(summary), 330 std::move(summary),
653 base::BindOnce(&ResourcePrefetchPredictor::OnVisitCountLookup, 331 base::BindOnce(&ResourcePrefetchPredictor::OnVisitCountLookup,
654 weak_factory_.GetWeakPtr()))), 332 weak_factory_.GetWeakPtr()))),
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 if (config_.IsPrefetchingEnabledForSomeOrigin(profile_)) { 545 if (config_.IsPrefetchingEnabledForSomeOrigin(profile_)) {
868 prefetch_manager_ = new ResourcePrefetcherManager( 546 prefetch_manager_ = new ResourcePrefetcherManager(
869 this, config_, profile_->GetRequestContext()); 547 this, config_, profile_->GetRequestContext());
870 } 548 }
871 initialization_state_ = INITIALIZED; 549 initialization_state_ = INITIALIZED;
872 550
873 if (observer_) 551 if (observer_)
874 observer_->OnPredictorInitialized(); 552 observer_->OnPredictorInitialized();
875 } 553 }
876 554
877 void ResourcePrefetchPredictor::CleanupAbandonedNavigations(
878 const NavigationID& navigation_id) {
879 if (stats_collector_)
880 stats_collector_->CleanupAbandonedStats();
881
882 static const base::TimeDelta max_navigation_age =
883 base::TimeDelta::FromSeconds(config_.max_navigation_lifetime_seconds);
884
885 base::TimeTicks time_now = base::TimeTicks::Now();
886 for (NavigationMap::iterator it = inflight_navigations_.begin();
887 it != inflight_navigations_.end();) {
888 if ((it->first.tab_id == navigation_id.tab_id) ||
889 (time_now - it->first.creation_time > max_navigation_age)) {
890 inflight_navigations_.erase(it++);
891 } else {
892 ++it;
893 }
894 }
895 }
896
897 void ResourcePrefetchPredictor::DeleteAllUrls() { 555 void ResourcePrefetchPredictor::DeleteAllUrls() {
898 inflight_navigations_.clear();
899
900 url_resource_data_->DeleteAllData(); 556 url_resource_data_->DeleteAllData();
901 host_resource_data_->DeleteAllData(); 557 host_resource_data_->DeleteAllData();
902 url_redirect_data_->DeleteAllData(); 558 url_redirect_data_->DeleteAllData();
903 host_redirect_data_->DeleteAllData(); 559 host_redirect_data_->DeleteAllData();
904 manifest_data_->DeleteAllData(); 560 manifest_data_->DeleteAllData();
905 origin_data_->DeleteAllData(); 561 origin_data_->DeleteAllData();
906 } 562 }
907 563
908 void ResourcePrefetchPredictor::DeleteUrls(const history::URLRows& urls) { 564 void ResourcePrefetchPredictor::DeleteUrls(const history::URLRows& urls) {
909 std::vector<std::string> urls_to_delete; 565 std::vector<std::string> urls_to_delete;
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 if (data.resources_size() == 0) 1019 if (data.resources_size() == 0)
1364 resource_data->DeleteData({key}); 1020 resource_data->DeleteData({key});
1365 else 1021 else
1366 resource_data->UpdateData(key, data); 1022 resource_data->UpdateData(key, data);
1367 } 1023 }
1368 } 1024 }
1369 1025
1370 void ResourcePrefetchPredictor::ConnectToHistoryService() { 1026 void ResourcePrefetchPredictor::ConnectToHistoryService() {
1371 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1027 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1372 DCHECK_EQ(INITIALIZING, initialization_state_); 1028 DCHECK_EQ(INITIALIZING, initialization_state_);
1373 DCHECK(inflight_navigations_.empty());
1374 1029
1375 // Register for HistoryServiceLoading if it is not ready. 1030 // Register for HistoryServiceLoading if it is not ready.
1376 history::HistoryService* history_service = 1031 history::HistoryService* history_service =
1377 HistoryServiceFactory::GetForProfile(profile_, 1032 HistoryServiceFactory::GetForProfile(profile_,
1378 ServiceAccessType::EXPLICIT_ACCESS); 1033 ServiceAccessType::EXPLICIT_ACCESS);
1379 if (!history_service) 1034 if (!history_service)
1380 return; 1035 return;
1381 DCHECK(!history_service_observer_.IsObserving(history_service)); 1036 DCHECK(!history_service_observer_.IsObserving(history_service));
1382 history_service_observer_.Add(history_service); 1037 history_service_observer_.Add(history_service);
1383 if (history_service->BackendLoaded()) { 1038 if (history_service->BackendLoaded()) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1424 TestObserver::~TestObserver() { 1079 TestObserver::~TestObserver() {
1425 predictor_->SetObserverForTesting(nullptr); 1080 predictor_->SetObserverForTesting(nullptr);
1426 } 1081 }
1427 1082
1428 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) 1083 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor)
1429 : predictor_(predictor) { 1084 : predictor_(predictor) {
1430 predictor_->SetObserverForTesting(this); 1085 predictor_->SetObserverForTesting(this);
1431 } 1086 }
1432 1087
1433 } // namespace predictors 1088 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698