| 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 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 prefetch_manager_ = NULL; | 387 prefetch_manager_ = NULL; |
| 388 } | 388 } |
| 389 history_service_observer_.RemoveAll(); | 389 history_service_observer_.RemoveAll(); |
| 390 } | 390 } |
| 391 | 391 |
| 392 void ResourcePrefetchPredictor::OnMainFrameRequest( | 392 void ResourcePrefetchPredictor::OnMainFrameRequest( |
| 393 const URLRequestSummary& request) { | 393 const URLRequestSummary& request) { |
| 394 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 394 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 395 DCHECK_EQ(INITIALIZED, initialization_state_); | 395 DCHECK_EQ(INITIALIZED, initialization_state_); |
| 396 | 396 |
| 397 StartPrefetching(request.navigation_id); | 397 StartPrefetching(request.navigation_id.main_frame_url); |
| 398 | 398 |
| 399 // Cleanup older navigations. | 399 // Cleanup older navigations. |
| 400 CleanupAbandonedNavigations(request.navigation_id); | 400 CleanupAbandonedNavigations(request.navigation_id); |
| 401 | 401 |
| 402 // New empty navigation entry. | 402 // New empty navigation entry. |
| 403 const GURL& initial_url = request.navigation_id.main_frame_url; | 403 const GURL& initial_url = request.navigation_id.main_frame_url; |
| 404 inflight_navigations_.insert( | 404 inflight_navigations_.insert( |
| 405 std::make_pair(request.navigation_id, | 405 std::make_pair(request.navigation_id, |
| 406 base::MakeUnique<PageRequestSummary>(initial_url))); | 406 base::MakeUnique<PageRequestSummary>(initial_url))); |
| 407 } | 407 } |
| 408 | 408 |
| 409 void ResourcePrefetchPredictor::OnMainFrameResponse( | 409 void ResourcePrefetchPredictor::OnMainFrameResponse( |
| 410 const URLRequestSummary& response) { | 410 const URLRequestSummary& response) { |
| 411 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 411 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 412 if (initialization_state_ != INITIALIZED) | 412 if (initialization_state_ != INITIALIZED) |
| 413 return; | 413 return; |
| 414 | 414 |
| 415 StopPrefetching(response.navigation_id); | 415 StopPrefetching(response.navigation_id.main_frame_url); |
| 416 } | 416 } |
| 417 | 417 |
| 418 void ResourcePrefetchPredictor::OnMainFrameRedirect( | 418 void ResourcePrefetchPredictor::OnMainFrameRedirect( |
| 419 const URLRequestSummary& response) { | 419 const URLRequestSummary& response) { |
| 420 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 420 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 421 | 421 |
| 422 // Stop any inflight prefetching. Remove the older navigation. | 422 // Stop any inflight prefetching. Remove the older navigation. |
| 423 StopPrefetching(response.navigation_id); | 423 StopPrefetching(response.navigation_id.main_frame_url); |
| 424 | 424 |
| 425 std::unique_ptr<PageRequestSummary> summary; | 425 std::unique_ptr<PageRequestSummary> summary; |
| 426 NavigationMap::iterator nav_it = | 426 NavigationMap::iterator nav_it = |
| 427 inflight_navigations_.find(response.navigation_id); | 427 inflight_navigations_.find(response.navigation_id); |
| 428 if (nav_it != inflight_navigations_.end()) { | 428 if (nav_it != inflight_navigations_.end()) { |
| 429 summary.reset(nav_it->second.release()); | 429 summary.reset(nav_it->second.release()); |
| 430 inflight_navigations_.erase(nav_it); | 430 inflight_navigations_.erase(nav_it); |
| 431 } | 431 } |
| 432 | 432 |
| 433 // The redirect url may be empty if the URL was invalid. | 433 // The redirect url may be empty if the URL was invalid. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 ServiceAccessType::EXPLICIT_ACCESS); | 482 ServiceAccessType::EXPLICIT_ACCESS); |
| 483 DCHECK(history_service); | 483 DCHECK(history_service); |
| 484 history_service->ScheduleDBTask( | 484 history_service->ScheduleDBTask( |
| 485 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( | 485 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( |
| 486 navigation_id, std::move(summary), | 486 navigation_id, std::move(summary), |
| 487 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, | 487 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, |
| 488 AsWeakPtr()))), | 488 AsWeakPtr()))), |
| 489 &history_lookup_consumer_); | 489 &history_lookup_consumer_); |
| 490 } | 490 } |
| 491 | 491 |
| 492 bool ResourcePrefetchPredictor::GetPrefetchData( | 492 bool ResourcePrefetchPredictor::GetPrefetchData(const GURL& main_frame_url, |
| 493 const NavigationID& navigation_id, | 493 std::vector<GURL>* urls) { |
| 494 std::vector<GURL>* urls, | |
| 495 PrefetchKeyType* key_type) { | |
| 496 DCHECK(urls); | 494 DCHECK(urls); |
| 497 DCHECK(key_type); | |
| 498 | |
| 499 *key_type = PREFETCH_KEY_TYPE_URL; | |
| 500 const GURL& main_frame_url = navigation_id.main_frame_url; | |
| 501 | 495 |
| 502 bool use_url_data = config_.IsPrefetchingEnabled(profile_) ? | 496 bool use_url_data = config_.IsPrefetchingEnabled(profile_) ? |
| 503 config_.IsURLPrefetchingEnabled(profile_) : | 497 config_.IsURLPrefetchingEnabled(profile_) : |
| 504 config_.IsURLLearningEnabled(); | 498 config_.IsURLLearningEnabled(); |
| 505 if (use_url_data) { | 499 if (use_url_data) { |
| 506 PrefetchDataMap::const_iterator iterator = | 500 PrefetchDataMap::const_iterator iterator = |
| 507 url_table_cache_->find(main_frame_url.spec()); | 501 url_table_cache_->find(main_frame_url.spec()); |
| 508 if (iterator != url_table_cache_->end()) | 502 if (iterator != url_table_cache_->end()) |
| 509 PopulatePrefetcherRequest(iterator->second, urls); | 503 PopulatePrefetcherRequest(iterator->second, urls); |
| 510 } | 504 } |
| 505 if (!urls->empty()) |
| 506 return true; |
| 511 | 507 |
| 512 bool use_host_data = config_.IsPrefetchingEnabled(profile_) ? | 508 bool use_host_data = config_.IsPrefetchingEnabled(profile_) ? |
| 513 config_.IsHostPrefetchingEnabled(profile_) : | 509 config_.IsHostPrefetchingEnabled(profile_) : |
| 514 config_.IsHostLearningEnabled(); | 510 config_.IsHostLearningEnabled(); |
| 515 if (urls->empty() && use_host_data) { | 511 if (use_host_data) { |
| 516 PrefetchDataMap::const_iterator iterator = | 512 PrefetchDataMap::const_iterator iterator = |
| 517 host_table_cache_->find(main_frame_url.host()); | 513 host_table_cache_->find(main_frame_url.host()); |
| 518 if (iterator != host_table_cache_->end()) { | 514 if (iterator != host_table_cache_->end()) |
| 519 *key_type = PREFETCH_KEY_TYPE_HOST; | |
| 520 PopulatePrefetcherRequest(iterator->second, urls); | 515 PopulatePrefetcherRequest(iterator->second, urls); |
| 521 } | |
| 522 } | 516 } |
| 523 | 517 |
| 524 return !urls->empty(); | 518 return !urls->empty(); |
| 525 } | 519 } |
| 526 | 520 |
| 527 void ResourcePrefetchPredictor::PopulatePrefetcherRequest( | 521 void ResourcePrefetchPredictor::PopulatePrefetcherRequest( |
| 528 const PrefetchData& data, | 522 const PrefetchData& data, |
| 529 std::vector<GURL>* urls) { | 523 std::vector<GURL>* urls) { |
| 530 for (const ResourceData& resource : data.resources) { | 524 for (const ResourceData& resource : data.resources) { |
| 531 float confidence = | 525 float confidence = |
| 532 static_cast<float>(resource.number_of_hits()) / | 526 static_cast<float>(resource.number_of_hits()) / |
| 533 (resource.number_of_hits() + resource.number_of_misses()); | 527 (resource.number_of_hits() + resource.number_of_misses()); |
| 534 if (confidence < config_.min_resource_confidence_to_trigger_prefetch || | 528 if (confidence < config_.min_resource_confidence_to_trigger_prefetch || |
| 535 resource.number_of_hits() < | 529 resource.number_of_hits() < |
| 536 config_.min_resource_hits_to_trigger_prefetch) { | 530 config_.min_resource_hits_to_trigger_prefetch) { |
| 537 continue; | 531 continue; |
| 538 } | 532 } |
| 539 | 533 |
| 540 urls->push_back(GURL(resource.resource_url())); | 534 urls->push_back(GURL(resource.resource_url())); |
| 541 } | 535 } |
| 542 } | 536 } |
| 543 | 537 |
| 544 void ResourcePrefetchPredictor::StartPrefetching( | 538 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url) { |
| 545 const NavigationID& navigation_id) { | |
| 546 if (!prefetch_manager_.get()) // Prefetching not enabled. | 539 if (!prefetch_manager_.get()) // Prefetching not enabled. |
| 547 return; | 540 return; |
| 548 | 541 |
| 549 // Prefer URL based data first. | 542 std::vector<GURL> subresource_urls; |
| 550 std::vector<GURL> urls; | 543 if (!GetPrefetchData(url, &subresource_urls)) { |
| 551 PrefetchKeyType key_type; | |
| 552 if (!GetPrefetchData(navigation_id, &urls, &key_type)) { | |
| 553 // No prefetching data at host or URL level. | 544 // No prefetching data at host or URL level. |
| 554 return; | 545 return; |
| 555 } | 546 } |
| 556 | 547 |
| 557 BrowserThread::PostTask( | 548 BrowserThread::PostTask( |
| 558 BrowserThread::IO, FROM_HERE, | 549 BrowserThread::IO, FROM_HERE, |
| 559 base::Bind(&ResourcePrefetcherManager::MaybeAddPrefetch, | 550 base::Bind(&ResourcePrefetcherManager::MaybeAddPrefetch, |
| 560 prefetch_manager_, navigation_id, urls)); | 551 prefetch_manager_, url, subresource_urls)); |
| 561 } | 552 } |
| 562 | 553 |
| 563 void ResourcePrefetchPredictor::StopPrefetching( | 554 void ResourcePrefetchPredictor::StopPrefetching(const GURL& url) { |
| 564 const NavigationID& navigation_id) { | |
| 565 if (!prefetch_manager_.get()) // Not enabled. | 555 if (!prefetch_manager_.get()) // Not enabled. |
| 566 return; | 556 return; |
| 567 | 557 |
| 568 BrowserThread::PostTask( | 558 BrowserThread::PostTask( |
| 569 BrowserThread::IO, FROM_HERE, | 559 BrowserThread::IO, FROM_HERE, |
| 570 base::Bind(&ResourcePrefetcherManager::MaybeRemovePrefetch, | 560 base::Bind(&ResourcePrefetcherManager::MaybeRemovePrefetch, |
| 571 prefetch_manager_, | 561 prefetch_manager_, url)); |
| 572 navigation_id)); | |
| 573 } | 562 } |
| 574 | 563 |
| 575 void ResourcePrefetchPredictor::StartInitialization() { | 564 void ResourcePrefetchPredictor::StartInitialization() { |
| 576 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 565 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 577 | 566 |
| 578 DCHECK_EQ(NOT_INITIALIZED, initialization_state_); | 567 DCHECK_EQ(NOT_INITIALIZED, initialization_state_); |
| 579 initialization_state_ = INITIALIZING; | 568 initialization_state_ = INITIALIZING; |
| 580 | 569 |
| 581 // Create local caches using the database as loaded. | 570 // Create local caches using the database as loaded. |
| 582 auto url_data_map = base::MakeUnique<PrefetchDataMap>(); | 571 auto url_data_map = base::MakeUnique<PrefetchDataMap>(); |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1086 // HistoryService is already loaded. Continue with Initialization. | 1075 // HistoryService is already loaded. Continue with Initialization. |
| 1087 OnHistoryAndCacheLoaded(); | 1076 OnHistoryAndCacheLoaded(); |
| 1088 return; | 1077 return; |
| 1089 } | 1078 } |
| 1090 DCHECK(!history_service_observer_.IsObserving(history_service)); | 1079 DCHECK(!history_service_observer_.IsObserving(history_service)); |
| 1091 history_service_observer_.Add(history_service); | 1080 history_service_observer_.Add(history_service); |
| 1092 return; | 1081 return; |
| 1093 } | 1082 } |
| 1094 | 1083 |
| 1095 } // namespace predictors | 1084 } // namespace predictors |
| OLD | NEW |