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

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

Issue 2800783002: predictors: Several improvements for redirects database. (Closed)
Patch Set: Rebase. Created 3 years, 8 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 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 std::any_of(std::begin(kFontMimeTypes), std::end(kFontMimeTypes), 391 std::any_of(std::begin(kFontMimeTypes), std::end(kFontMimeTypes),
392 [&mime_type](const std::string& mime) { 392 [&mime_type](const std::string& mime) {
393 return net::MatchesMimeType(mime, mime_type); 393 return net::MatchesMimeType(mime, mime_type);
394 }); 394 });
395 if (found) 395 if (found)
396 return content::RESOURCE_TYPE_FONT_RESOURCE; 396 return content::RESOURCE_TYPE_FONT_RESOURCE;
397 } 397 }
398 return fallback; 398 return fallback;
399 } 399 }
400 400
401 // static
402 bool ResourcePrefetchPredictor::GetRedirectEndpoint( 401 bool ResourcePrefetchPredictor::GetRedirectEndpoint(
403 const std::string& first_redirect, 402 const std::string& entry_point,
404 const RedirectDataMap& redirect_data_map, 403 const RedirectDataMap& redirect_data_map,
405 std::string* final_redirect) { 404 std::string* redirect_endpoint) const {
406 DCHECK(final_redirect); 405 DCHECK(redirect_endpoint);
407 406
408 RedirectDataMap::const_iterator it = redirect_data_map.find(first_redirect); 407 RedirectDataMap::const_iterator it = redirect_data_map.find(entry_point);
409 if (it == redirect_data_map.end()) 408 if (it == redirect_data_map.end()) {
410 return false; 409 // Fallback to fetching URLs based on the incoming URL/host. By default
410 // the predictor is confident that there is no redirect.
411 *redirect_endpoint = entry_point;
412 return true;
413 }
411 414
412 const RedirectData& redirect_data = it->second; 415 const RedirectData& redirect_data = it->second;
413 auto best_redirect = std::max_element( 416 DCHECK_GT(redirect_data.redirect_endpoints_size(), 0);
414 redirect_data.redirect_endpoints().begin(), 417 if (redirect_data.redirect_endpoints_size() > 1) {
415 redirect_data.redirect_endpoints().end(), 418 // The predictor observed multiple redirect destinations recently. Redirect
416 [](const RedirectStat& x, const RedirectStat& y) { 419 // endpoint is ambiguous. The predictor predicts a redirect only if it
417 return ComputeRedirectConfidence(x) < ComputeRedirectConfidence(y); 420 // believes that the redirect is "permanent", i.e. subsequent navigations
418 }); 421 // will lead to the same destination.
422 return false;
423 }
419 424
420 const float kMinRedirectConfidenceToTriggerPrefetch = 0.7f; 425 // The threshold is higher than the threshold for resources because the
426 // redirect misprediction causes the waste of whole prefetch.
427 const float kMinRedirectConfidenceToTriggerPrefetch = 0.9f;
421 const int kMinRedirectHitsToTriggerPrefetch = 2; 428 const int kMinRedirectHitsToTriggerPrefetch = 2;
422 429
423 if (best_redirect == redirect_data.redirect_endpoints().end() || 430 // The predictor doesn't apply a minimum-number-of-hits threshold to
424 ComputeRedirectConfidence(*best_redirect) < 431 // the no-redirect case because the no-redirect is a default assumption.
432 const RedirectStat& redirect = redirect_data.redirect_endpoints(0);
433 if (ComputeRedirectConfidence(redirect) <
425 kMinRedirectConfidenceToTriggerPrefetch || 434 kMinRedirectConfidenceToTriggerPrefetch ||
426 best_redirect->number_of_hits() < kMinRedirectHitsToTriggerPrefetch) 435 (redirect.number_of_hits() < kMinRedirectHitsToTriggerPrefetch &&
436 redirect.url() != entry_point)) {
427 return false; 437 return false;
438 }
428 439
429 *final_redirect = best_redirect->url(); 440 *redirect_endpoint = redirect.url();
430 return true; 441 return true;
431 } 442 }
432 443
433 // static 444 // static
434 void ResourcePrefetchPredictor::SetAllowPortInUrlsForTesting(bool state) { 445 void ResourcePrefetchPredictor::SetAllowPortInUrlsForTesting(bool state) {
435 g_allow_port_in_urls = state; 446 g_allow_port_in_urls = state;
436 } 447 }
437 448
438 //////////////////////////////////////////////////////////////////////////////// 449 ////////////////////////////////////////////////////////////////////////////////
439 // ResourcePrefetchPredictor nested types. 450 // ResourcePrefetchPredictor nested types.
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 } 873 }
863 } 874 }
864 875
865 bool ResourcePrefetchPredictor::GetPrefetchData( 876 bool ResourcePrefetchPredictor::GetPrefetchData(
866 const GURL& main_frame_url, 877 const GURL& main_frame_url,
867 ResourcePrefetchPredictor::Prediction* prediction) const { 878 ResourcePrefetchPredictor::Prediction* prediction) const {
868 std::vector<GURL>* urls = 879 std::vector<GURL>* urls =
869 prediction ? &prediction->subresource_urls : nullptr; 880 prediction ? &prediction->subresource_urls : nullptr;
870 DCHECK(!urls || urls->empty()); 881 DCHECK(!urls || urls->empty());
871 882
872 // Fetch URLs based on a redirect endpoint for URL/host first. 883 // Fetch resources using URL-keyed data first.
873 std::string redirect_endpoint; 884 std::string redirect_endpoint;
885 const std::string& main_frame_url_spec = main_frame_url.spec();
874 if (config_.is_url_learning_enabled && 886 if (config_.is_url_learning_enabled &&
875 GetRedirectEndpoint(main_frame_url.spec(), *url_redirect_table_cache_, 887 GetRedirectEndpoint(main_frame_url_spec, *url_redirect_table_cache_,
876 &redirect_endpoint) && 888 &redirect_endpoint) &&
877 PopulatePrefetcherRequest(redirect_endpoint, *url_table_cache_, urls)) { 889 PopulatePrefetcherRequest(redirect_endpoint, *url_table_cache_, urls)) {
878 if (prediction) { 890 if (prediction) {
879 prediction->is_host = false; 891 prediction->is_host = false;
880 prediction->is_redirected = true;
881 prediction->main_frame_key = redirect_endpoint; 892 prediction->main_frame_key = redirect_endpoint;
893 prediction->is_redirected = (redirect_endpoint != main_frame_url_spec);
882 } 894 }
883 return true; 895 return true;
884 } 896 }
885 897
886 if (GetRedirectEndpoint(main_frame_url.host(), *host_redirect_table_cache_, 898 // Use host data if the URL-based prediction isn't available.
899 std::string main_frame_url_host = main_frame_url.host();
900 if (GetRedirectEndpoint(main_frame_url_host, *host_redirect_table_cache_,
887 &redirect_endpoint) && 901 &redirect_endpoint) &&
888 PopulatePrefetcherRequest(redirect_endpoint, *host_table_cache_, urls)) { 902 PopulatePrefetcherRequest(redirect_endpoint, *host_table_cache_, urls)) {
889 if (prediction) { 903 if (prediction) {
890 prediction->is_host = true; 904 prediction->is_host = true;
891 prediction->is_redirected = true;
892 prediction->main_frame_key = redirect_endpoint; 905 prediction->main_frame_key = redirect_endpoint;
906 prediction->is_redirected = (redirect_endpoint != main_frame_url_host);
893 } 907 }
894 return true; 908 return true;
895 } 909 }
896
897 // Fallback to fetching URLs based on the incoming URL/host.
898 if (config_.is_url_learning_enabled &&
899 PopulatePrefetcherRequest(main_frame_url.spec(), *url_table_cache_,
900 urls)) {
901 if (prediction) {
902 prediction->is_host = false;
903 prediction->is_redirected = false;
904 prediction->main_frame_key = main_frame_url.spec();
905 }
906 return true;
907 }
908
909 if (PopulatePrefetcherRequest(main_frame_url.host(), *host_table_cache_,
910 urls)) {
911 if (prediction) {
912 prediction->is_host = true;
913 prediction->is_redirected = false;
914 prediction->main_frame_key = main_frame_url.host();
915 }
916 return true;
917 }
918 910
919 return false; 911 return false;
920 } 912 }
921 913
922 bool ResourcePrefetchPredictor::PopulatePrefetcherRequest( 914 bool ResourcePrefetchPredictor::PopulatePrefetcherRequest(
923 const std::string& main_frame_key, 915 const std::string& main_frame_key,
924 const PrefetchDataMap& data_map, 916 const PrefetchDataMap& data_map,
925 std::vector<GURL>* urls) const { 917 std::vector<GURL>* urls) const {
926 PrefetchDataMap::const_iterator it = data_map.find(main_frame_key); 918 PrefetchDataMap::const_iterator it = data_map.find(main_frame_key);
927 if (it == data_map.end()) 919 if (it == data_map.end())
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; 1392 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST;
1401 const PrefetchData& host_data = is_host ? data : empty_data; 1393 const PrefetchData& host_data = is_host ? data : empty_data;
1402 const PrefetchData& url_data = is_host ? empty_data : data; 1394 const PrefetchData& url_data = is_host ? empty_data : data;
1403 BrowserThread::PostTask( 1395 BrowserThread::PostTask(
1404 BrowserThread::DB, FROM_HERE, 1396 BrowserThread::DB, FROM_HERE,
1405 base::Bind(&ResourcePrefetchPredictorTables::UpdateData, tables_, 1397 base::Bind(&ResourcePrefetchPredictorTables::UpdateData, tables_,
1406 url_data, host_data, empty_redirect_data, 1398 url_data, host_data, empty_redirect_data,
1407 empty_redirect_data)); 1399 empty_redirect_data));
1408 } 1400 }
1409 1401
1410 if (key != key_before_redirects) { 1402 // Predictor learns about both redirected and non-redirected destinations to
1411 LearnRedirect(key_before_redirects, key_type, key, max_data_map_size, 1403 // estimate whether the endpoint is permanent.
1412 redirect_map); 1404 LearnRedirect(key_before_redirects, key_type, key, max_data_map_size,
1413 } 1405 redirect_map);
1414 } 1406 }
1415 1407
1416 void ResourcePrefetchPredictor::LearnRedirect(const std::string& key, 1408 void ResourcePrefetchPredictor::LearnRedirect(const std::string& key,
1417 PrefetchKeyType key_type, 1409 PrefetchKeyType key_type,
1418 const std::string& final_redirect, 1410 const std::string& final_redirect,
1419 size_t max_redirect_map_size, 1411 size_t max_redirect_map_size,
1420 RedirectDataMap* redirect_map) { 1412 RedirectDataMap* redirect_map) {
1421 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1413 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1422 // If the primary key is too long reject it. 1414 // If the primary key is too long reject it.
1423 if (key.length() > ResourcePrefetchPredictorTables::kMaxStringLength) 1415 if (key.length() > ResourcePrefetchPredictorTables::kMaxStringLength)
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1455 if (need_to_add) { 1447 if (need_to_add) {
1456 RedirectStat* redirect_to_add = data.add_redirect_endpoints(); 1448 RedirectStat* redirect_to_add = data.add_redirect_endpoints();
1457 redirect_to_add->set_url(final_redirect); 1449 redirect_to_add->set_url(final_redirect);
1458 redirect_to_add->set_number_of_hits(1); 1450 redirect_to_add->set_number_of_hits(1);
1459 } 1451 }
1460 } 1452 }
1461 1453
1462 RedirectData& data = cache_entry->second; 1454 RedirectData& data = cache_entry->second;
1463 // Trim the redirects after the update. 1455 // Trim the redirects after the update.
1464 ResourcePrefetchPredictorTables::TrimRedirects( 1456 ResourcePrefetchPredictorTables::TrimRedirects(
1465 &data, config_.max_consecutive_misses); 1457 &data, config_.max_redirect_consecutive_misses);
1466 1458
1467 if (data.redirect_endpoints_size() == 0) { 1459 if (data.redirect_endpoints_size() == 0) {
1468 redirect_map->erase(cache_entry); 1460 redirect_map->erase(cache_entry);
1469 BrowserThread::PostTask( 1461 BrowserThread::PostTask(
1470 BrowserThread::DB, FROM_HERE, 1462 BrowserThread::DB, FROM_HERE,
1471 base::Bind( 1463 base::Bind(
1472 &ResourcePrefetchPredictorTables::DeleteSingleRedirectDataPoint, 1464 &ResourcePrefetchPredictorTables::DeleteSingleRedirectDataPoint,
1473 tables_, key, key_type)); 1465 tables_, key, key_type));
1474 } else { 1466 } else {
1475 RedirectData empty_redirect_data; 1467 RedirectData empty_redirect_data;
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
1706 TestObserver::~TestObserver() { 1698 TestObserver::~TestObserver() {
1707 predictor_->SetObserverForTesting(nullptr); 1699 predictor_->SetObserverForTesting(nullptr);
1708 } 1700 }
1709 1701
1710 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) 1702 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor)
1711 : predictor_(predictor) { 1703 : predictor_(predictor) {
1712 predictor_->SetObserverForTesting(this); 1704 predictor_->SetObserverForTesting(this);
1713 } 1705 }
1714 1706
1715 } // namespace predictors 1707 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698