Index: chrome/browser/predictors/resource_prefetch_common.cc |
diff --git a/chrome/browser/predictors/resource_prefetch_common.cc b/chrome/browser/predictors/resource_prefetch_common.cc |
index 731bda64f3922ff9c41f81c7ae561e1a5bea9c3a..d558eab5f0f7e4708c1f126f877a4edc3676167c 100644 |
--- a/chrome/browser/predictors/resource_prefetch_common.cc |
+++ b/chrome/browser/predictors/resource_prefetch_common.cc |
@@ -4,21 +4,52 @@ |
#include "chrome/browser/predictors/resource_prefetch_common.h" |
+#include <stdlib.h> |
+ |
#include "base/command_line.h" |
#include "base/metrics/field_trial.h" |
#include "base/prefs/pref_service.h" |
+#include "base/strings/string_split.h" |
+#include "chrome/browser/net/prediction_options.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/common/chrome_switches.h" |
#include "chrome/common/pref_names.h" |
+#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/render_process_host.h" |
#include "content/public/browser/render_view_host.h" |
#include "content/public/browser/web_contents.h" |
+using base::FieldTrialList; |
+using std::string; |
+using std::vector; |
+ |
namespace predictors { |
const char kSpeculativePrefetchingTrialName[] = |
"SpeculativeResourcePrefetching"; |
+/* |
+ * SpeculativeResourcePrefetching is a field trial, and its value must have the |
+ * following format: key1=value1:key2=value2:key3=value3 |
+ * e.g. "Prefetching=Enabled:Predictor=Url:Confidence=High" |
+ * The function below extracts the value corresponding to a key provided from |
+ * the SpeculativeResourcePrefetching field trial. |
+ */ |
+string GetFiledTrialSpecValue(string key) { |
+ vector<string> elements; |
+ base::SplitString( |
+ FieldTrialList::FindFullName(kSpeculativePrefetchingTrialName), |
+ ':', |
+ &elements); |
+ for (int i = 0; i < static_cast<int>(elements.size()); i++) { |
+ vector<string> key_value; |
+ base::SplitString(elements[i], '=', &key_value); |
+ if (key_value.size() == 2 && key_value[0] == key) |
+ return key_value[1]; |
+ } |
+ return string(); |
+} |
+ |
bool IsSpeculativeResourcePrefetchingEnabled( |
Profile* profile, |
ResourcePrefetchPredictorConfig* config) { |
@@ -28,14 +59,8 @@ bool IsSpeculativeResourcePrefetchingEnabled( |
if (!profile || profile->IsOffTheRecord()) |
return false; |
- // If the user has explicitly disabled "predictive actions" - disabled. |
- if (!profile->GetPrefs() || |
- !profile->GetPrefs()->GetBoolean(prefs::kNetworkPredictionEnabled)) { |
- return false; |
- } |
- |
- // The config has the default params already set. The command line with just |
- // enable them with the default params. |
+ // Enabled by command line switch. The config has the default params already |
+ // set. The command line with just enable them with the default params. |
if (CommandLine::ForCurrentProcess()->HasSwitch( |
switches::kSpeculativeResourcePrefetching)) { |
const std::string value = |
@@ -57,104 +82,73 @@ bool IsSpeculativeResourcePrefetchingEnabled( |
} |
} |
+ // Disable if no field trial is specified. |
std::string trial = base::FieldTrialList::FindFullName( |
- kSpeculativePrefetchingTrialName); |
- |
- if (trial == "LearningHost") { |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
- return true; |
- } else if (trial == "LearningURL") { |
- config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
- return true; |
- } else if (trial == "Learning") { |
- config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
- return true; |
- } else if (trial == "PrefetchingHost") { |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; |
- return true; |
- } else if (trial == "PrefetchingURL") { |
- config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
- config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; |
- return true; |
- } else if (trial == "Prefetching") { |
- config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
- config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; |
- return true; |
- } else if (trial == "PrefetchingLowConfidence") { |
- config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
- config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; |
+ kSpeculativePrefetchingTrialName); |
+ if (trial.empty()) |
+ return false; |
+ |
+ // Enabled by field trial. |
+ std::string spec_prefetching = GetFiledTrialSpecValue("Prefetching"); |
+ std::string spec_predictor = GetFiledTrialSpecValue("Predictor"); |
+ std::string spec_confidence = GetFiledTrialSpecValue("Confidence"); |
+ std::string spec_more_resources = GetFiledTrialSpecValue("MoreResources"); |
+ std::string spec_small_db = GetFiledTrialSpecValue("SmallDB"); |
+ if (spec_prefetching == "Learning") { |
+ if (spec_predictor == "Url") { |
+ config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
+ } else if (spec_predictor == "Host") { |
+ config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
+ } else { |
+ // Default: both Url and Host |
+ config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
+ config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
+ } |
+ } else if (spec_prefetching == "Enabled") { |
+ if (spec_predictor == "Url") { |
+ config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
+ config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; |
+ } else if (spec_predictor == "Host") { |
+ config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
+ config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; |
+ } else { |
+ // Default: both Url and Host |
+ config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
+ config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
+ config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; |
+ config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; |
+ } |
+ } else { |
+ // Default: spec_prefetching == "Disabled" |
+ return false; |
+ } |
+ |
+ if (spec_confidence == "Low") { |
config->min_url_visit_count = 1; |
config->min_resource_confidence_to_trigger_prefetch = 0.5f; |
config->min_resource_hits_to_trigger_prefetch = 1; |
- return true; |
- } else if (trial == "PrefetchingHighConfidence") { |
- config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
- config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; |
- |
+ } else if (spec_confidence == "High") { |
config->min_url_visit_count = 3; |
config->min_resource_confidence_to_trigger_prefetch = 0.9f; |
config->min_resource_hits_to_trigger_prefetch = 3; |
- return true; |
- } else if (trial == "PrefetchingMoreResources") { |
- config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
- config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; |
+ } else { |
+ // default |
+ config->min_url_visit_count = 2; |
+ config->min_resource_confidence_to_trigger_prefetch = 0.7f; |
+ config->min_resource_hits_to_trigger_prefetch = 2; |
+ } |
+ if (spec_more_resources == "Enabled") { |
config->max_resources_per_entry = 100; |
- return true; |
- } else if (trial == "LearningSmallDB") { |
- config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
- |
- config->max_urls_to_track = 200; |
- config->max_hosts_to_track = 100; |
- return true; |
- } else if (trial == "PrefetchingSmallDB") { |
- config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
- config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; |
- |
- config->max_urls_to_track = 200; |
- config->max_hosts_to_track = 100; |
- return true; |
- } else if (trial == "PrefetchingSmallDBLowConfidence") { |
- config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
- config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; |
- |
- config->max_urls_to_track = 200; |
- config->max_hosts_to_track = 100; |
- config->min_url_visit_count = 1; |
- config->min_resource_confidence_to_trigger_prefetch = 0.5f; |
- config->min_resource_hits_to_trigger_prefetch = 1; |
- return true; |
- } else if (trial == "PrefetchingSmallDBHighConfidence") { |
- config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING; |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING; |
- config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING; |
- config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING; |
+ } |
+ if (spec_small_db == "Enabled") { |
config->max_urls_to_track = 200; |
config->max_hosts_to_track = 100; |
- config->min_url_visit_count = 3; |
- config->min_resource_confidence_to_trigger_prefetch = 0.9f; |
- config->min_resource_hits_to_trigger_prefetch = 3; |
- return true; |
} |
- return false; |
+ return true; |
} |
NavigationID::NavigationID() |
@@ -209,8 +203,8 @@ ResourcePrefetchPredictorConfig::ResourcePrefetchPredictorConfig() |
min_url_visit_count(2), |
max_resources_per_entry(50), |
max_consecutive_misses(3), |
- min_resource_confidence_to_trigger_prefetch(0.8f), |
- min_resource_hits_to_trigger_prefetch(3), |
+ min_resource_confidence_to_trigger_prefetch(0.7f), |
+ min_resource_hits_to_trigger_prefetch(2), |
max_prefetches_inflight_per_navigation(24), |
max_prefetches_inflight_per_host_per_navigation(3) { |
} |
@@ -222,8 +216,9 @@ bool ResourcePrefetchPredictorConfig::IsLearningEnabled() const { |
return IsURLLearningEnabled() || IsHostLearningEnabled(); |
} |
-bool ResourcePrefetchPredictorConfig::IsPrefetchingEnabled() const { |
- return IsURLPrefetchingEnabled() || IsHostPrefetchingEnabled(); |
+bool ResourcePrefetchPredictorConfig::IsPrefetchingEnabled( |
+ Profile* profile) const { |
+ return IsURLPrefetchingEnabled(profile) || IsHostPrefetchingEnabled(profile); |
} |
bool ResourcePrefetchPredictorConfig::IsURLLearningEnabled() const { |
@@ -234,12 +229,44 @@ bool ResourcePrefetchPredictorConfig::IsHostLearningEnabled() const { |
return (mode & HOST_LEARNING) > 0; |
} |
-bool ResourcePrefetchPredictorConfig::IsURLPrefetchingEnabled() const { |
+bool ResourcePrefetchPredictorConfig::IsURLPrefetchingEnabled( |
+ Profile* profile) const { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ if (!profile || !profile->GetPrefs() || |
+ !chrome_browser_net::CanPrefetchAndPrerenderUI(profile->GetPrefs())) { |
+ return false; |
+ } |
return (mode & URL_PREFETCHING) > 0; |
} |
-bool ResourcePrefetchPredictorConfig::IsHostPrefetchingEnabled() const { |
+bool ResourcePrefetchPredictorConfig::IsHostPrefetchingEnabled( |
+ Profile* profile) const { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ if (!profile || !profile->GetPrefs() || |
+ !chrome_browser_net::CanPrefetchAndPrerenderUI(profile->GetPrefs())) { |
+ return false; |
+ } |
return (mode & HOST_PRFETCHING) > 0; |
} |
+bool ResourcePrefetchPredictorConfig::IsLowConfidenceForTest() const { |
+ return min_url_visit_count == 1 && |
+ std::abs(min_resource_confidence_to_trigger_prefetch - 0.5f) < 1e-6 && |
+ min_resource_hits_to_trigger_prefetch == 1; |
+} |
+ |
+bool ResourcePrefetchPredictorConfig::IsHighConfidenceForTest() const { |
+ return min_url_visit_count == 3 && |
+ std::abs(min_resource_confidence_to_trigger_prefetch - 0.9f) < 1e-6 && |
+ min_resource_hits_to_trigger_prefetch == 3; |
+} |
+ |
+bool ResourcePrefetchPredictorConfig::IsMoreResourcesEnabledForTest() const { |
+ return max_resources_per_entry == 100; |
+} |
+ |
+bool ResourcePrefetchPredictorConfig::IsSmallDBEnabledForTest() const { |
+ return max_urls_to_track == 200 && max_hosts_to_track == 100; |
+} |
+ |
} // namespace predictors |