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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 visit_count_ = url_row.visit_count(); | 113 visit_count_ = url_row.visit_count(); |
| 114 return true; | 114 return true; |
| 115 } | 115 } |
| 116 | 116 |
| 117 void GetUrlVisitCountTask::DoneRunOnMainThread() { | 117 void GetUrlVisitCountTask::DoneRunOnMainThread() { |
| 118 callback_.Run(visit_count_, *summary_); | 118 callback_.Run(visit_count_, *summary_); |
| 119 } | 119 } |
| 120 | 120 |
| 121 GetUrlVisitCountTask::~GetUrlVisitCountTask() {} | 121 GetUrlVisitCountTask::~GetUrlVisitCountTask() {} |
| 122 | 122 |
| 123 void ReportPrefetchAccuracy( | |
| 124 const ResourcePrefetcher::PrefetcherStats& stats, | |
| 125 const std::vector<ResourcePrefetchPredictor::URLRequestSummary>& | |
| 126 summaries) { | |
| 127 if (stats.requests_stats.empty()) | |
| 128 return; | |
| 129 | |
| 130 std::set<GURL> urls; | |
| 131 for (const auto& summary : summaries) | |
| 132 urls.insert(summary.resource_url); | |
| 133 | |
| 134 int cached_misses_count = 0; | |
| 135 int not_cached_misses_count = 0; | |
| 136 int cached_hits_count = 0; | |
| 137 int not_cached_hits_count = 0; | |
| 138 int64_t misses_bytes = 0; | |
| 139 int64_t hits_bytes = 0; | |
| 140 | |
| 141 for (const auto& request_stats : stats.requests_stats) { | |
| 142 bool hit = urls.find(request_stats.resource_url) != urls.end(); | |
| 143 bool cached = request_stats.was_cached; | |
| 144 size_t bytes = request_stats.total_received_bytes; | |
| 145 | |
| 146 cached_hits_count += cached && hit; | |
| 147 cached_misses_count += cached && !hit; | |
| 148 not_cached_hits_count += !cached && hit; | |
| 149 not_cached_misses_count += !cached && !hit; | |
| 150 misses_bytes += !hit * bytes; | |
| 151 hits_bytes += hit * bytes; | |
| 152 } | |
| 153 | |
| 154 UMA_HISTOGRAM_COUNTS_100( | |
| 155 internal::kResourcePrefetchPredictorPrefetchMissesCountCached, | |
| 156 cached_misses_count); | |
| 157 UMA_HISTOGRAM_COUNTS_100( | |
| 158 internal::kResourcePrefetchPredictorPrefetchMissesCountNotCached, | |
| 159 not_cached_misses_count); | |
| 160 UMA_HISTOGRAM_COUNTS_100( | |
| 161 internal::kResourcePrefetchPredictorPrefetchHitsCountCached, | |
| 162 cached_hits_count); | |
| 163 UMA_HISTOGRAM_COUNTS_100( | |
| 164 internal::kResourcePrefetchPredictorPrefetchHitsCountNotCached, | |
| 165 not_cached_hits_count); | |
| 166 UMA_HISTOGRAM_COUNTS_10000( | |
| 167 internal::kResourcePrefetchPredictorPrefetchHitsSize, hits_bytes / 1024); | |
|
Ilya Sherman
2017/02/15 00:07:41
This goes up to about 10MB, right? Is that enough
Benoit L
2017/02/15 09:55:34
I think so, yes. The amount of actual data fetched
| |
| 168 UMA_HISTOGRAM_COUNTS_10000( | |
| 169 internal::kResourcePrefetchPredictorPrefetchMissesSize, | |
| 170 misses_bytes / 1024); | |
| 171 } | |
| 172 | |
| 123 void ReportPredictionAccuracy( | 173 void ReportPredictionAccuracy( |
| 124 const std::vector<GURL>& predicted_urls, | 174 const std::vector<GURL>& predicted_urls, |
| 125 const ResourcePrefetchPredictor::PageRequestSummary& summary) { | 175 const ResourcePrefetchPredictor::PageRequestSummary& summary) { |
| 126 DCHECK(!predicted_urls.empty()); | 176 DCHECK(!predicted_urls.empty()); |
| 127 | 177 |
| 128 if (predicted_urls.empty() || summary.subresource_requests.empty()) | 178 if (predicted_urls.empty() || summary.subresource_requests.empty()) |
| 129 return; | 179 return; |
| 130 | 180 |
| 131 std::set<GURL> predicted_urls_set(predicted_urls.begin(), | 181 std::set<GURL> predicted_urls_set(predicted_urls.begin(), |
| 132 predicted_urls.end()); | 182 predicted_urls.end()); |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 542 if (!prefetch_manager_.get()) // Not enabled. | 592 if (!prefetch_manager_.get()) // Not enabled. |
| 543 return; | 593 return; |
| 544 | 594 |
| 545 BrowserThread::PostTask( | 595 BrowserThread::PostTask( |
| 546 BrowserThread::IO, FROM_HERE, | 596 BrowserThread::IO, FROM_HERE, |
| 547 base::Bind(&ResourcePrefetcherManager::MaybeRemovePrefetch, | 597 base::Bind(&ResourcePrefetcherManager::MaybeRemovePrefetch, |
| 548 prefetch_manager_, url)); | 598 prefetch_manager_, url)); |
| 549 } | 599 } |
| 550 | 600 |
| 551 void ResourcePrefetchPredictor::OnPrefetchingFinished( | 601 void ResourcePrefetchPredictor::OnPrefetchingFinished( |
| 552 const GURL& main_frame_url) { | 602 const GURL& main_frame_url, |
| 603 std::unique_ptr<ResourcePrefetcher::PrefetcherStats> stats) { | |
| 553 if (observer_) | 604 if (observer_) |
| 554 observer_->OnPrefetchingFinished(main_frame_url); | 605 observer_->OnPrefetchingFinished(main_frame_url); |
| 606 | |
| 607 prefetcher_stats_.insert(std::make_pair(main_frame_url, std::move(stats))); | |
| 555 } | 608 } |
| 556 | 609 |
| 557 bool ResourcePrefetchPredictor::IsUrlPrefetchable(const GURL& main_frame_url) { | 610 bool ResourcePrefetchPredictor::IsUrlPrefetchable(const GURL& main_frame_url) { |
| 558 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 611 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 559 if (initialization_state_ != INITIALIZED) | 612 if (initialization_state_ != INITIALIZED) |
| 560 return false; | 613 return false; |
| 561 | 614 |
| 562 return GetPrefetchData(main_frame_url, nullptr); | 615 return GetPrefetchData(main_frame_url, nullptr); |
| 563 } | 616 } |
| 564 | 617 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 575 } | 628 } |
| 576 | 629 |
| 577 void ResourcePrefetchPredictor::OnMainFrameRequest( | 630 void ResourcePrefetchPredictor::OnMainFrameRequest( |
| 578 const URLRequestSummary& request) { | 631 const URLRequestSummary& request) { |
| 579 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 632 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 580 DCHECK_EQ(INITIALIZED, initialization_state_); | 633 DCHECK_EQ(INITIALIZED, initialization_state_); |
| 581 | 634 |
| 582 const GURL& main_frame_url = request.navigation_id.main_frame_url; | 635 const GURL& main_frame_url = request.navigation_id.main_frame_url; |
| 583 StartPrefetching(main_frame_url, PrefetchOrigin::NAVIGATION); | 636 StartPrefetching(main_frame_url, PrefetchOrigin::NAVIGATION); |
| 584 | 637 |
| 585 // Cleanup older navigations. | |
| 586 CleanupAbandonedNavigations(request.navigation_id); | 638 CleanupAbandonedNavigations(request.navigation_id); |
| 587 | 639 |
| 588 // New empty navigation entry. | 640 // New empty navigation entry. |
| 589 inflight_navigations_.insert( | 641 inflight_navigations_.insert( |
| 590 std::make_pair(request.navigation_id, | 642 std::make_pair(request.navigation_id, |
| 591 base::MakeUnique<PageRequestSummary>(main_frame_url))); | 643 base::MakeUnique<PageRequestSummary>(main_frame_url))); |
| 592 } | 644 } |
| 593 | 645 |
| 594 void ResourcePrefetchPredictor::OnMainFrameResponse( | 646 void ResourcePrefetchPredictor::OnMainFrameResponse( |
| 595 const URLRequestSummary& response) { | 647 const URLRequestSummary& response) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 650 | 702 |
| 651 NavigationMap::iterator nav_it = | 703 NavigationMap::iterator nav_it = |
| 652 inflight_navigations_.find(nav_id_without_timing_info); | 704 inflight_navigations_.find(nav_id_without_timing_info); |
| 653 if (nav_it == inflight_navigations_.end()) | 705 if (nav_it == inflight_navigations_.end()) |
| 654 return; | 706 return; |
| 655 | 707 |
| 656 // Remove the navigation from the inflight navigations. | 708 // Remove the navigation from the inflight navigations. |
| 657 std::unique_ptr<PageRequestSummary> summary = std::move(nav_it->second); | 709 std::unique_ptr<PageRequestSummary> summary = std::move(nav_it->second); |
| 658 inflight_navigations_.erase(nav_it); | 710 inflight_navigations_.erase(nav_it); |
| 659 | 711 |
| 712 const GURL& main_frame_url = nav_id_without_timing_info.main_frame_url; | |
| 660 std::vector<GURL> predicted_urls; | 713 std::vector<GURL> predicted_urls; |
| 661 bool has_data = GetPrefetchData(nav_id_without_timing_info.main_frame_url, | 714 bool has_data = GetPrefetchData(main_frame_url, &predicted_urls); |
| 662 &predicted_urls); | |
| 663 if (has_data) | 715 if (has_data) |
| 664 ReportPredictionAccuracy(predicted_urls, *summary); | 716 ReportPredictionAccuracy(predicted_urls, *summary); |
| 665 | 717 |
| 718 auto it = prefetcher_stats_.find(main_frame_url); | |
| 719 if (it != prefetcher_stats_.end()) { | |
| 720 const std::vector<URLRequestSummary>& summaries = | |
| 721 summary->subresource_requests; | |
| 722 ReportPrefetchAccuracy(*it->second, summaries); | |
| 723 prefetcher_stats_.erase(it); | |
| 724 } | |
| 725 | |
| 666 // Kick off history lookup to determine if we should record the URL. | 726 // Kick off history lookup to determine if we should record the URL. |
| 667 history::HistoryService* history_service = | 727 history::HistoryService* history_service = |
| 668 HistoryServiceFactory::GetForProfile(profile_, | 728 HistoryServiceFactory::GetForProfile(profile_, |
| 669 ServiceAccessType::EXPLICIT_ACCESS); | 729 ServiceAccessType::EXPLICIT_ACCESS); |
| 670 DCHECK(history_service); | 730 DCHECK(history_service); |
| 671 history_service->ScheduleDBTask( | 731 history_service->ScheduleDBTask( |
| 672 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( | 732 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( |
| 673 std::move(summary), | 733 std::move(summary), |
| 674 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, | 734 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, |
| 675 AsWeakPtr()))), | 735 AsWeakPtr()))), |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 785 } | 845 } |
| 786 } | 846 } |
| 787 | 847 |
| 788 for (auto it = inflight_prefetches_.begin(); | 848 for (auto it = inflight_prefetches_.begin(); |
| 789 it != inflight_prefetches_.end();) { | 849 it != inflight_prefetches_.end();) { |
| 790 if (time_now - it->second > max_navigation_age) | 850 if (time_now - it->second > max_navigation_age) |
| 791 it = inflight_prefetches_.erase(it); | 851 it = inflight_prefetches_.erase(it); |
| 792 else | 852 else |
| 793 ++it; | 853 ++it; |
| 794 } | 854 } |
| 855 | |
| 856 // Remove old prefetches that haven't been claimed. | |
| 857 for (auto stats_it = prefetcher_stats_.begin(); | |
| 858 stats_it != prefetcher_stats_.end();) { | |
| 859 if (time_now - stats_it->second->start_time > max_navigation_age) { | |
| 860 // No requests -> everything is a miss. | |
| 861 ReportPrefetchAccuracy(*stats_it->second, | |
| 862 std::vector<URLRequestSummary>()); | |
| 863 stats_it = prefetcher_stats_.erase(stats_it); | |
| 864 } else { | |
| 865 ++stats_it; | |
| 866 } | |
| 867 } | |
| 795 } | 868 } |
| 796 | 869 |
| 797 void ResourcePrefetchPredictor::DeleteAllUrls() { | 870 void ResourcePrefetchPredictor::DeleteAllUrls() { |
| 798 inflight_navigations_.clear(); | 871 inflight_navigations_.clear(); |
| 799 url_table_cache_->clear(); | 872 url_table_cache_->clear(); |
| 800 host_table_cache_->clear(); | 873 host_table_cache_->clear(); |
| 801 url_redirect_table_cache_->clear(); | 874 url_redirect_table_cache_->clear(); |
| 802 host_redirect_table_cache_->clear(); | 875 host_redirect_table_cache_->clear(); |
| 803 | 876 |
| 804 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, | 877 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1264 TestObserver::~TestObserver() { | 1337 TestObserver::~TestObserver() { |
| 1265 predictor_->SetObserverForTesting(nullptr); | 1338 predictor_->SetObserverForTesting(nullptr); |
| 1266 } | 1339 } |
| 1267 | 1340 |
| 1268 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) | 1341 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) |
| 1269 : predictor_(predictor) { | 1342 : predictor_(predictor) { |
| 1270 predictor_->SetObserverForTesting(this); | 1343 predictor_->SetObserverForTesting(this); |
| 1271 } | 1344 } |
| 1272 | 1345 |
| 1273 } // namespace predictors | 1346 } // namespace predictors |
| OLD | NEW |