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

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

Issue 2397943004: predictors: Use redirect data in prefetch. (Closed)
Patch Set: Non-empty check. 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 (best_redirect == redirect_data.redirect_endpoints().end() ||
241 ComputeRedirectConfidence(*best_redirect) <
242 kMinRedirectConfidenceToTriggerPrefetch ||
243 best_redirect->number_of_hits() < kMinRedirectHitsToTriggerPrefetch)
244 return false;
245
246 *final_redirect = best_redirect->url();
247 return true;
248 }
249
213 //////////////////////////////////////////////////////////////////////////////// 250 ////////////////////////////////////////////////////////////////////////////////
214 // ResourcePrefetchPredictor nested types. 251 // ResourcePrefetchPredictor nested types.
215 252
216 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary() 253 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary()
217 : resource_type(content::RESOURCE_TYPE_LAST_TYPE), 254 : resource_type(content::RESOURCE_TYPE_LAST_TYPE),
218 priority(net::IDLE), 255 priority(net::IDLE),
219 was_cached(false), 256 was_cached(false),
220 has_validators(false), 257 has_validators(false),
221 always_revalidate(false) {} 258 always_revalidate(false) {}
222 259
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 if (initialization_state_ != INITIALIZED) 449 if (initialization_state_ != INITIALIZED)
413 return; 450 return;
414 451
415 StopPrefetching(response.navigation_id.main_frame_url); 452 StopPrefetching(response.navigation_id.main_frame_url);
416 } 453 }
417 454
418 void ResourcePrefetchPredictor::OnMainFrameRedirect( 455 void ResourcePrefetchPredictor::OnMainFrameRedirect(
419 const URLRequestSummary& response) { 456 const URLRequestSummary& response) {
420 DCHECK_CURRENTLY_ON(BrowserThread::UI); 457 DCHECK_CURRENTLY_ON(BrowserThread::UI);
421 458
422 // Stop any inflight prefetching. Remove the older navigation.
423 StopPrefetching(response.navigation_id.main_frame_url);
424
425 std::unique_ptr<PageRequestSummary> summary; 459 std::unique_ptr<PageRequestSummary> summary;
426 NavigationMap::iterator nav_it = 460 NavigationMap::iterator nav_it =
427 inflight_navigations_.find(response.navigation_id); 461 inflight_navigations_.find(response.navigation_id);
428 if (nav_it != inflight_navigations_.end()) { 462 if (nav_it != inflight_navigations_.end()) {
429 summary.reset(nav_it->second.release()); 463 summary.reset(nav_it->second.release());
430 inflight_navigations_.erase(nav_it); 464 inflight_navigations_.erase(nav_it);
431 } 465 }
432 466
433 // The redirect url may be empty if the URL was invalid. 467 // The redirect url may be empty if the URL was invalid.
434 if (response.redirect_url.is_empty()) 468 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( 519 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask(
486 navigation_id, std::move(summary), 520 navigation_id, std::move(summary),
487 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, 521 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup,
488 AsWeakPtr()))), 522 AsWeakPtr()))),
489 &history_lookup_consumer_); 523 &history_lookup_consumer_);
490 } 524 }
491 525
492 bool ResourcePrefetchPredictor::GetPrefetchData(const GURL& main_frame_url, 526 bool ResourcePrefetchPredictor::GetPrefetchData(const GURL& main_frame_url,
493 std::vector<GURL>* urls) { 527 std::vector<GURL>* urls) {
494 DCHECK(urls); 528 DCHECK(urls);
495 529 DCHECK(urls->empty());
496 bool use_url_data = config_.IsPrefetchingEnabled(profile_) ? 530 bool use_url_data = config_.IsPrefetchingEnabled(profile_) ?
497 config_.IsURLPrefetchingEnabled(profile_) : 531 config_.IsURLPrefetchingEnabled(profile_) :
498 config_.IsURLLearningEnabled(); 532 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_) ? 533 bool use_host_data = config_.IsPrefetchingEnabled(profile_) ?
509 config_.IsHostPrefetchingEnabled(profile_) : 534 config_.IsHostPrefetchingEnabled(profile_) :
510 config_.IsHostLearningEnabled(); 535 config_.IsHostLearningEnabled();
511 if (use_host_data) { 536
512 PrefetchDataMap::const_iterator iterator = 537 // Fetch URLs based on a redirect endpoint for URL/host first.
513 host_table_cache_->find(main_frame_url.host()); 538 std::string redirect_endpoint;
514 if (iterator != host_table_cache_->end()) 539 if (use_url_data &&
515 PopulatePrefetcherRequest(iterator->second, urls); 540 GetRedirectEndpoint(main_frame_url.spec(), *url_redirect_table_cache_,
541 &redirect_endpoint) &&
542 PopulatePrefetcherRequest(redirect_endpoint, *url_table_cache_, urls)) {
543 return true;
516 } 544 }
517 545
518 return !urls->empty(); 546 if (use_host_data &&
547 GetRedirectEndpoint(main_frame_url.host(), *host_redirect_table_cache_,
548 &redirect_endpoint) &&
549 PopulatePrefetcherRequest(redirect_endpoint, *host_table_cache_, urls)) {
550 return true;
551 }
552
553 // Fallback to fetching URLs based on the incoming URL/host.
554 if (use_url_data && PopulatePrefetcherRequest(main_frame_url.spec(),
555 *url_table_cache_, urls)) {
556 return true;
557 }
558
559 return use_host_data && PopulatePrefetcherRequest(main_frame_url.host(),
560 *host_table_cache_, urls);
519 } 561 }
520 562
521 void ResourcePrefetchPredictor::PopulatePrefetcherRequest( 563 bool ResourcePrefetchPredictor::PopulatePrefetcherRequest(
522 const PrefetchData& data, 564 const std::string& main_frame_key,
565 const PrefetchDataMap& data_map,
523 std::vector<GURL>* urls) { 566 std::vector<GURL>* urls) {
524 for (const ResourceData& resource : data.resources()) { 567 DCHECK(urls);
568 PrefetchDataMap::const_iterator it = data_map.find(main_frame_key);
569 if (it == data_map.end())
570 return false;
571
572 size_t initial_size = urls->size();
573 for (const ResourceData& resource : it->second.resources()) {
525 float confidence = 574 float confidence =
526 static_cast<float>(resource.number_of_hits()) / 575 static_cast<float>(resource.number_of_hits()) /
527 (resource.number_of_hits() + resource.number_of_misses()); 576 (resource.number_of_hits() + resource.number_of_misses());
528 if (confidence < config_.min_resource_confidence_to_trigger_prefetch || 577 if (confidence < config_.min_resource_confidence_to_trigger_prefetch ||
529 resource.number_of_hits() < 578 resource.number_of_hits() <
530 config_.min_resource_hits_to_trigger_prefetch) { 579 config_.min_resource_hits_to_trigger_prefetch)
531 continue; 580 continue;
532 }
533 581
534 urls->push_back(GURL(resource.resource_url())); 582 urls->push_back(GURL(resource.resource_url()));
535 } 583 }
584
585 return urls->size() > initial_size;
536 } 586 }
537 587
538 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url) { 588 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url) {
539 if (!prefetch_manager_.get()) // Prefetching not enabled. 589 if (!prefetch_manager_.get()) // Prefetching not enabled.
540 return; 590 return;
541 591
542 std::vector<GURL> subresource_urls; 592 std::vector<GURL> subresource_urls;
543 if (!GetPrefetchData(url, &subresource_urls)) { 593 if (!GetPrefetchData(url, &subresource_urls)) {
544 // No prefetching data at host or URL level. 594 // No prefetching data at host or URL level.
545 return; 595 return;
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 } 1043 }
994 1044
995 if (need_to_add) { 1045 if (need_to_add) {
996 RedirectStat* redirect_to_add = data.add_redirect_endpoints(); 1046 RedirectStat* redirect_to_add = data.add_redirect_endpoints();
997 redirect_to_add->set_url(final_redirect); 1047 redirect_to_add->set_url(final_redirect);
998 redirect_to_add->set_number_of_hits(1); 1048 redirect_to_add->set_number_of_hits(1);
999 } 1049 }
1000 } 1050 }
1001 1051
1002 RedirectData& data = cache_entry->second; 1052 RedirectData& data = cache_entry->second;
1003 // Trim and sort the redirects after the update. 1053 // Trim the redirects after the update.
1004 ResourcePrefetchPredictorTables::TrimRedirects( 1054 ResourcePrefetchPredictorTables::TrimRedirects(
1005 &data, config_.max_consecutive_misses); 1055 &data, config_.max_consecutive_misses);
1006 ResourcePrefetchPredictorTables::SortRedirects(&data);
1007 1056
1008 if (data.redirect_endpoints_size() == 0) { 1057 if (data.redirect_endpoints_size() == 0) {
1009 redirect_map->erase(cache_entry); 1058 redirect_map->erase(cache_entry);
1010 BrowserThread::PostTask( 1059 BrowserThread::PostTask(
1011 BrowserThread::DB, FROM_HERE, 1060 BrowserThread::DB, FROM_HERE,
1012 base::Bind( 1061 base::Bind(
1013 &ResourcePrefetchPredictorTables::DeleteSingleRedirectDataPoint, 1062 &ResourcePrefetchPredictorTables::DeleteSingleRedirectDataPoint,
1014 tables_, key, key_type)); 1063 tables_, key, key_type));
1015 } else { 1064 } else {
1016 RedirectData empty_redirect_data; 1065 RedirectData empty_redirect_data;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 // HistoryService is already loaded. Continue with Initialization. 1117 // HistoryService is already loaded. Continue with Initialization.
1069 OnHistoryAndCacheLoaded(); 1118 OnHistoryAndCacheLoaded();
1070 return; 1119 return;
1071 } 1120 }
1072 DCHECK(!history_service_observer_.IsObserving(history_service)); 1121 DCHECK(!history_service_observer_.IsObserving(history_service));
1073 history_service_observer_.Add(history_service); 1122 history_service_observer_.Add(history_service);
1074 return; 1123 return;
1075 } 1124 }
1076 1125
1077 } // namespace predictors 1126 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698