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

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

Issue 2397943004: predictors: Use redirect data in prefetch. (Closed)
Patch Set: Add comments + std::max_element. Created 4 years, 2 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
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 "application/font-sfnt", 54 "application/font-sfnt",
55 "application/font-ttf"}; 55 "application/font-ttf"};
56 56
57 // For reporting events of interest that are not tied to any navigation. 57 // For reporting events of interest that are not tied to any navigation.
58 enum ReportingEvent { 58 enum ReportingEvent {
59 REPORTING_EVENT_ALL_HISTORY_CLEARED = 0, 59 REPORTING_EVENT_ALL_HISTORY_CLEARED = 0,
60 REPORTING_EVENT_PARTIAL_HISTORY_CLEARED = 1, 60 REPORTING_EVENT_PARTIAL_HISTORY_CLEARED = 1,
61 REPORTING_EVENT_COUNT = 2 61 REPORTING_EVENT_COUNT = 2
62 }; 62 };
63 63
64 float ComputeRedirectConfidence(const predictors::RedirectStat& redirect) {
65 return (redirect.number_of_hits() + 0.0) /
66 (redirect.number_of_hits() + redirect.number_of_misses());
67 }
68
64 } // namespace 69 } // namespace
65 70
66 namespace predictors { 71 namespace predictors {
67 72
68 //////////////////////////////////////////////////////////////////////////////// 73 ////////////////////////////////////////////////////////////////////////////////
69 // ResourcePrefetchPredictor static functions. 74 // ResourcePrefetchPredictor static functions.
70 75
71 // static 76 // static
72 bool ResourcePrefetchPredictor::ShouldRecordRequest( 77 bool ResourcePrefetchPredictor::ShouldRecordRequest(
73 net::URLRequest* request, 78 net::URLRequest* request,
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 std::any_of(std::begin(kFontMimeTypes), std::end(kFontMimeTypes), 208 std::any_of(std::begin(kFontMimeTypes), std::end(kFontMimeTypes),
204 [&mime_type](const std::string& mime) { 209 [&mime_type](const std::string& mime) {
205 return net::MatchesMimeType(mime, mime_type); 210 return net::MatchesMimeType(mime, mime_type);
206 }); 211 });
207 if (found) 212 if (found)
208 return content::RESOURCE_TYPE_FONT_RESOURCE; 213 return content::RESOURCE_TYPE_FONT_RESOURCE;
209 } 214 }
210 return fallback; 215 return fallback;
211 } 216 }
212 217
218 // static
219 bool ResourcePrefetchPredictor::GetRedirectEndpoint(
220 const std::string& first_redirect,
221 const RedirectDataMap& redirect_data_map,
222 std::string* final_redirect) {
223 DCHECK(final_redirect);
224
225 RedirectDataMap::const_iterator it = redirect_data_map.find(first_redirect);
226 if (it == redirect_data_map.end())
227 return false;
228
229 const RedirectData& redirect_data = it->second;
230 auto best_redirect = std::max_element(
231 redirect_data.redirect_endpoints().begin(),
232 redirect_data.redirect_endpoints().end(),
233 [](const RedirectStat& x, const RedirectStat& y) {
234 return ComputeRedirectConfidence(x) < ComputeRedirectConfidence(y);
235 });
236
237 const float kMinRedirectConfidenceToTriggerPrefetch = 0.7f;
238 const int kMinRedirectHitsToTriggerPrefetch = 2;
239
240 if (ComputeRedirectConfidence(*best_redirect) <
241 kMinRedirectConfidenceToTriggerPrefetch ||
242 best_redirect->number_of_hits() < kMinRedirectHitsToTriggerPrefetch)
243 return false;
244
245 *final_redirect = best_redirect->url();
246 return true;
247 }
248
213 //////////////////////////////////////////////////////////////////////////////// 249 ////////////////////////////////////////////////////////////////////////////////
214 // ResourcePrefetchPredictor nested types. 250 // ResourcePrefetchPredictor nested types.
215 251
216 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary() 252 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary()
217 : resource_type(content::RESOURCE_TYPE_LAST_TYPE), 253 : resource_type(content::RESOURCE_TYPE_LAST_TYPE),
218 priority(net::IDLE), 254 priority(net::IDLE),
219 was_cached(false), 255 was_cached(false),
220 has_validators(false), 256 has_validators(false),
221 always_revalidate(false) {} 257 always_revalidate(false) {}
222 258
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 if (initialization_state_ != INITIALIZED) 448 if (initialization_state_ != INITIALIZED)
413 return; 449 return;
414 450
415 StopPrefetching(response.navigation_id.main_frame_url); 451 StopPrefetching(response.navigation_id.main_frame_url);
416 } 452 }
417 453
418 void ResourcePrefetchPredictor::OnMainFrameRedirect( 454 void ResourcePrefetchPredictor::OnMainFrameRedirect(
419 const URLRequestSummary& response) { 455 const URLRequestSummary& response) {
420 DCHECK_CURRENTLY_ON(BrowserThread::UI); 456 DCHECK_CURRENTLY_ON(BrowserThread::UI);
421 457
422 // Stop any inflight prefetching. Remove the older navigation.
423 StopPrefetching(response.navigation_id.main_frame_url);
424
425 std::unique_ptr<PageRequestSummary> summary; 458 std::unique_ptr<PageRequestSummary> summary;
426 NavigationMap::iterator nav_it = 459 NavigationMap::iterator nav_it =
427 inflight_navigations_.find(response.navigation_id); 460 inflight_navigations_.find(response.navigation_id);
428 if (nav_it != inflight_navigations_.end()) { 461 if (nav_it != inflight_navigations_.end()) {
429 summary.reset(nav_it->second.release()); 462 summary.reset(nav_it->second.release());
430 inflight_navigations_.erase(nav_it); 463 inflight_navigations_.erase(nav_it);
431 } 464 }
432 465
433 // The redirect url may be empty if the URL was invalid. 466 // The redirect url may be empty if the URL was invalid.
434 if (response.redirect_url.is_empty()) 467 if (response.redirect_url.is_empty())
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( 518 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask(
486 navigation_id, std::move(summary), 519 navigation_id, std::move(summary),
487 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, 520 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup,
488 AsWeakPtr()))), 521 AsWeakPtr()))),
489 &history_lookup_consumer_); 522 &history_lookup_consumer_);
490 } 523 }
491 524
492 bool ResourcePrefetchPredictor::GetPrefetchData(const GURL& main_frame_url, 525 bool ResourcePrefetchPredictor::GetPrefetchData(const GURL& main_frame_url,
493 std::vector<GURL>* urls) { 526 std::vector<GURL>* urls) {
494 DCHECK(urls); 527 DCHECK(urls);
495 528 DCHECK(urls->empty());
496 bool use_url_data = config_.IsPrefetchingEnabled(profile_) ? 529 bool use_url_data = config_.IsPrefetchingEnabled(profile_) ?
497 config_.IsURLPrefetchingEnabled(profile_) : 530 config_.IsURLPrefetchingEnabled(profile_) :
498 config_.IsURLLearningEnabled(); 531 config_.IsURLLearningEnabled();
499 if (use_url_data) {
500 PrefetchDataMap::const_iterator iterator =
501 url_table_cache_->find(main_frame_url.spec());
502 if (iterator != url_table_cache_->end())
503 PopulatePrefetcherRequest(iterator->second, urls);
504 }
505 if (!urls->empty())
506 return true;
507
508 bool use_host_data = config_.IsPrefetchingEnabled(profile_) ? 532 bool use_host_data = config_.IsPrefetchingEnabled(profile_) ?
509 config_.IsHostPrefetchingEnabled(profile_) : 533 config_.IsHostPrefetchingEnabled(profile_) :
510 config_.IsHostLearningEnabled(); 534 config_.IsHostLearningEnabled();
511 if (use_host_data) { 535
512 PrefetchDataMap::const_iterator iterator = 536 // Attempt to fetch URLs based on the incoming URL/host.
Benoit L 2016/10/10 15:56:04 I'm not sure that's the policy we want, though I'm
alexilin 2016/10/11 13:14:41 So, do you suggest that we should fetch resources
Benoit L 2016/10/11 13:37:11 I think that what you suggest is better than what'
alexilin 2016/10/11 14:00:35 Done.
513 host_table_cache_->find(main_frame_url.host()); 537 if (use_url_data && PopulatePrefetcherRequest(main_frame_url.spec(),
514 if (iterator != host_table_cache_->end()) 538 *url_table_cache_, urls)) {
515 PopulatePrefetcherRequest(iterator->second, urls); 539 return true;
516 } 540 }
517 541
518 return !urls->empty(); 542 if (use_host_data && PopulatePrefetcherRequest(main_frame_url.host(),
543 *host_table_cache_, urls)) {
544 return true;
545 }
546
547 // Fallback to fetching URLs based on a redirect endpoint for URL/host.
548 std::string redirect_endpoint;
549 if (GetRedirectEndpoint(main_frame_url.spec(), *url_redirect_table_cache_,
550 &redirect_endpoint)) {
551 GURL redirect_endpoint_url(redirect_endpoint);
552
553 if (use_url_data && PopulatePrefetcherRequest(redirect_endpoint_url.spec(),
554 *url_table_cache_, urls)) {
555 return true;
556 }
557
558 if (use_host_data && PopulatePrefetcherRequest(redirect_endpoint_url.host(),
559 *host_table_cache_, urls)) {
560 return true;
561 }
562 }
563
564 return use_host_data &&
565 GetRedirectEndpoint(main_frame_url.host(), *host_redirect_table_cache_,
566 &redirect_endpoint) &&
567 PopulatePrefetcherRequest(redirect_endpoint, *host_table_cache_, urls);
519 } 568 }
520 569
521 void ResourcePrefetchPredictor::PopulatePrefetcherRequest( 570 bool ResourcePrefetchPredictor::PopulatePrefetcherRequest(
522 const PrefetchData& data, 571 const std::string& main_frame_key,
572 const PrefetchDataMap& data_map,
523 std::vector<GURL>* urls) { 573 std::vector<GURL>* urls) {
524 for (const ResourceData& resource : data.resources()) { 574 DCHECK(urls);
575 PrefetchDataMap::const_iterator it = data_map.find(main_frame_key);
576 if (it == data_map.end())
577 return false;
578
579 size_t initial_size = urls->size();
580 for (const ResourceData& resource : it->second.resources()) {
525 float confidence = 581 float confidence =
526 static_cast<float>(resource.number_of_hits()) / 582 static_cast<float>(resource.number_of_hits()) /
527 (resource.number_of_hits() + resource.number_of_misses()); 583 (resource.number_of_hits() + resource.number_of_misses());
528 if (confidence < config_.min_resource_confidence_to_trigger_prefetch || 584 if (confidence < config_.min_resource_confidence_to_trigger_prefetch ||
529 resource.number_of_hits() < 585 resource.number_of_hits() <
530 config_.min_resource_hits_to_trigger_prefetch) { 586 config_.min_resource_hits_to_trigger_prefetch)
531 continue; 587 continue;
532 }
533 588
534 urls->push_back(GURL(resource.resource_url())); 589 urls->push_back(GURL(resource.resource_url()));
535 } 590 }
591
592 return urls->size() > initial_size;
536 } 593 }
537 594
538 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url) { 595 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url) {
539 if (!prefetch_manager_.get()) // Prefetching not enabled. 596 if (!prefetch_manager_.get()) // Prefetching not enabled.
540 return; 597 return;
541 598
542 std::vector<GURL> subresource_urls; 599 std::vector<GURL> subresource_urls;
543 if (!GetPrefetchData(url, &subresource_urls)) { 600 if (!GetPrefetchData(url, &subresource_urls)) {
544 // No prefetching data at host or URL level. 601 // No prefetching data at host or URL level.
545 return; 602 return;
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 } 1050 }
994 1051
995 if (need_to_add) { 1052 if (need_to_add) {
996 RedirectStat* redirect_to_add = data.add_redirect_endpoints(); 1053 RedirectStat* redirect_to_add = data.add_redirect_endpoints();
997 redirect_to_add->set_url(final_redirect); 1054 redirect_to_add->set_url(final_redirect);
998 redirect_to_add->set_number_of_hits(1); 1055 redirect_to_add->set_number_of_hits(1);
999 } 1056 }
1000 } 1057 }
1001 1058
1002 RedirectData& data = cache_entry->second; 1059 RedirectData& data = cache_entry->second;
1003 // Trim and sort the redirects after the update. 1060 // Trim the redirects after the update.
1004 ResourcePrefetchPredictorTables::TrimRedirects( 1061 ResourcePrefetchPredictorTables::TrimRedirects(
1005 &data, config_.max_consecutive_misses); 1062 &data, config_.max_consecutive_misses);
1006 ResourcePrefetchPredictorTables::SortRedirects(&data);
1007 1063
1008 if (data.redirect_endpoints_size() == 0) { 1064 if (data.redirect_endpoints_size() == 0) {
1009 redirect_map->erase(cache_entry); 1065 redirect_map->erase(cache_entry);
1010 BrowserThread::PostTask( 1066 BrowserThread::PostTask(
1011 BrowserThread::DB, FROM_HERE, 1067 BrowserThread::DB, FROM_HERE,
1012 base::Bind( 1068 base::Bind(
1013 &ResourcePrefetchPredictorTables::DeleteSingleRedirectDataPoint, 1069 &ResourcePrefetchPredictorTables::DeleteSingleRedirectDataPoint,
1014 tables_, key, key_type)); 1070 tables_, key, key_type));
1015 } else { 1071 } else {
1016 RedirectData empty_redirect_data; 1072 RedirectData empty_redirect_data;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 // HistoryService is already loaded. Continue with Initialization. 1124 // HistoryService is already loaded. Continue with Initialization.
1069 OnHistoryAndCacheLoaded(); 1125 OnHistoryAndCacheLoaded();
1070 return; 1126 return;
1071 } 1127 }
1072 DCHECK(!history_service_observer_.IsObserving(history_service)); 1128 DCHECK(!history_service_observer_.IsObserving(history_service));
1073 history_service_observer_.Add(history_service); 1129 history_service_observer_.Add(history_service);
1074 return; 1130 return;
1075 } 1131 }
1076 1132
1077 } // namespace predictors 1133 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698