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 size_t misses_bytes = 0; | |
139 size_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); | |
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 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
527 if (!prefetch_manager_.get()) // Not enabled. | 577 if (!prefetch_manager_.get()) // Not enabled. |
528 return; | 578 return; |
529 | 579 |
530 BrowserThread::PostTask( | 580 BrowserThread::PostTask( |
531 BrowserThread::IO, FROM_HERE, | 581 BrowserThread::IO, FROM_HERE, |
532 base::Bind(&ResourcePrefetcherManager::MaybeRemovePrefetch, | 582 base::Bind(&ResourcePrefetcherManager::MaybeRemovePrefetch, |
533 prefetch_manager_, url)); | 583 prefetch_manager_, url)); |
534 } | 584 } |
535 | 585 |
536 void ResourcePrefetchPredictor::OnPrefetchingFinished( | 586 void ResourcePrefetchPredictor::OnPrefetchingFinished( |
537 const GURL& main_frame_url) { | 587 const GURL& main_frame_url, |
588 const ResourcePrefetcher::PrefetcherStats& stats) { | |
538 if (observer_) | 589 if (observer_) |
539 observer_->OnPrefetchingFinished(main_frame_url); | 590 observer_->OnPrefetchingFinished(main_frame_url, stats); |
alexilin
2017/02/09 15:24:17
You don't use stats inside an observer. Why?
Benoit L
2017/02/13 16:13:15
Done.
| |
591 | |
592 prefetcher_stats_.insert({main_frame_url, stats}); | |
540 } | 593 } |
541 | 594 |
542 bool ResourcePrefetchPredictor::IsUrlPrefetchable(const GURL& main_frame_url) { | 595 bool ResourcePrefetchPredictor::IsUrlPrefetchable(const GURL& main_frame_url) { |
543 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 596 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
544 if (initialization_state_ != INITIALIZED) | 597 if (initialization_state_ != INITIALIZED) |
545 return false; | 598 return false; |
546 | 599 |
547 return GetPrefetchData(main_frame_url, nullptr); | 600 return GetPrefetchData(main_frame_url, nullptr); |
548 } | 601 } |
549 | 602 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
635 | 688 |
636 NavigationMap::iterator nav_it = | 689 NavigationMap::iterator nav_it = |
637 inflight_navigations_.find(nav_id_without_timing_info); | 690 inflight_navigations_.find(nav_id_without_timing_info); |
638 if (nav_it == inflight_navigations_.end()) | 691 if (nav_it == inflight_navigations_.end()) |
639 return; | 692 return; |
640 | 693 |
641 // Remove the navigation from the inflight navigations. | 694 // Remove the navigation from the inflight navigations. |
642 std::unique_ptr<PageRequestSummary> summary = std::move(nav_it->second); | 695 std::unique_ptr<PageRequestSummary> summary = std::move(nav_it->second); |
643 inflight_navigations_.erase(nav_it); | 696 inflight_navigations_.erase(nav_it); |
644 | 697 |
698 const GURL& main_frame_url = nav_id_without_timing_info.main_frame_url; | |
645 std::vector<GURL> predicted_urls; | 699 std::vector<GURL> predicted_urls; |
646 bool has_data = GetPrefetchData(nav_id_without_timing_info.main_frame_url, | 700 bool has_data = GetPrefetchData(main_frame_url, &predicted_urls); |
647 &predicted_urls); | |
648 if (has_data) | 701 if (has_data) |
649 ReportPredictionAccuracy(predicted_urls, *summary); | 702 ReportPredictionAccuracy(predicted_urls, *summary); |
650 | 703 |
704 auto it = prefetcher_stats_.find(main_frame_url); | |
alexilin
2017/02/09 15:24:17
I suspect that prefetching can end after navigatio
Benoit L
2017/02/13 16:13:15
Yes, that's possible, but I don't think it's worth
alexilin
2017/02/13 17:07:05
Yes, I also think that this case isn't worth the a
| |
705 if (it != prefetcher_stats_.end()) { | |
706 const std::vector<URLRequestSummary>& summaries = | |
707 summary->subresource_requests; | |
708 ReportPrefetchAccuracy(it->second, summaries); | |
709 prefetcher_stats_.erase(it); | |
710 } | |
711 | |
712 // Remove old prefetches that haven't been claimed. | |
alexilin
2017/02/09 15:24:17
Could you move this into CleanupAbandonedNavigatio
Benoit L
2017/02/13 16:13:15
Done.
| |
713 base::TimeTicks now = base::TimeTicks::Now(); | |
714 it = prefetcher_stats_.begin(); | |
715 while (it != prefetcher_stats_.end()) { | |
716 if (now - it->second.start_time > base::TimeDelta::FromMinutes(5)) { | |
717 // No requests -> everything is a miss. | |
718 ReportPrefetchAccuracy(it->second, std::vector<URLRequestSummary>()); | |
719 it = prefetcher_stats_.erase(it); | |
720 } else { | |
721 ++it; | |
722 } | |
723 } | |
724 | |
651 // Kick off history lookup to determine if we should record the URL. | 725 // Kick off history lookup to determine if we should record the URL. |
652 history::HistoryService* history_service = | 726 history::HistoryService* history_service = |
653 HistoryServiceFactory::GetForProfile(profile_, | 727 HistoryServiceFactory::GetForProfile(profile_, |
654 ServiceAccessType::EXPLICIT_ACCESS); | 728 ServiceAccessType::EXPLICIT_ACCESS); |
655 DCHECK(history_service); | 729 DCHECK(history_service); |
656 history_service->ScheduleDBTask( | 730 history_service->ScheduleDBTask( |
657 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( | 731 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( |
658 std::move(summary), | 732 std::move(summary), |
659 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, | 733 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, |
660 AsWeakPtr()))), | 734 AsWeakPtr()))), |
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1241 TestObserver::~TestObserver() { | 1315 TestObserver::~TestObserver() { |
1242 predictor_->SetObserverForTesting(nullptr); | 1316 predictor_->SetObserverForTesting(nullptr); |
1243 } | 1317 } |
1244 | 1318 |
1245 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) | 1319 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) |
1246 : predictor_(predictor) { | 1320 : predictor_(predictor) { |
1247 predictor_->SetObserverForTesting(this); | 1321 predictor_->SetObserverForTesting(this); |
1248 } | 1322 } |
1249 | 1323 |
1250 } // namespace predictors | 1324 } // namespace predictors |
OLD | NEW |