Home | History | Annotate | Download | only in predictors
      1 // Copyright (c) 2012 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() : render_process_id(-1), render_view_id(-1) {
    161 }
    162 
    163 NavigationID::NavigationID(const NavigationID& other)
    164     : render_process_id(other.render_process_id),
    165       render_view_id(other.render_view_id),
    166       main_frame_url(other.main_frame_url),
    167       creation_time(other.creation_time) {
    168 }
    169 
    170 NavigationID::NavigationID(const content::WebContents& web_contents)
    171     : render_process_id(web_contents.GetRenderProcessHost()->GetID()),
    172       render_view_id(web_contents.GetRenderViewHost()->GetRoutingID()),
    173       main_frame_url(web_contents.GetURL()) {
    174 }
    175 
    176 bool NavigationID::is_valid() const {
    177   return render_process_id != -1 && render_view_id != -1 &&
    178       !main_frame_url.is_empty();
    179 }
    180 
    181 bool NavigationID::operator<(const NavigationID& rhs) const {
    182   DCHECK(is_valid() && rhs.is_valid());
    183   if (render_process_id != rhs.render_process_id)
    184     return render_process_id < rhs.render_process_id;
    185   else if (render_view_id != rhs.render_view_id)
    186     return render_view_id < rhs.render_view_id;
    187   else
    188     return main_frame_url < rhs.main_frame_url;
    189 }
    190 
    191 bool NavigationID::operator==(const NavigationID& rhs) const {
    192   DCHECK(is_valid() && rhs.is_valid());
    193   return IsSameRenderer(rhs) && main_frame_url == rhs.main_frame_url;
    194 }
    195 
    196 bool NavigationID::IsSameRenderer(const NavigationID& other) const {
    197   DCHECK(is_valid() && other.is_valid());
    198   return render_process_id == other.render_process_id &&
    199       render_view_id == other.render_view_id;
    200 }
    201 
    202 ResourcePrefetchPredictorConfig::ResourcePrefetchPredictorConfig()
    203     : mode(0),
    204       max_navigation_lifetime_seconds(60),
    205       max_urls_to_track(500),
    206       max_hosts_to_track(200),
    207       min_url_visit_count(2),
    208       max_resources_per_entry(50),
    209       max_consecutive_misses(3),
    210       min_resource_confidence_to_trigger_prefetch(0.8f),
    211       min_resource_hits_to_trigger_prefetch(3),
    212       max_prefetches_inflight_per_navigation(24),
    213       max_prefetches_inflight_per_host_per_navigation(3) {
    214 }
    215 
    216 ResourcePrefetchPredictorConfig::~ResourcePrefetchPredictorConfig() {
    217 }
    218 
    219 bool ResourcePrefetchPredictorConfig::IsLearningEnabled() const {
    220   return IsURLLearningEnabled() || IsHostLearningEnabled();
    221 }
    222 
    223 bool ResourcePrefetchPredictorConfig::IsPrefetchingEnabled() const {
    224   return IsURLPrefetchingEnabled() || IsHostPrefetchingEnabled();
    225 }
    226 
    227 bool ResourcePrefetchPredictorConfig::IsURLLearningEnabled() const {
    228   return (mode & URL_LEARNING) > 0;
    229 }
    230 
    231 bool ResourcePrefetchPredictorConfig::IsHostLearningEnabled() const {
    232   return (mode & HOST_LEARNING) > 0;
    233 }
    234 
    235 bool ResourcePrefetchPredictorConfig::IsURLPrefetchingEnabled() const {
    236   return (mode & URL_PREFETCHING) > 0;
    237 }
    238 
    239 bool ResourcePrefetchPredictorConfig::IsHostPrefetchingEnabled() const {
    240   return (mode & HOST_PRFETCHING) > 0;
    241 }
    242 
    243 }  // namespace predictors
    244