| 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 |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 observer_(nullptr), | 376 observer_(nullptr), |
| 377 config_(config), | 377 config_(config), |
| 378 initialization_state_(NOT_INITIALIZED), | 378 initialization_state_(NOT_INITIALIZED), |
| 379 tables_(PredictorDatabaseFactory::GetForProfile(profile) | 379 tables_(PredictorDatabaseFactory::GetForProfile(profile) |
| 380 ->resource_prefetch_tables()), | 380 ->resource_prefetch_tables()), |
| 381 history_service_observer_(this) { | 381 history_service_observer_(this) { |
| 382 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 382 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 383 | 383 |
| 384 // Some form of learning has to be enabled. | 384 // Some form of learning has to be enabled. |
| 385 DCHECK(config_.IsLearningEnabled()); | 385 DCHECK(config_.IsLearningEnabled()); |
| 386 if (config_.IsURLPrefetchingEnabled(profile_)) | |
| 387 DCHECK(config_.IsURLLearningEnabled()); | |
| 388 if (config_.IsHostPrefetchingEnabled(profile_)) | |
| 389 DCHECK(config_.IsHostLearningEnabled()); | |
| 390 } | 386 } |
| 391 | 387 |
| 392 ResourcePrefetchPredictor::~ResourcePrefetchPredictor() {} | 388 ResourcePrefetchPredictor::~ResourcePrefetchPredictor() {} |
| 393 | 389 |
| 394 void ResourcePrefetchPredictor::StartInitialization() { | 390 void ResourcePrefetchPredictor::StartInitialization() { |
| 395 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 391 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 396 TRACE_EVENT0("browser", "ResourcePrefetchPredictor::StartInitialization"); | 392 TRACE_EVENT0("browser", "ResourcePrefetchPredictor::StartInitialization"); |
| 397 | 393 |
| 398 if (initialization_state_ != NOT_INITIALIZED) | 394 if (initialization_state_ != NOT_INITIALIZED) |
| 399 return; | 395 return; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 // corresponding to the navigation has not been created yet. | 464 // corresponding to the navigation has not been created yet. |
| 469 if (!navigation_id.main_frame_url.is_empty()) | 465 if (!navigation_id.main_frame_url.is_empty()) |
| 470 OnNavigationComplete(navigation_id); | 466 OnNavigationComplete(navigation_id); |
| 471 break; | 467 break; |
| 472 default: | 468 default: |
| 473 NOTREACHED() << "Unexpected initialization_state_: " | 469 NOTREACHED() << "Unexpected initialization_state_: " |
| 474 << initialization_state_; | 470 << initialization_state_; |
| 475 } | 471 } |
| 476 } | 472 } |
| 477 | 473 |
| 478 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url) { | 474 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url, |
| 475 PrefetchOrigin origin) { |
| 479 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StartPrefetching", "url", | 476 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StartPrefetching", "url", |
| 480 url.spec()); | 477 url.spec()); |
| 481 if (!prefetch_manager_.get()) // Prefetching not enabled. | 478 if (!prefetch_manager_.get()) // Prefetching not enabled. |
| 482 return; | 479 return; |
| 480 if (!config_.IsPrefetchingEnabledForOrigin(profile_, origin)) |
| 481 return; |
| 483 | 482 |
| 484 std::vector<GURL> subresource_urls; | 483 std::vector<GURL> subresource_urls; |
| 485 if (!GetPrefetchData(url, &subresource_urls)) { | 484 if (!GetPrefetchData(url, &subresource_urls)) |
| 486 // No prefetching data at host or URL level. | |
| 487 return; | 485 return; |
| 488 } | |
| 489 | 486 |
| 490 BrowserThread::PostTask( | 487 BrowserThread::PostTask( |
| 491 BrowserThread::IO, FROM_HERE, | 488 BrowserThread::IO, FROM_HERE, |
| 492 base::Bind(&ResourcePrefetcherManager::MaybeAddPrefetch, | 489 base::Bind(&ResourcePrefetcherManager::MaybeAddPrefetch, |
| 493 prefetch_manager_, url, subresource_urls)); | 490 prefetch_manager_, url, subresource_urls)); |
| 494 } | 491 } |
| 495 | 492 |
| 496 void ResourcePrefetchPredictor::StopPrefetching(const GURL& url) { | 493 void ResourcePrefetchPredictor::StopPrefetching(const GURL& url) { |
| 497 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StopPrefetching", "url", | 494 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StopPrefetching", "url", |
| 498 url.spec()); | 495 url.spec()); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 516 } | 513 } |
| 517 history_service_observer_.RemoveAll(); | 514 history_service_observer_.RemoveAll(); |
| 518 } | 515 } |
| 519 | 516 |
| 520 void ResourcePrefetchPredictor::OnMainFrameRequest( | 517 void ResourcePrefetchPredictor::OnMainFrameRequest( |
| 521 const URLRequestSummary& request) { | 518 const URLRequestSummary& request) { |
| 522 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 519 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 523 DCHECK_EQ(INITIALIZED, initialization_state_); | 520 DCHECK_EQ(INITIALIZED, initialization_state_); |
| 524 | 521 |
| 525 const GURL& main_frame_url = request.navigation_id.main_frame_url; | 522 const GURL& main_frame_url = request.navigation_id.main_frame_url; |
| 526 StartPrefetching(main_frame_url); | 523 StartPrefetching(main_frame_url, PrefetchOrigin::NAVIGATION); |
| 527 | 524 |
| 528 // Cleanup older navigations. | 525 // Cleanup older navigations. |
| 529 CleanupAbandonedNavigations(request.navigation_id); | 526 CleanupAbandonedNavigations(request.navigation_id); |
| 530 | 527 |
| 531 // New empty navigation entry. | 528 // New empty navigation entry. |
| 532 inflight_navigations_.insert( | 529 inflight_navigations_.insert( |
| 533 std::make_pair(request.navigation_id, | 530 std::make_pair(request.navigation_id, |
| 534 base::MakeUnique<PageRequestSummary>(main_frame_url))); | 531 base::MakeUnique<PageRequestSummary>(main_frame_url))); |
| 535 } | 532 } |
| 536 | 533 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 std::move(summary), | 607 std::move(summary), |
| 611 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, | 608 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, |
| 612 AsWeakPtr()))), | 609 AsWeakPtr()))), |
| 613 &history_lookup_consumer_); | 610 &history_lookup_consumer_); |
| 614 } | 611 } |
| 615 | 612 |
| 616 bool ResourcePrefetchPredictor::GetPrefetchData(const GURL& main_frame_url, | 613 bool ResourcePrefetchPredictor::GetPrefetchData(const GURL& main_frame_url, |
| 617 std::vector<GURL>* urls) { | 614 std::vector<GURL>* urls) { |
| 618 DCHECK(urls); | 615 DCHECK(urls); |
| 619 DCHECK(urls->empty()); | 616 DCHECK(urls->empty()); |
| 620 bool use_url_data = config_.IsPrefetchingEnabled(profile_) ? | |
| 621 config_.IsURLPrefetchingEnabled(profile_) : | |
| 622 config_.IsURLLearningEnabled(); | |
| 623 bool use_host_data = config_.IsPrefetchingEnabled(profile_) ? | |
| 624 config_.IsHostPrefetchingEnabled(profile_) : | |
| 625 config_.IsHostLearningEnabled(); | |
| 626 | 617 |
| 627 // Fetch URLs based on a redirect endpoint for URL/host first. | 618 // Fetch URLs based on a redirect endpoint for URL/host first. |
| 628 std::string redirect_endpoint; | 619 std::string redirect_endpoint; |
| 629 if (use_url_data && | 620 if (GetRedirectEndpoint(main_frame_url.spec(), *url_redirect_table_cache_, |
| 630 GetRedirectEndpoint(main_frame_url.spec(), *url_redirect_table_cache_, | |
| 631 &redirect_endpoint) && | 621 &redirect_endpoint) && |
| 632 PopulatePrefetcherRequest(redirect_endpoint, *url_table_cache_, urls)) { | 622 PopulatePrefetcherRequest(redirect_endpoint, *url_table_cache_, urls)) { |
| 633 return true; | 623 return true; |
| 634 } | 624 } |
| 635 | 625 |
| 636 if (use_host_data && | 626 if (GetRedirectEndpoint(main_frame_url.host(), *host_redirect_table_cache_, |
| 637 GetRedirectEndpoint(main_frame_url.host(), *host_redirect_table_cache_, | |
| 638 &redirect_endpoint) && | 627 &redirect_endpoint) && |
| 639 PopulatePrefetcherRequest(redirect_endpoint, *host_table_cache_, urls)) { | 628 PopulatePrefetcherRequest(redirect_endpoint, *host_table_cache_, urls)) { |
| 640 return true; | 629 return true; |
| 641 } | 630 } |
| 642 | 631 |
| 643 // Fallback to fetching URLs based on the incoming URL/host. | 632 // Fallback to fetching URLs based on the incoming URL/host. |
| 644 if (use_url_data && PopulatePrefetcherRequest(main_frame_url.spec(), | 633 if (PopulatePrefetcherRequest(main_frame_url.spec(), *url_table_cache_, |
| 645 *url_table_cache_, urls)) { | 634 urls)) { |
| 646 return true; | 635 return true; |
| 647 } | 636 } |
| 648 | 637 |
| 649 return use_host_data && PopulatePrefetcherRequest(main_frame_url.host(), | 638 return PopulatePrefetcherRequest(main_frame_url.host(), *host_table_cache_, |
| 650 *host_table_cache_, urls); | 639 urls); |
| 651 } | 640 } |
| 652 | 641 |
| 653 bool ResourcePrefetchPredictor::PopulatePrefetcherRequest( | 642 bool ResourcePrefetchPredictor::PopulatePrefetcherRequest( |
| 654 const std::string& main_frame_key, | 643 const std::string& main_frame_key, |
| 655 const PrefetchDataMap& data_map, | 644 const PrefetchDataMap& data_map, |
| 656 std::vector<GURL>* urls) { | 645 std::vector<GURL>* urls) { |
| 657 DCHECK(urls); | 646 DCHECK(urls); |
| 658 PrefetchDataMap::const_iterator it = data_map.find(main_frame_key); | 647 PrefetchDataMap::const_iterator it = data_map.find(main_frame_key); |
| 659 if (it == data_map.end()) | 648 if (it == data_map.end()) |
| 660 return false; | 649 return false; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 host_table_cache_->size()); | 689 host_table_cache_->size()); |
| 701 | 690 |
| 702 ConnectToHistoryService(); | 691 ConnectToHistoryService(); |
| 703 } | 692 } |
| 704 | 693 |
| 705 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() { | 694 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() { |
| 706 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 695 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 707 DCHECK_EQ(INITIALIZING, initialization_state_); | 696 DCHECK_EQ(INITIALIZING, initialization_state_); |
| 708 | 697 |
| 709 // Initialize the prefetch manager only if prefetching is enabled. | 698 // Initialize the prefetch manager only if prefetching is enabled. |
| 710 if (config_.IsPrefetchingEnabled(profile_)) { | 699 if (config_.IsPrefetchingEnabledForSomeOrigin(profile_)) { |
| 711 prefetch_manager_ = new ResourcePrefetcherManager( | 700 prefetch_manager_ = new ResourcePrefetcherManager( |
| 712 this, config_, profile_->GetRequestContext()); | 701 this, config_, profile_->GetRequestContext()); |
| 713 } | 702 } |
| 714 initialization_state_ = INITIALIZED; | 703 initialization_state_ = INITIALIZED; |
| 715 | 704 |
| 716 if (observer_) | 705 if (observer_) |
| 717 observer_->OnPredictorInitialized(); | 706 observer_->OnPredictorInitialized(); |
| 718 } | 707 } |
| 719 | 708 |
| 720 void ResourcePrefetchPredictor::CleanupAbandonedNavigations( | 709 void ResourcePrefetchPredictor::CleanupAbandonedNavigations( |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 // TODO(alexilin): make only one request to DB thread. | 840 // TODO(alexilin): make only one request to DB thread. |
| 852 | 841 |
| 853 // URL level data - merge only if we already saved the data, or it | 842 // URL level data - merge only if we already saved the data, or it |
| 854 // meets the cutoff requirement. | 843 // meets the cutoff requirement. |
| 855 const std::string url_spec = summary.main_frame_url.spec(); | 844 const std::string url_spec = summary.main_frame_url.spec(); |
| 856 bool already_tracking = url_table_cache_->find(url_spec) != | 845 bool already_tracking = url_table_cache_->find(url_spec) != |
| 857 url_table_cache_->end(); | 846 url_table_cache_->end(); |
| 858 bool should_track_url = | 847 bool should_track_url = |
| 859 already_tracking || (url_visit_count >= config_.min_url_visit_count); | 848 already_tracking || (url_visit_count >= config_.min_url_visit_count); |
| 860 | 849 |
| 861 if (should_track_url && config_.IsURLLearningEnabled()) { | 850 if (should_track_url) { |
| 862 LearnNavigation(url_spec, PREFETCH_KEY_TYPE_URL, | 851 LearnNavigation(url_spec, PREFETCH_KEY_TYPE_URL, |
| 863 summary.subresource_requests, config_.max_urls_to_track, | 852 summary.subresource_requests, config_.max_urls_to_track, |
| 864 url_table_cache_.get(), summary.initial_url.spec(), | 853 url_table_cache_.get(), summary.initial_url.spec(), |
| 865 url_redirect_table_cache_.get()); | 854 url_redirect_table_cache_.get()); |
| 866 } | 855 } |
| 867 | 856 |
| 868 // Host level data - no cutoff, always learn the navigation if enabled. | 857 // Host level data - no cutoff, always learn the navigation if enabled. |
| 869 if (config_.IsHostLearningEnabled()) { | 858 const std::string host = summary.main_frame_url.host(); |
| 870 const std::string host = summary.main_frame_url.host(); | 859 LearnNavigation(host, PREFETCH_KEY_TYPE_HOST, summary.subresource_requests, |
| 871 LearnNavigation(host, PREFETCH_KEY_TYPE_HOST, summary.subresource_requests, | 860 config_.max_hosts_to_track, host_table_cache_.get(), |
| 872 config_.max_hosts_to_track, host_table_cache_.get(), | 861 summary.initial_url.host(), host_redirect_table_cache_.get()); |
| 873 summary.initial_url.host(), | |
| 874 host_redirect_table_cache_.get()); | |
| 875 } | |
| 876 | 862 |
| 877 if (observer_) | 863 if (observer_) |
| 878 observer_->OnNavigationLearned(url_visit_count, summary); | 864 observer_->OnNavigationLearned(url_visit_count, summary); |
| 879 } | 865 } |
| 880 | 866 |
| 881 void ResourcePrefetchPredictor::LearnNavigation( | 867 void ResourcePrefetchPredictor::LearnNavigation( |
| 882 const std::string& key, | 868 const std::string& key, |
| 883 PrefetchKeyType key_type, | 869 PrefetchKeyType key_type, |
| 884 const std::vector<URLRequestSummary>& new_resources, | 870 const std::vector<URLRequestSummary>& new_resources, |
| 885 size_t max_data_map_size, | 871 size_t max_data_map_size, |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1170 TestObserver::~TestObserver() { | 1156 TestObserver::~TestObserver() { |
| 1171 predictor_->SetObserverForTesting(nullptr); | 1157 predictor_->SetObserverForTesting(nullptr); |
| 1172 } | 1158 } |
| 1173 | 1159 |
| 1174 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) | 1160 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) |
| 1175 : predictor_(predictor) { | 1161 : predictor_(predictor) { |
| 1176 predictor_->SetObserverForTesting(this); | 1162 predictor_->SetObserverForTesting(this); |
| 1177 } | 1163 } |
| 1178 | 1164 |
| 1179 } // namespace predictors | 1165 } // namespace predictors |
| OLD | NEW |