Home | History | Annotate | Download | only in predictors
      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
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/predictors/resource_prefetch_common.h"
      6 
      7 #include "base/command_line.h"
      8 #include "base/metrics/field_trial.h"
      9 #include "base/prefs/pref_service.h"
     10 #include "chrome/browser/profiles/profile.h"
     11 #include "chrome/common/chrome_switches.h"
     12 #include "chrome/common/pref_names.h"
     13 #include "content/public/browser/render_process_host.h"
     14 #include "content/public/browser/render_view_host.h"
     15 #include "content/public/browser/web_contents.h"
     16 
     17 namespace predictors {
     18 
     19 const char kSpeculativePrefetchingTrialName[] =
     20     "SpeculativeResourcePrefetching";
     21 
     22 bool IsSpeculativeResourcePrefetchingEnabled(
     23     Profile* profile,
     24     ResourcePrefetchPredictorConfig* config) {
     25   DCHECK(config);
     26 
     27   // Off the record - disabled.
     28   if (!profile || profile->IsOffTheRecord())
     29     return false;
     30 
     31   // If the user has explicitly disabled "predictive actions" - disabled.
     32   if (!profile->GetPrefs() ||
     33       !profile->GetPrefs()->GetBoolean(prefs::kNetworkPredictionEnabled)) {
     34     return false;
     35   }
     36 
     37   // The config has the default params already set. The command line with just
     38   // enable them with the default params.
     39   if (CommandLine::ForCurrentProcess()->HasSwitch(
     40           switches::kSpeculativeResourcePrefetching)) {
     41     const std::string value =
     42         CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
     43             switches::kSpeculativeResourcePrefetching);
     44 
     45     if (value == switches::kSpeculativeResourcePrefetchingDisabled) {
     46       return false;
     47     } else if (value == switches::kSpeculativeResourcePrefetchingLearning) {
     48       config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING;
     49       config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING;
     50       return true;
     51     } else if (value == switches::kSpeculativeResourcePrefetchingEnabled) {
     52       config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING;
     53       config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING;
     54       config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING;
     55       config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING;
     56       return true;
     57     }
     58   }
     59 
     60   std::string trial = base::FieldTrialList::FindFullName(
     61       kSpeculativePrefetchingTrialName);
     62 
     63   if (trial == "LearningHost") {
     64     config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING;
     65     return true;
     66   } else if (trial == "LearningURL") {
     67     config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING;
     68     return true;
     69   } else if (trial == "Learning") {
     70     config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING;
     71     config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING;
     72     return true;
     73   } else if (trial == "PrefetchingHost") {
     74     config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING;
     75     config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING;
     76     return true;
     77   } else if (trial == "PrefetchingURL") {
     78     config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING;
     79     config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING;
     80     return true;
     81   } else if (trial == "Prefetching") {
     82     config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING;
     83     config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING;
     84     config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING;
     85     config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING;
     86     return true;
     87   } else if (trial == "PrefetchingLowConfidence") {
     88     config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING;
     89     config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING;
     90     config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING;
     91     config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING;
     92 
     93     config->min_url_visit_count = 1;
     94     config->min_resource_confidence_to_trigger_prefetch = 0.5f;
     95     config->min_resource_hits_to_trigger_prefetch = 1;
     96     return true;
     97   } else if (trial == "PrefetchingHighConfidence") {
     98     config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING;
     99     config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING;
    100     config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING;
    101     config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING;
    102 
    103     config->min_url_visit_count = 3;
    104     config->min_resource_confidence_to_trigger_prefetch = 0.9f;
    105     config->min_resource_hits_to_trigger_prefetch = 3;
    106     return true;
    107   } else if (trial == "PrefetchingMoreResources") {
    108     config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING;
    109     config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING;
    110     config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING;
    111     config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING;
    112 
    113     config->max_resources_per_entry = 100;
    114     return true;
    115   } else if (trial == "LearningSmallDB") {
    116     config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING;
    117     config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING;
    118 
    119     config->max_urls_to_track = 200;
    120     config->max_hosts_to_track = 100;
    121     return true;
    122   } else if (trial == "PrefetchingSmallDB") {
    123     config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING;
    124     config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING;
    125     config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING;
    126     config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING;
    127 
    128     config->max_urls_to_track = 200;
    129     config->max_hosts_to_track = 100;
    130     return true;
    131   } else if (trial == "PrefetchingSmallDBLowConfidence") {
    132     config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING;
    133     config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING;
    134     config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING;
    135     config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING;
    136 
    137     config->max_urls_to_track = 200;
    138     config->max_hosts_to_track = 100;
    139     config->min_url_visit_count = 1;
    140     config->min_resource_confidence_to_trigger_prefetch = 0.5f;
    141     config->min_resource_hits_to_trigger_prefetch = 1;
    142     return true;
    143   } else if (trial == "PrefetchingSmallDBHighConfidence") {
    144     config->mode |= ResourcePrefetchPredictorConfig::URL_LEARNING;
    145     config->mode |= ResourcePrefetchPredictorConfig::HOST_LEARNING;
    146     config->mode |= ResourcePrefetchPredictorConfig::URL_PREFETCHING;
    147     config->mode |= ResourcePrefetchPredictorConfig::HOST_PRFETCHING;
    148 
    149     config->max_urls_to_track = 200;
    150     config->max_hosts_to_track = 100;
    151     config->min_url_visit_count = 3;
    152     config->min_resource_confidence_to_trigger_prefetch = 0.9f;
    153     config->min_resource_hits_to_trigger_prefetch = 3;
    154     return true;
    155   }
    156 
    157   return false;
    158 }
    159 
    160 NavigationID::NavigationID()
    161     : render_process_id(-1),
    162       render_frame_id(-1) {
    163 }
    164 
    165 NavigationID::NavigationID(const NavigationID& other)
    166     : render_process_id(other.render_process_id),
    167       render_frame_id(other.render_frame_id),
    168       main_frame_url(other.main_frame_url),
    169       creation_time(other.creation_time) {
    170 }
    171 
    172 NavigationID::NavigationID(content::WebContents* web_contents)
    173     : render_process_id(web_contents->GetRenderProcessHost()->GetID()),
    174       render_frame_id(web_contents->GetRenderViewHost()->GetRoutingID()),
    175       main_frame_url(web_contents->GetURL()) {
    176 }
    177 
    178 bool NavigationID::is_valid() const {
    179   return render_process_id != -1 && render_frame_id != -1 &&
    180       !main_frame_url.is_empty();
    181 }
    182 
    183 bool NavigationID::operator<(const NavigationID& rhs) const {
    184   DCHECK(is_valid() && rhs.is_valid());
    185   if (render_process_id != rhs.render_process_id)
    186     return render_process_id < rhs.render_process_id;
    187   else if (render_frame_id != rhs.render_frame_id)
    188     return render_frame_id < rhs.render_frame_id;
    189   else
    190     return main_frame_url < rhs.main_frame_url;
    191 }
    192 
    193 bool NavigationID::operator==(const NavigationID& rhs) const {
    194   DCHECK(is_valid() && rhs.is_valid());
    195   return IsSameRenderer(rhs) && main_frame_url == rhs.main_frame_url;
    196 }
    197 
    198 bool NavigationID::IsSameRenderer(const NavigationID& other) const {
    199   DCHECK(is_valid() && other.is_valid());
    200   return render_process_id == other.render_process_id &&
    201       render_frame_id == other.render_frame_id;
    202 }
    203 
    204 ResourcePrefetchPredictorConfig::ResourcePrefetchPredictorConfig()
    205     : mode(0),
    206       max_navigation_lifetime_seconds(60),
    207       max_urls_to_track(500),
    208       max_hosts_to_track(200),
    209       min_url_visit_count(2),
    210       max_resources_per_entry(50),
    211       max_consecutive_misses(3),
    212       min_resource_confidence_to_trigger_prefetch(0.8f),
    213       min_resource_hits_to_trigger_prefetch(3),
    214       max_prefetches_inflight_per_navigation(24),
    215       max_prefetches_inflight_per_host_per_navigation(3) {
    216 }
    217 
    218 ResourcePrefetchPredictorConfig::~ResourcePrefetchPredictorConfig() {
    219 }
    220 
    221 bool ResourcePrefetchPredictorConfig::IsLearningEnabled() const {
    222   return IsURLLearningEnabled() || IsHostLearningEnabled();
    223 }
    224 
    225 bool ResourcePrefetchPredictorConfig::IsPrefetchingEnabled() const {
    226   return IsURLPrefetchingEnabled() || IsHostPrefetchingEnabled();
    227 }
    228 
    229 bool ResourcePrefetchPredictorConfig::IsURLLearningEnabled() const {
    230   return (mode & URL_LEARNING) > 0;
    231 }
    232 
    233 bool ResourcePrefetchPredictorConfig::IsHostLearningEnabled() const {
    234   return (mode & HOST_LEARNING) > 0;
    235 }
    236 
    237 bool ResourcePrefetchPredictorConfig::IsURLPrefetchingEnabled() const {
    238   return (mode & URL_PREFETCHING) > 0;
    239 }
    240 
    241 bool ResourcePrefetchPredictorConfig::IsHostPrefetchingEnabled() const {
    242   return (mode & HOST_PRFETCHING) > 0;
    243 }
    244 
    245 }  // namespace predictors
    246