| OLD | NEW |
| 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 |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/metrics/sparse_histogram.h" | 13 #include "base/metrics/sparse_histogram.h" |
| 14 #include "base/stl_util.h" | |
| 15 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 16 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
| 17 #include "base/time/time.h" | 16 #include "base/time/time.h" |
| 18 #include "chrome/browser/history/history_service_factory.h" | 17 #include "chrome/browser/history/history_service_factory.h" |
| 19 #include "chrome/browser/predictors/predictor_database.h" | 18 #include "chrome/browser/predictors/predictor_database.h" |
| 20 #include "chrome/browser/predictors/predictor_database_factory.h" | 19 #include "chrome/browser/predictors/predictor_database_factory.h" |
| 21 #include "chrome/browser/predictors/resource_prefetcher_manager.h" | 20 #include "chrome/browser/predictors/resource_prefetcher_manager.h" |
| 22 #include "chrome/browser/profiles/profile.h" | 21 #include "chrome/browser/profiles/profile.h" |
| 23 #include "chrome/common/chrome_switches.h" | 22 #include "chrome/common/chrome_switches.h" |
| 24 #include "chrome/common/url_constants.h" | 23 #include "chrome/common/url_constants.h" |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 // ResourcePrefetchPredictor. | 339 // ResourcePrefetchPredictor. |
| 341 | 340 |
| 342 ResourcePrefetchPredictor::ResourcePrefetchPredictor( | 341 ResourcePrefetchPredictor::ResourcePrefetchPredictor( |
| 343 const ResourcePrefetchPredictorConfig& config, | 342 const ResourcePrefetchPredictorConfig& config, |
| 344 Profile* profile) | 343 Profile* profile) |
| 345 : profile_(profile), | 344 : profile_(profile), |
| 346 config_(config), | 345 config_(config), |
| 347 initialization_state_(NOT_INITIALIZED), | 346 initialization_state_(NOT_INITIALIZED), |
| 348 tables_(PredictorDatabaseFactory::GetForProfile(profile) | 347 tables_(PredictorDatabaseFactory::GetForProfile(profile) |
| 349 ->resource_prefetch_tables()), | 348 ->resource_prefetch_tables()), |
| 350 results_map_deleter_(&results_map_), | |
| 351 history_service_observer_(this) { | 349 history_service_observer_(this) { |
| 352 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 350 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 353 | 351 |
| 354 // Some form of learning has to be enabled. | 352 // Some form of learning has to be enabled. |
| 355 DCHECK(config_.IsLearningEnabled()); | 353 DCHECK(config_.IsLearningEnabled()); |
| 356 if (config_.IsURLPrefetchingEnabled(profile_)) | 354 if (config_.IsURLPrefetchingEnabled(profile_)) |
| 357 DCHECK(config_.IsURLLearningEnabled()); | 355 DCHECK(config_.IsURLLearningEnabled()); |
| 358 if (config_.IsHostPrefetchingEnabled(profile_)) | 356 if (config_.IsHostPrefetchingEnabled(profile_)) |
| 359 DCHECK(config_.IsHostLearningEnabled()); | 357 DCHECK(config_.IsHostLearningEnabled()); |
| 360 } | 358 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 << initialization_state_; | 415 << initialization_state_; |
| 418 } | 416 } |
| 419 } | 417 } |
| 420 | 418 |
| 421 void ResourcePrefetchPredictor::FinishedPrefetchForNavigation( | 419 void ResourcePrefetchPredictor::FinishedPrefetchForNavigation( |
| 422 const NavigationID& navigation_id, | 420 const NavigationID& navigation_id, |
| 423 PrefetchKeyType key_type, | 421 PrefetchKeyType key_type, |
| 424 ResourcePrefetcher::RequestVector* requests) { | 422 ResourcePrefetcher::RequestVector* requests) { |
| 425 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 423 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 426 | 424 |
| 427 Result* result = new Result(key_type, requests); | 425 scoped_ptr<Result> result(new Result(key_type, requests)); |
| 428 // Add the results to the results map. | 426 // Add the results to the results map. |
| 429 if (!results_map_.insert(std::make_pair(navigation_id, result)).second) { | 427 if (!results_map_.insert(navigation_id, result.Pass()).second) |
| 430 DLOG(FATAL) << "Returning results for existing navigation."; | 428 DLOG(FATAL) << "Returning results for existing navigation."; |
| 431 delete result; | |
| 432 } | |
| 433 } | 429 } |
| 434 | 430 |
| 435 void ResourcePrefetchPredictor::Shutdown() { | 431 void ResourcePrefetchPredictor::Shutdown() { |
| 436 if (prefetch_manager_.get()) { | 432 if (prefetch_manager_.get()) { |
| 437 prefetch_manager_->ShutdownOnUIThread(); | 433 prefetch_manager_->ShutdownOnUIThread(); |
| 438 prefetch_manager_ = NULL; | 434 prefetch_manager_ = NULL; |
| 439 } | 435 } |
| 440 history_service_observer_.RemoveAll(); | 436 history_service_observer_.RemoveAll(); |
| 441 } | 437 } |
| 442 | 438 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 RecordNavigationEvent(NAVIGATION_EVENT_ONLOAD_TRACKED_URL); | 522 RecordNavigationEvent(NAVIGATION_EVENT_ONLOAD_TRACKED_URL); |
| 527 | 523 |
| 528 // Get and use the navigation ID stored in |inflight_navigations_| because it | 524 // Get and use the navigation ID stored in |inflight_navigations_| because it |
| 529 // has the timing infomation. | 525 // has the timing infomation. |
| 530 const NavigationID navigation_id(nav_it->first); | 526 const NavigationID navigation_id(nav_it->first); |
| 531 | 527 |
| 532 // Report any stats. | 528 // Report any stats. |
| 533 base::TimeDelta plt = base::TimeTicks::Now() - navigation_id.creation_time; | 529 base::TimeDelta plt = base::TimeTicks::Now() - navigation_id.creation_time; |
| 534 ReportPageLoadTimeStats(plt); | 530 ReportPageLoadTimeStats(plt); |
| 535 if (prefetch_manager_.get()) { | 531 if (prefetch_manager_.get()) { |
| 536 ResultsMap::iterator results_it = results_map_.find(navigation_id); | 532 ResultsMap::const_iterator results_it = results_map_.find(navigation_id); |
| 537 bool have_prefetch_results = results_it != results_map_.end(); | 533 bool have_prefetch_results = results_it != results_map_.end(); |
| 538 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.HavePrefetchResults", | 534 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.HavePrefetchResults", |
| 539 have_prefetch_results); | 535 have_prefetch_results); |
| 540 if (have_prefetch_results) { | 536 if (have_prefetch_results) { |
| 541 ReportAccuracyStats(results_it->second->key_type, | 537 ReportAccuracyStats(results_it->second->key_type, |
| 542 *(nav_it->second), | 538 *(nav_it->second), |
| 543 results_it->second->requests.get()); | 539 results_it->second->requests.get()); |
| 544 ReportPageLoadTimePrefetchStats( | 540 ReportPageLoadTimePrefetchStats( |
| 545 plt, | 541 plt, |
| 546 true, | 542 true, |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 739 for (NavigationMap::iterator it = inflight_navigations_.begin(); | 735 for (NavigationMap::iterator it = inflight_navigations_.begin(); |
| 740 it != inflight_navigations_.end();) { | 736 it != inflight_navigations_.end();) { |
| 741 if (it->first.IsSameRenderer(navigation_id) || | 737 if (it->first.IsSameRenderer(navigation_id) || |
| 742 (time_now - it->first.creation_time > max_navigation_age)) { | 738 (time_now - it->first.creation_time > max_navigation_age)) { |
| 743 inflight_navigations_.erase(it++); | 739 inflight_navigations_.erase(it++); |
| 744 RecordNavigationEvent(NAVIGATION_EVENT_REQUEST_EXPIRED); | 740 RecordNavigationEvent(NAVIGATION_EVENT_REQUEST_EXPIRED); |
| 745 } else { | 741 } else { |
| 746 ++it; | 742 ++it; |
| 747 } | 743 } |
| 748 } | 744 } |
| 749 for (ResultsMap::iterator it = results_map_.begin(); | 745 for (ResultsMap::const_iterator it = results_map_.begin(); |
| 750 it != results_map_.end();) { | 746 it != results_map_.end();) { |
| 751 if (it->first.IsSameRenderer(navigation_id) || | 747 if (it->first.IsSameRenderer(navigation_id) || |
| 752 (time_now - it->first.creation_time > max_navigation_age)) { | 748 (time_now - it->first.creation_time > max_navigation_age)) { |
| 753 delete it->second; | |
| 754 results_map_.erase(it++); | 749 results_map_.erase(it++); |
| 755 } else { | 750 } else { |
| 756 ++it; | 751 ++it; |
| 757 } | 752 } |
| 758 } | 753 } |
| 759 } | 754 } |
| 760 | 755 |
| 761 void ResourcePrefetchPredictor::DeleteAllUrls() { | 756 void ResourcePrefetchPredictor::DeleteAllUrls() { |
| 762 inflight_navigations_.clear(); | 757 inflight_navigations_.clear(); |
| 763 url_table_cache_->clear(); | 758 url_table_cache_->clear(); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 850 // Host level data - no cutoff, always learn the navigation if enabled. | 845 // Host level data - no cutoff, always learn the navigation if enabled. |
| 851 if (config_.IsHostLearningEnabled()) { | 846 if (config_.IsHostLearningEnabled()) { |
| 852 LearnNavigation(navigation_id.main_frame_url.host(), | 847 LearnNavigation(navigation_id.main_frame_url.host(), |
| 853 PREFETCH_KEY_TYPE_HOST, | 848 PREFETCH_KEY_TYPE_HOST, |
| 854 requests, | 849 requests, |
| 855 config_.max_hosts_to_track, | 850 config_.max_hosts_to_track, |
| 856 host_table_cache_.get()); | 851 host_table_cache_.get()); |
| 857 } | 852 } |
| 858 | 853 |
| 859 // Remove the navigation from the results map. | 854 // Remove the navigation from the results map. |
| 860 ResultsMap::iterator results_it = results_map_.find(navigation_id); | 855 results_map_.erase(navigation_id); |
| 861 if (results_it != results_map_.end()) { | |
| 862 delete results_it->second; | |
| 863 results_map_.erase(results_it); | |
| 864 } | |
| 865 } | 856 } |
| 866 | 857 |
| 867 void ResourcePrefetchPredictor::LearnNavigation( | 858 void ResourcePrefetchPredictor::LearnNavigation( |
| 868 const std::string& key, | 859 const std::string& key, |
| 869 PrefetchKeyType key_type, | 860 PrefetchKeyType key_type, |
| 870 const std::vector<URLRequestSummary>& new_resources, | 861 const std::vector<URLRequestSummary>& new_resources, |
| 871 size_t max_data_map_size, | 862 size_t max_data_map_size, |
| 872 PrefetchDataMap* data_map) { | 863 PrefetchDataMap* data_map) { |
| 873 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 864 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 874 | 865 |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1100 int prefetch_cancelled = 0, prefetch_failed = 0, prefetch_not_started = 0; | 1091 int prefetch_cancelled = 0, prefetch_failed = 0, prefetch_not_started = 0; |
| 1101 // 'a_' -> actual, 'p_' -> predicted. | 1092 // 'a_' -> actual, 'p_' -> predicted. |
| 1102 int p_cache_a_cache = 0, p_cache_a_network = 0, p_cache_a_notused = 0, | 1093 int p_cache_a_cache = 0, p_cache_a_network = 0, p_cache_a_notused = 0, |
| 1103 p_network_a_cache = 0, p_network_a_network = 0, p_network_a_notused = 0; | 1094 p_network_a_cache = 0, p_network_a_network = 0, p_network_a_notused = 0; |
| 1104 | 1095 |
| 1105 for (ResourcePrefetcher::RequestVector::iterator it = prefetched->begin(); | 1096 for (ResourcePrefetcher::RequestVector::iterator it = prefetched->begin(); |
| 1106 it != prefetched->end(); ++it) { | 1097 it != prefetched->end(); ++it) { |
| 1107 ResourcePrefetcher::Request* req = *it; | 1098 ResourcePrefetcher::Request* req = *it; |
| 1108 | 1099 |
| 1109 // Set the usage states if the resource was actually used. | 1100 // Set the usage states if the resource was actually used. |
| 1110 std::map<GURL, bool>::iterator actual_it = actual_resources.find( | 1101 std::map<GURL, bool>::const_iterator actual_it = |
| 1111 req->resource_url); | 1102 actual_resources.find(req->resource_url); |
| 1112 if (actual_it != actual_resources.end()) { | 1103 if (actual_it != actual_resources.end()) { |
| 1113 if (actual_it->second) { | 1104 if (actual_it->second) { |
| 1114 req->usage_status = | 1105 req->usage_status = |
| 1115 ResourcePrefetcher::Request::USAGE_STATUS_FROM_CACHE; | 1106 ResourcePrefetcher::Request::USAGE_STATUS_FROM_CACHE; |
| 1116 } else { | 1107 } else { |
| 1117 req->usage_status = | 1108 req->usage_status = |
| 1118 ResourcePrefetcher::Request::USAGE_STATUS_FROM_NETWORK; | 1109 ResourcePrefetcher::Request::USAGE_STATUS_FROM_NETWORK; |
| 1119 } | 1110 } |
| 1120 } | 1111 } |
| 1121 | 1112 |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1343 // HistoryService is already loaded. Continue with Initialization. | 1334 // HistoryService is already loaded. Continue with Initialization. |
| 1344 OnHistoryAndCacheLoaded(); | 1335 OnHistoryAndCacheLoaded(); |
| 1345 return; | 1336 return; |
| 1346 } | 1337 } |
| 1347 DCHECK(!history_service_observer_.IsObserving(history_service)); | 1338 DCHECK(!history_service_observer_.IsObserving(history_service)); |
| 1348 history_service_observer_.Add(history_service); | 1339 history_service_observer_.Add(history_service); |
| 1349 return; | 1340 return; |
| 1350 } | 1341 } |
| 1351 | 1342 |
| 1352 } // namespace predictors | 1343 } // namespace predictors |
| OLD | NEW |