| Index: chrome/browser/predictors/resource_prefetch_predictor.cc
|
| diff --git a/chrome/browser/predictors/resource_prefetch_predictor.cc b/chrome/browser/predictors/resource_prefetch_predictor.cc
|
| index 7b9979906fb4a7a074304f966c5304088ed5fcee..69c2d5d2910e8655019ef0f57eaabfa56e7da376 100644
|
| --- a/chrome/browser/predictors/resource_prefetch_predictor.cc
|
| +++ b/chrome/browser/predictors/resource_prefetch_predictor.cc
|
| @@ -390,35 +390,41 @@ content::ResourceType ResourcePrefetchPredictor::GetResourceTypeFromMimeType(
|
| return fallback;
|
| }
|
|
|
| -// static
|
| bool ResourcePrefetchPredictor::GetRedirectEndpoint(
|
| - const std::string& first_redirect,
|
| + const std::string& entry_point,
|
| const RedirectDataMap& redirect_data_map,
|
| - std::string* final_redirect) {
|
| - DCHECK(final_redirect);
|
| + std::string* redirect_endpoint) const {
|
| + DCHECK(redirect_endpoint);
|
|
|
| - RedirectDataMap::const_iterator it = redirect_data_map.find(first_redirect);
|
| - if (it == redirect_data_map.end())
|
| - return false;
|
| + RedirectDataMap::const_iterator it = redirect_data_map.find(entry_point);
|
| + if (it == redirect_data_map.end()) {
|
| + // Fallback to fetching URLs based on the incoming URL/host.
|
| + *redirect_endpoint = entry_point;
|
| + return true;
|
| + }
|
|
|
| const RedirectData& redirect_data = it->second;
|
| - auto best_redirect = std::max_element(
|
| - redirect_data.redirect_endpoints().begin(),
|
| - redirect_data.redirect_endpoints().end(),
|
| - [](const RedirectStat& x, const RedirectStat& y) {
|
| - return ComputeRedirectConfidence(x) < ComputeRedirectConfidence(y);
|
| - });
|
| + DCHECK_GT(redirect_data.redirect_endpoints_size(), 0);
|
| + if (redirect_data.redirect_endpoints_size() > 1) {
|
| + // Predictor observed multiple redirect destinations recently. Redirect
|
| + // endpoint is ambiguous.
|
| + return false;
|
| + }
|
|
|
| - const float kMinRedirectConfidenceToTriggerPrefetch = 0.7f;
|
| + // The threshold is higher than the threshold for resources because the
|
| + // redirect misprediction causes the waste of whole prefetch.
|
| + const float kMinRedirectConfidenceToTriggerPrefetch = 0.9f;
|
| const int kMinRedirectHitsToTriggerPrefetch = 2;
|
|
|
| - if (best_redirect == redirect_data.redirect_endpoints().end() ||
|
| - ComputeRedirectConfidence(*best_redirect) <
|
| + const RedirectStat& redirect = redirect_data.redirect_endpoints(0);
|
| + if (ComputeRedirectConfidence(redirect) <
|
| kMinRedirectConfidenceToTriggerPrefetch ||
|
| - best_redirect->number_of_hits() < kMinRedirectHitsToTriggerPrefetch)
|
| + (redirect.number_of_hits() < kMinRedirectHitsToTriggerPrefetch &&
|
| + redirect.url() != entry_point)) {
|
| return false;
|
| + }
|
|
|
| - *final_redirect = best_redirect->url();
|
| + *redirect_endpoint = redirect.url();
|
| return true;
|
| }
|
|
|
| @@ -828,49 +834,30 @@ bool ResourcePrefetchPredictor::GetPrefetchData(
|
| prediction ? &prediction->subresource_urls : nullptr;
|
| DCHECK(!urls || urls->empty());
|
|
|
| - // Fetch URLs based on a redirect endpoint for URL/host first.
|
| + // Fetch resources using URL-keyed data first.
|
| std::string redirect_endpoint;
|
| + const std::string& main_frame_url_spec = main_frame_url.spec();
|
| if (config_.is_url_learning_enabled &&
|
| - GetRedirectEndpoint(main_frame_url.spec(), *url_redirect_table_cache_,
|
| + GetRedirectEndpoint(main_frame_url_spec, *url_redirect_table_cache_,
|
| &redirect_endpoint) &&
|
| PopulatePrefetcherRequest(redirect_endpoint, *url_table_cache_, urls)) {
|
| if (prediction) {
|
| prediction->is_host = false;
|
| - prediction->is_redirected = true;
|
| prediction->main_frame_key = redirect_endpoint;
|
| + prediction->is_redirected = (redirect_endpoint != main_frame_url_spec);
|
| }
|
| return true;
|
| }
|
|
|
| - if (GetRedirectEndpoint(main_frame_url.host(), *host_redirect_table_cache_,
|
| + // Use host data if the URL-based prediction isn't available.
|
| + std::string main_frame_url_host = main_frame_url.host();
|
| + if (GetRedirectEndpoint(main_frame_url_host, *host_redirect_table_cache_,
|
| &redirect_endpoint) &&
|
| PopulatePrefetcherRequest(redirect_endpoint, *host_table_cache_, urls)) {
|
| if (prediction) {
|
| prediction->is_host = true;
|
| - prediction->is_redirected = true;
|
| prediction->main_frame_key = redirect_endpoint;
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - // Fallback to fetching URLs based on the incoming URL/host.
|
| - if (config_.is_url_learning_enabled &&
|
| - PopulatePrefetcherRequest(main_frame_url.spec(), *url_table_cache_,
|
| - urls)) {
|
| - if (prediction) {
|
| - prediction->is_host = false;
|
| - prediction->is_redirected = false;
|
| - prediction->main_frame_key = main_frame_url.spec();
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - if (PopulatePrefetcherRequest(main_frame_url.host(), *host_table_cache_,
|
| - urls)) {
|
| - if (prediction) {
|
| - prediction->is_host = true;
|
| - prediction->is_redirected = false;
|
| - prediction->main_frame_key = main_frame_url.host();
|
| + prediction->is_redirected = (redirect_endpoint != main_frame_url_host);
|
| }
|
| return true;
|
| }
|
| @@ -1321,10 +1308,8 @@ void ResourcePrefetchPredictor::LearnNavigation(
|
| empty_redirect_data));
|
| }
|
|
|
| - if (key != key_before_redirects) {
|
| - LearnRedirect(key_before_redirects, key_type, key, max_data_map_size,
|
| - redirect_map);
|
| - }
|
| + LearnRedirect(key_before_redirects, key_type, key, max_data_map_size,
|
| + redirect_map);
|
| }
|
|
|
| void ResourcePrefetchPredictor::LearnRedirect(const std::string& key,
|
| @@ -1376,7 +1361,7 @@ void ResourcePrefetchPredictor::LearnRedirect(const std::string& key,
|
| RedirectData& data = cache_entry->second;
|
| // Trim the redirects after the update.
|
| ResourcePrefetchPredictorTables::TrimRedirects(
|
| - &data, config_.max_consecutive_misses);
|
| + &data, config_.max_redirect_consecutive_misses);
|
|
|
| if (data.redirect_endpoints_size() == 0) {
|
| redirect_map->erase(cache_entry);
|
|
|