Chromium Code Reviews| 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 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 311 summary->has_validators = headers->HasValidators(); | 311 summary->has_validators = headers->HasValidators(); |
| 312 // RFC 2616, section 14.9. | 312 // RFC 2616, section 14.9. |
| 313 summary->always_revalidate = | 313 summary->always_revalidate = |
| 314 headers->HasHeaderValue("cache-control", "no-cache") || | 314 headers->HasHeaderValue("cache-control", "no-cache") || |
| 315 headers->HasHeaderValue("pragma", "no-cache") || | 315 headers->HasHeaderValue("pragma", "no-cache") || |
| 316 headers->HasHeaderValue("vary", "*"); | 316 headers->HasHeaderValue("vary", "*"); |
| 317 } | 317 } |
| 318 return true; | 318 return true; |
| 319 } | 319 } |
| 320 | 320 |
| 321 ResourcePrefetchPredictor::Result::Result( | |
| 322 PrefetchKeyType i_key_type, | |
| 323 ResourcePrefetcher::RequestVector* i_requests) | |
| 324 : key_type(i_key_type), | |
| 325 requests(i_requests) { | |
| 326 } | |
| 327 | |
| 328 ResourcePrefetchPredictor::Result::~Result() { | |
| 329 } | |
| 330 | |
| 331 //////////////////////////////////////////////////////////////////////////////// | 321 //////////////////////////////////////////////////////////////////////////////// |
| 332 // ResourcePrefetchPredictor. | 322 // ResourcePrefetchPredictor. |
| 333 | 323 |
| 334 ResourcePrefetchPredictor::ResourcePrefetchPredictor( | 324 ResourcePrefetchPredictor::ResourcePrefetchPredictor( |
| 335 const ResourcePrefetchPredictorConfig& config, | 325 const ResourcePrefetchPredictorConfig& config, |
| 336 Profile* profile) | 326 Profile* profile) |
| 337 : profile_(profile), | 327 : profile_(profile), |
| 338 config_(config), | 328 config_(config), |
| 339 initialization_state_(NOT_INITIALIZED), | 329 initialization_state_(NOT_INITIALIZED), |
| 340 tables_(PredictorDatabaseFactory::GetForProfile(profile) | 330 tables_(PredictorDatabaseFactory::GetForProfile(profile) |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 398 // corresponding to the navigation has not been created yet. | 388 // corresponding to the navigation has not been created yet. |
| 399 if (!navigation_id.main_frame_url.is_empty()) | 389 if (!navigation_id.main_frame_url.is_empty()) |
| 400 OnNavigationComplete(navigation_id); | 390 OnNavigationComplete(navigation_id); |
| 401 break; | 391 break; |
| 402 default: | 392 default: |
| 403 NOTREACHED() << "Unexpected initialization_state_: " | 393 NOTREACHED() << "Unexpected initialization_state_: " |
| 404 << initialization_state_; | 394 << initialization_state_; |
| 405 } | 395 } |
| 406 } | 396 } |
| 407 | 397 |
| 408 void ResourcePrefetchPredictor::FinishedPrefetchForNavigation( | |
| 409 const NavigationID& navigation_id, | |
| 410 PrefetchKeyType key_type, | |
| 411 ResourcePrefetcher::RequestVector* requests) { | |
| 412 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 413 | |
| 414 std::unique_ptr<Result> result(new Result(key_type, requests)); | |
| 415 // Add the results to the results map. | |
| 416 if (!results_map_.insert(std::make_pair(navigation_id, std::move(result))) | |
| 417 .second) | |
| 418 DLOG(FATAL) << "Returning results for existing navigation."; | |
| 419 } | |
| 420 | |
| 421 void ResourcePrefetchPredictor::Shutdown() { | 398 void ResourcePrefetchPredictor::Shutdown() { |
| 422 if (prefetch_manager_.get()) { | 399 if (prefetch_manager_.get()) { |
| 423 prefetch_manager_->ShutdownOnUIThread(); | 400 prefetch_manager_->ShutdownOnUIThread(); |
| 424 prefetch_manager_ = NULL; | 401 prefetch_manager_ = NULL; |
| 425 } | 402 } |
| 426 history_service_observer_.RemoveAll(); | 403 history_service_observer_.RemoveAll(); |
| 427 } | 404 } |
| 428 | 405 |
| 429 void ResourcePrefetchPredictor::OnMainFrameRequest( | 406 void ResourcePrefetchPredictor::OnMainFrameRequest( |
| 430 const URLRequestSummary& request) { | 407 const URLRequestSummary& request) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 514 history_service->ScheduleDBTask( | 491 history_service->ScheduleDBTask( |
| 515 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( | 492 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( |
| 516 navigation_id, requests, | 493 navigation_id, requests, |
| 517 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, | 494 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, |
| 518 AsWeakPtr()))), | 495 AsWeakPtr()))), |
| 519 &history_lookup_consumer_); | 496 &history_lookup_consumer_); |
| 520 } | 497 } |
| 521 | 498 |
| 522 bool ResourcePrefetchPredictor::GetPrefetchData( | 499 bool ResourcePrefetchPredictor::GetPrefetchData( |
| 523 const NavigationID& navigation_id, | 500 const NavigationID& navigation_id, |
| 524 ResourcePrefetcher::RequestVector* prefetch_requests, | 501 std::vector<GURL>* urls, |
| 525 PrefetchKeyType* key_type) { | 502 PrefetchKeyType* key_type) { |
| 526 DCHECK(prefetch_requests); | 503 DCHECK(urls); |
| 527 DCHECK(key_type); | 504 DCHECK(key_type); |
| 528 | 505 |
| 529 *key_type = PREFETCH_KEY_TYPE_URL; | 506 *key_type = PREFETCH_KEY_TYPE_URL; |
| 530 const GURL& main_frame_url = navigation_id.main_frame_url; | 507 const GURL& main_frame_url = navigation_id.main_frame_url; |
| 531 | 508 |
| 532 bool use_url_data = config_.IsPrefetchingEnabled(profile_) ? | 509 bool use_url_data = config_.IsPrefetchingEnabled(profile_) ? |
| 533 config_.IsURLPrefetchingEnabled(profile_) : | 510 config_.IsURLPrefetchingEnabled(profile_) : |
| 534 config_.IsURLLearningEnabled(); | 511 config_.IsURLLearningEnabled(); |
| 535 if (use_url_data) { | 512 if (use_url_data) { |
| 536 PrefetchDataMap::const_iterator iterator = | 513 PrefetchDataMap::const_iterator iterator = |
| 537 url_table_cache_->find(main_frame_url.spec()); | 514 url_table_cache_->find(main_frame_url.spec()); |
| 538 if (iterator != url_table_cache_->end()) | 515 if (iterator != url_table_cache_->end()) |
| 539 PopulatePrefetcherRequest(iterator->second, prefetch_requests); | 516 PopulatePrefetcherRequest(iterator->second, urls); |
| 540 } | 517 } |
| 541 if (!prefetch_requests->empty()) | |
| 542 return true; | |
|
pasko
2016/09/22 13:21:05
why is this early return removed? guaranteed to be
Benoit L
2016/09/22 14:42:49
No, but the return re-arrangement is equivalent. J
| |
| 543 | 518 |
| 544 bool use_host_data = config_.IsPrefetchingEnabled(profile_) ? | 519 bool use_host_data = config_.IsPrefetchingEnabled(profile_) ? |
| 545 config_.IsHostPrefetchingEnabled(profile_) : | 520 config_.IsHostPrefetchingEnabled(profile_) : |
| 546 config_.IsHostLearningEnabled(); | 521 config_.IsHostLearningEnabled(); |
| 547 if (use_host_data) { | 522 if (urls->empty() && use_host_data) { |
| 548 PrefetchDataMap::const_iterator iterator = | 523 PrefetchDataMap::const_iterator iterator = |
| 549 host_table_cache_->find(main_frame_url.host()); | 524 host_table_cache_->find(main_frame_url.host()); |
| 550 if (iterator != host_table_cache_->end()) { | 525 if (iterator != host_table_cache_->end()) { |
| 551 *key_type = PREFETCH_KEY_TYPE_HOST; | 526 *key_type = PREFETCH_KEY_TYPE_HOST; |
| 552 PopulatePrefetcherRequest(iterator->second, prefetch_requests); | 527 PopulatePrefetcherRequest(iterator->second, urls); |
| 553 } | 528 } |
| 554 } | 529 } |
| 555 | 530 |
| 556 return !prefetch_requests->empty(); | 531 return !urls->empty(); |
| 557 } | 532 } |
| 558 | 533 |
| 559 void ResourcePrefetchPredictor::PopulatePrefetcherRequest( | 534 void ResourcePrefetchPredictor::PopulatePrefetcherRequest( |
| 560 const PrefetchData& data, | 535 const PrefetchData& data, |
| 561 ResourcePrefetcher::RequestVector* requests) { | 536 std::vector<GURL>* urls) { |
| 562 for (const ResourceRow& row : data.resources) { | 537 for (const ResourceRow& row : data.resources) { |
| 563 float confidence = static_cast<float>(row.number_of_hits) / | 538 float confidence = static_cast<float>(row.number_of_hits) / |
| 564 (row.number_of_hits + row.number_of_misses); | 539 (row.number_of_hits + row.number_of_misses); |
| 565 if (confidence < config_.min_resource_confidence_to_trigger_prefetch || | 540 if (confidence < config_.min_resource_confidence_to_trigger_prefetch || |
| 566 row.number_of_hits < config_.min_resource_hits_to_trigger_prefetch) { | 541 row.number_of_hits < config_.min_resource_hits_to_trigger_prefetch) { |
| 567 continue; | 542 continue; |
| 568 } | 543 } |
| 569 | 544 |
| 570 ResourcePrefetcher::Request* req = | 545 urls->push_back(row.resource_url); |
| 571 new ResourcePrefetcher::Request(row.resource_url); | |
| 572 requests->push_back(req); | |
| 573 } | 546 } |
| 574 } | 547 } |
| 575 | 548 |
| 576 void ResourcePrefetchPredictor::StartPrefetching( | 549 void ResourcePrefetchPredictor::StartPrefetching( |
| 577 const NavigationID& navigation_id) { | 550 const NavigationID& navigation_id) { |
| 578 if (!prefetch_manager_.get()) // Prefetching not enabled. | 551 if (!prefetch_manager_.get()) // Prefetching not enabled. |
| 579 return; | 552 return; |
| 580 | 553 |
| 581 // Prefer URL based data first. | 554 // Prefer URL based data first. |
| 582 std::unique_ptr<ResourcePrefetcher::RequestVector> requests( | 555 std::vector<GURL> urls; |
| 583 new ResourcePrefetcher::RequestVector); | |
| 584 PrefetchKeyType key_type; | 556 PrefetchKeyType key_type; |
| 585 if (!GetPrefetchData(navigation_id, requests.get(), &key_type)) { | 557 if (!GetPrefetchData(navigation_id, &urls, &key_type)) { |
| 586 // No prefetching data at host or URL level. | 558 // No prefetching data at host or URL level. |
| 587 return; | 559 return; |
| 588 } | 560 } |
| 589 | 561 |
| 590 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 562 BrowserThread::PostTask( |
| 563 BrowserThread::IO, FROM_HERE, | |
| 591 base::Bind(&ResourcePrefetcherManager::MaybeAddPrefetch, | 564 base::Bind(&ResourcePrefetcherManager::MaybeAddPrefetch, |
| 592 prefetch_manager_, | 565 prefetch_manager_, navigation_id, key_type, urls)); |
| 593 navigation_id, | |
| 594 key_type, | |
| 595 base::Passed(&requests))); | |
| 596 } | 566 } |
| 597 | 567 |
| 598 void ResourcePrefetchPredictor::StopPrefetching( | 568 void ResourcePrefetchPredictor::StopPrefetching( |
| 599 const NavigationID& navigation_id) { | 569 const NavigationID& navigation_id) { |
| 600 if (!prefetch_manager_.get()) // Not enabled. | 570 if (!prefetch_manager_.get()) // Not enabled. |
| 601 return; | 571 return; |
| 602 | 572 |
| 603 BrowserThread::PostTask( | 573 BrowserThread::PostTask( |
| 604 BrowserThread::IO, FROM_HERE, | 574 BrowserThread::IO, FROM_HERE, |
| 605 base::Bind(&ResourcePrefetcherManager::MaybeRemovePrefetch, | 575 base::Bind(&ResourcePrefetcherManager::MaybeRemovePrefetch, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 668 base::TimeTicks time_now = base::TimeTicks::Now(); | 638 base::TimeTicks time_now = base::TimeTicks::Now(); |
| 669 for (NavigationMap::iterator it = inflight_navigations_.begin(); | 639 for (NavigationMap::iterator it = inflight_navigations_.begin(); |
| 670 it != inflight_navigations_.end();) { | 640 it != inflight_navigations_.end();) { |
| 671 if (it->first.IsSameRenderer(navigation_id) || | 641 if (it->first.IsSameRenderer(navigation_id) || |
| 672 (time_now - it->first.creation_time > max_navigation_age)) { | 642 (time_now - it->first.creation_time > max_navigation_age)) { |
| 673 inflight_navigations_.erase(it++); | 643 inflight_navigations_.erase(it++); |
| 674 } else { | 644 } else { |
| 675 ++it; | 645 ++it; |
| 676 } | 646 } |
| 677 } | 647 } |
| 678 for (ResultsMap::const_iterator it = results_map_.begin(); | |
| 679 it != results_map_.end();) { | |
| 680 if (it->first.IsSameRenderer(navigation_id) || | |
| 681 (time_now - it->first.creation_time > max_navigation_age)) { | |
| 682 results_map_.erase(it++); | |
| 683 } else { | |
| 684 ++it; | |
| 685 } | |
| 686 } | |
| 687 } | 648 } |
| 688 | 649 |
| 689 void ResourcePrefetchPredictor::DeleteAllUrls() { | 650 void ResourcePrefetchPredictor::DeleteAllUrls() { |
| 690 inflight_navigations_.clear(); | 651 inflight_navigations_.clear(); |
| 691 url_table_cache_->clear(); | 652 url_table_cache_->clear(); |
| 692 host_table_cache_->clear(); | 653 host_table_cache_->clear(); |
| 693 | 654 |
| 694 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, | 655 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, |
| 695 base::Bind(&ResourcePrefetchPredictorTables::DeleteAllData, tables_)); | 656 base::Bind(&ResourcePrefetchPredictorTables::DeleteAllData, tables_)); |
| 696 } | 657 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 770 } | 731 } |
| 771 | 732 |
| 772 // Host level data - no cutoff, always learn the navigation if enabled. | 733 // Host level data - no cutoff, always learn the navigation if enabled. |
| 773 if (config_.IsHostLearningEnabled()) { | 734 if (config_.IsHostLearningEnabled()) { |
| 774 LearnNavigation(navigation_id.main_frame_url.host(), | 735 LearnNavigation(navigation_id.main_frame_url.host(), |
| 775 PREFETCH_KEY_TYPE_HOST, | 736 PREFETCH_KEY_TYPE_HOST, |
| 776 requests, | 737 requests, |
| 777 config_.max_hosts_to_track, | 738 config_.max_hosts_to_track, |
| 778 host_table_cache_.get()); | 739 host_table_cache_.get()); |
| 779 } | 740 } |
| 780 | |
| 781 // Remove the navigation from the results map. | |
| 782 results_map_.erase(navigation_id); | |
| 783 } | 741 } |
| 784 | 742 |
| 785 void ResourcePrefetchPredictor::LearnNavigation( | 743 void ResourcePrefetchPredictor::LearnNavigation( |
| 786 const std::string& key, | 744 const std::string& key, |
| 787 PrefetchKeyType key_type, | 745 PrefetchKeyType key_type, |
| 788 const std::vector<URLRequestSummary>& new_resources, | 746 const std::vector<URLRequestSummary>& new_resources, |
| 789 size_t max_data_map_size, | 747 size_t max_data_map_size, |
| 790 PrefetchDataMap* data_map) { | 748 PrefetchDataMap* data_map) { |
| 791 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 749 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 792 | 750 |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 969 // HistoryService is already loaded. Continue with Initialization. | 927 // HistoryService is already loaded. Continue with Initialization. |
| 970 OnHistoryAndCacheLoaded(); | 928 OnHistoryAndCacheLoaded(); |
| 971 return; | 929 return; |
| 972 } | 930 } |
| 973 DCHECK(!history_service_observer_.IsObserving(history_service)); | 931 DCHECK(!history_service_observer_.IsObserving(history_service)); |
| 974 history_service_observer_.Add(history_service); | 932 history_service_observer_.Add(history_service); |
| 975 return; | 933 return; |
| 976 } | 934 } |
| 977 | 935 |
| 978 } // namespace predictors | 936 } // namespace predictors |
| OLD | NEW |