Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: chrome/browser/predictors/resource_prefetch_predictor.cc

Issue 2719533002: predictors: Add RedirectStatus histogram + fix redirects related bug. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 internal::kResourcePrefetchPredictorPrefetchHitsCountNotCached, 164 internal::kResourcePrefetchPredictorPrefetchHitsCountNotCached,
165 not_cached_hits_count); 165 not_cached_hits_count);
166 UMA_HISTOGRAM_COUNTS_10000( 166 UMA_HISTOGRAM_COUNTS_10000(
167 internal::kResourcePrefetchPredictorPrefetchHitsSize, hits_bytes / 1024); 167 internal::kResourcePrefetchPredictorPrefetchHitsSize, hits_bytes / 1024);
168 UMA_HISTOGRAM_COUNTS_10000( 168 UMA_HISTOGRAM_COUNTS_10000(
169 internal::kResourcePrefetchPredictorPrefetchMissesSize, 169 internal::kResourcePrefetchPredictorPrefetchMissesSize,
170 misses_bytes / 1024); 170 misses_bytes / 1024);
171 } 171 }
172 172
173 void ReportPredictionAccuracy( 173 void ReportPredictionAccuracy(
174 const std::vector<GURL>& predicted_urls, 174 const ResourcePrefetchPredictor::Prediction& prediction,
175 const ResourcePrefetchPredictor::PageRequestSummary& summary) { 175 const ResourcePrefetchPredictor::PageRequestSummary& summary) {
176 DCHECK(!predicted_urls.empty()); 176 const std::vector<GURL>& predicted_urls = prediction.subresource_urls;
177
178 if (predicted_urls.empty() || summary.subresource_requests.empty()) 177 if (predicted_urls.empty() || summary.subresource_requests.empty())
179 return; 178 return;
180 179
181 std::set<GURL> predicted_urls_set(predicted_urls.begin(), 180 std::set<GURL> predicted_urls_set(predicted_urls.begin(),
182 predicted_urls.end()); 181 predicted_urls.end());
183 std::set<GURL> actual_urls_set; 182 std::set<GURL> actual_urls_set;
184 for (const auto& request_summary : summary.subresource_requests) 183 for (const auto& request_summary : summary.subresource_requests)
185 actual_urls_set.insert(request_summary.resource_url); 184 actual_urls_set.insert(request_summary.resource_url);
186 185
187 size_t correctly_predicted_count = 0; 186 size_t correctly_predicted_count = 0;
188 for (const GURL& predicted_url : predicted_urls_set) { 187 for (const GURL& predicted_url : predicted_urls_set) {
189 if (actual_urls_set.find(predicted_url) != actual_urls_set.end()) 188 if (actual_urls_set.find(predicted_url) != actual_urls_set.end())
190 correctly_predicted_count++; 189 correctly_predicted_count++;
191 } 190 }
192 191
193 size_t precision_percentage = 192 size_t precision_percentage =
194 (100 * correctly_predicted_count) / predicted_urls_set.size(); 193 (100 * correctly_predicted_count) / predicted_urls_set.size();
195 size_t recall_percentage = 194 size_t recall_percentage =
196 (100 * correctly_predicted_count) / actual_urls_set.size(); 195 (100 * correctly_predicted_count) / actual_urls_set.size();
197 196
197 using RedirectStatus = ResourcePrefetchPredictor::RedirectStatus;
198 RedirectStatus redirect_status;
199 if (summary.main_frame_url == summary.initial_url) {
200 // The actual navigation wasn't redirected.
201 redirect_status = prediction.is_redirected
202 ? RedirectStatus::NO_REDIRECT_BUT_PREDICTED
203 : RedirectStatus::NO_REDIRECT;
204 } else {
205 if (prediction.is_redirected) {
206 std::string main_frame_key = prediction.is_host
207 ? summary.main_frame_url.host()
208 : summary.main_frame_url.spec();
209 redirect_status = main_frame_key == prediction.main_frame_key
210 ? RedirectStatus::REDIRECT_CORRECTLY_PREDICTED
211 : RedirectStatus::REDIRECT_WRONG_PREDICTED;
212 } else {
213 redirect_status = RedirectStatus::REDIRECT_NOT_PREDICTED;
214 }
215 }
216
198 UMA_HISTOGRAM_PERCENTAGE( 217 UMA_HISTOGRAM_PERCENTAGE(
199 internal::kResourcePrefetchPredictorPrecisionHistogram, 218 internal::kResourcePrefetchPredictorPrecisionHistogram,
200 precision_percentage); 219 precision_percentage);
201 UMA_HISTOGRAM_PERCENTAGE(internal::kResourcePrefetchPredictorRecallHistogram, 220 UMA_HISTOGRAM_PERCENTAGE(internal::kResourcePrefetchPredictorRecallHistogram,
202 recall_percentage); 221 recall_percentage);
203 UMA_HISTOGRAM_COUNTS_100(internal::kResourcePrefetchPredictorCountHistogram, 222 UMA_HISTOGRAM_COUNTS_100(internal::kResourcePrefetchPredictorCountHistogram,
204 predicted_urls.size()); 223 predicted_urls.size());
224 UMA_HISTOGRAM_ENUMERATION(
225 internal::kResourcePrefetchPredictorRedirectStatusHistogram,
226 static_cast<int>(redirect_status), static_cast<int>(RedirectStatus::MAX));
205 } 227 }
206 228
207 } // namespace 229 } // namespace
208 230
209 //////////////////////////////////////////////////////////////////////////////// 231 ////////////////////////////////////////////////////////////////////////////////
210 // ResourcePrefetchPredictor static functions. 232 // ResourcePrefetchPredictor static functions.
211 233
212 // static 234 // static
213 bool ResourcePrefetchPredictor::ShouldRecordRequest( 235 bool ResourcePrefetchPredictor::ShouldRecordRequest(
214 net::URLRequest* request, 236 net::URLRequest* request,
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 464
443 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( 465 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary(
444 const GURL& i_main_frame_url) 466 const GURL& i_main_frame_url)
445 : main_frame_url(i_main_frame_url), initial_url(i_main_frame_url) {} 467 : main_frame_url(i_main_frame_url), initial_url(i_main_frame_url) {}
446 468
447 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( 469 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary(
448 const PageRequestSummary& other) = default; 470 const PageRequestSummary& other) = default;
449 471
450 ResourcePrefetchPredictor::PageRequestSummary::~PageRequestSummary() {} 472 ResourcePrefetchPredictor::PageRequestSummary::~PageRequestSummary() {}
451 473
474 ResourcePrefetchPredictor::Prediction::Prediction() = default;
475
476 ResourcePrefetchPredictor::Prediction::Prediction(
477 const ResourcePrefetchPredictor::Prediction& other) = default;
478
479 ResourcePrefetchPredictor::Prediction::~Prediction() = default;
480
452 //////////////////////////////////////////////////////////////////////////////// 481 ////////////////////////////////////////////////////////////////////////////////
453 // ResourcePrefetchPredictor. 482 // ResourcePrefetchPredictor.
454 483
455 ResourcePrefetchPredictor::ResourcePrefetchPredictor( 484 ResourcePrefetchPredictor::ResourcePrefetchPredictor(
456 const ResourcePrefetchPredictorConfig& config, 485 const ResourcePrefetchPredictorConfig& config,
457 Profile* profile) 486 Profile* profile)
458 : profile_(profile), 487 : profile_(profile),
459 observer_(nullptr), 488 observer_(nullptr),
460 config_(config), 489 config_(config),
461 initialization_state_(NOT_INITIALIZED), 490 initialization_state_(NOT_INITIALIZED),
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 if (inflight_prefetches_.find(url) == inflight_prefetches_.end() && 591 if (inflight_prefetches_.find(url) == inflight_prefetches_.end() &&
563 IsUrlPrefetchable(url)) { 592 IsUrlPrefetchable(url)) {
564 inflight_prefetches_.insert(std::make_pair(url, base::TimeTicks::Now())); 593 inflight_prefetches_.insert(std::make_pair(url, base::TimeTicks::Now()));
565 } 594 }
566 595
567 if (!prefetch_manager_.get()) // Prefetching not enabled. 596 if (!prefetch_manager_.get()) // Prefetching not enabled.
568 return; 597 return;
569 if (!config_.IsPrefetchingEnabledForOrigin(profile_, origin)) 598 if (!config_.IsPrefetchingEnabledForOrigin(profile_, origin))
570 return; 599 return;
571 600
572 std::vector<GURL> subresource_urls; 601 ResourcePrefetchPredictor::Prediction prediction;
573 if (!GetPrefetchData(url, &subresource_urls)) 602 if (!GetPrefetchData(url, &prediction))
574 return; 603 return;
575 604
576 BrowserThread::PostTask( 605 BrowserThread::PostTask(
577 BrowserThread::IO, FROM_HERE, 606 BrowserThread::IO, FROM_HERE,
578 base::Bind(&ResourcePrefetcherManager::MaybeAddPrefetch, 607 base::Bind(&ResourcePrefetcherManager::MaybeAddPrefetch,
579 prefetch_manager_, url, subresource_urls)); 608 prefetch_manager_, url, prediction.subresource_urls));
580 } 609 }
581 610
582 void ResourcePrefetchPredictor::StopPrefetching(const GURL& url) { 611 void ResourcePrefetchPredictor::StopPrefetching(const GURL& url) {
583 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StopPrefetching", "url", 612 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StopPrefetching", "url",
584 url.spec()); 613 url.spec());
585 auto it = inflight_prefetches_.find(url); 614 auto it = inflight_prefetches_.find(url);
586 if (it != inflight_prefetches_.end()) { 615 if (it != inflight_prefetches_.end()) {
587 UMA_HISTOGRAM_TIMES( 616 UMA_HISTOGRAM_TIMES(
588 internal::kResourcePrefetchPredictorPrefetchingDurationHistogram, 617 internal::kResourcePrefetchPredictorPrefetchingDurationHistogram,
589 base::TimeTicks::Now() - it->second); 618 base::TimeTicks::Now() - it->second);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 731
703 NavigationMap::iterator nav_it = 732 NavigationMap::iterator nav_it =
704 inflight_navigations_.find(nav_id_without_timing_info); 733 inflight_navigations_.find(nav_id_without_timing_info);
705 if (nav_it == inflight_navigations_.end()) 734 if (nav_it == inflight_navigations_.end())
706 return; 735 return;
707 736
708 // Remove the navigation from the inflight navigations. 737 // Remove the navigation from the inflight navigations.
709 std::unique_ptr<PageRequestSummary> summary = std::move(nav_it->second); 738 std::unique_ptr<PageRequestSummary> summary = std::move(nav_it->second);
710 inflight_navigations_.erase(nav_it); 739 inflight_navigations_.erase(nav_it);
711 740
712 const GURL& main_frame_url = nav_id_without_timing_info.main_frame_url; 741 const GURL& initial_url = summary->initial_url;
alexilin 2017/02/24 17:24:10 This is a bug that I'm talking about. We starts pr
713 std::vector<GURL> predicted_urls; 742 ResourcePrefetchPredictor::Prediction prediction;
714 bool has_data = GetPrefetchData(main_frame_url, &predicted_urls); 743 bool has_data = GetPrefetchData(initial_url, &prediction);
715 if (has_data) 744 if (has_data)
716 ReportPredictionAccuracy(predicted_urls, *summary); 745 ReportPredictionAccuracy(prediction, *summary);
717 746
718 auto it = prefetcher_stats_.find(main_frame_url); 747 auto it = prefetcher_stats_.find(initial_url);
719 if (it != prefetcher_stats_.end()) { 748 if (it != prefetcher_stats_.end()) {
720 const std::vector<URLRequestSummary>& summaries = 749 const std::vector<URLRequestSummary>& summaries =
721 summary->subresource_requests; 750 summary->subresource_requests;
722 ReportPrefetchAccuracy(*it->second, summaries); 751 ReportPrefetchAccuracy(*it->second, summaries);
723 prefetcher_stats_.erase(it); 752 prefetcher_stats_.erase(it);
724 } 753 }
725 754
726 // Kick off history lookup to determine if we should record the URL. 755 // Kick off history lookup to determine if we should record the URL.
727 history::HistoryService* history_service = 756 history::HistoryService* history_service =
728 HistoryServiceFactory::GetForProfile(profile_, 757 HistoryServiceFactory::GetForProfile(profile_,
729 ServiceAccessType::EXPLICIT_ACCESS); 758 ServiceAccessType::EXPLICIT_ACCESS);
730 DCHECK(history_service); 759 DCHECK(history_service);
731 history_service->ScheduleDBTask( 760 history_service->ScheduleDBTask(
732 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( 761 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask(
733 std::move(summary), 762 std::move(summary),
734 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, 763 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup,
735 AsWeakPtr()))), 764 AsWeakPtr()))),
736 &history_lookup_consumer_); 765 &history_lookup_consumer_);
737 766
738 // Report readiness metric with 20% probability. 767 // Report readiness metric with 20% probability.
739 if (base::RandInt(1, 5) == 5) { 768 if (base::RandInt(1, 5) == 5) {
740 history_service->TopHosts( 769 history_service->TopHosts(
741 kNumSampleHosts, 770 kNumSampleHosts,
742 base::Bind(&ResourcePrefetchPredictor::ReportDatabaseReadiness, 771 base::Bind(&ResourcePrefetchPredictor::ReportDatabaseReadiness,
743 AsWeakPtr())); 772 AsWeakPtr()));
744 } 773 }
745 } 774 }
746 775
747 bool ResourcePrefetchPredictor::GetPrefetchData(const GURL& main_frame_url, 776 bool ResourcePrefetchPredictor::GetPrefetchData(
748 std::vector<GURL>* urls) const { 777 const GURL& main_frame_url,
778 ResourcePrefetchPredictor::Prediction* prediction) const {
779 std::vector<GURL>* urls =
780 prediction ? &prediction->subresource_urls : nullptr;
749 DCHECK(!urls || urls->empty()); 781 DCHECK(!urls || urls->empty());
750 782
751 // Fetch URLs based on a redirect endpoint for URL/host first. 783 // Fetch URLs based on a redirect endpoint for URL/host first.
752 std::string redirect_endpoint; 784 std::string redirect_endpoint;
753 if (GetRedirectEndpoint(main_frame_url.spec(), *url_redirect_table_cache_, 785 if (GetRedirectEndpoint(main_frame_url.spec(), *url_redirect_table_cache_,
754 &redirect_endpoint) && 786 &redirect_endpoint) &&
755 PopulatePrefetcherRequest(redirect_endpoint, *url_table_cache_, urls)) { 787 PopulatePrefetcherRequest(redirect_endpoint, *url_table_cache_, urls)) {
788 if (prediction) {
789 prediction->is_host = false;
790 prediction->is_redirected = true;
791 prediction->main_frame_key = redirect_endpoint;
792 }
756 return true; 793 return true;
757 } 794 }
758 795
759 if (GetRedirectEndpoint(main_frame_url.host(), *host_redirect_table_cache_, 796 if (GetRedirectEndpoint(main_frame_url.host(), *host_redirect_table_cache_,
760 &redirect_endpoint) && 797 &redirect_endpoint) &&
761 PopulatePrefetcherRequest(redirect_endpoint, *host_table_cache_, urls)) { 798 PopulatePrefetcherRequest(redirect_endpoint, *host_table_cache_, urls)) {
799 if (prediction) {
800 prediction->is_host = true;
801 prediction->is_redirected = true;
802 prediction->main_frame_key = redirect_endpoint;
803 }
762 return true; 804 return true;
763 } 805 }
764 806
765 // Fallback to fetching URLs based on the incoming URL/host. 807 // Fallback to fetching URLs based on the incoming URL/host.
766 if (PopulatePrefetcherRequest(main_frame_url.spec(), *url_table_cache_, 808 if (PopulatePrefetcherRequest(main_frame_url.spec(), *url_table_cache_,
767 urls)) { 809 urls)) {
810 if (prediction) {
811 prediction->is_host = false;
812 prediction->is_redirected = false;
813 prediction->main_frame_key = main_frame_url.spec();
814 }
768 return true; 815 return true;
769 } 816 }
770 817
771 return PopulatePrefetcherRequest(main_frame_url.host(), *host_table_cache_, 818 if (PopulatePrefetcherRequest(main_frame_url.host(), *host_table_cache_,
772 urls); 819 urls)) {
820 if (prediction) {
821 prediction->is_host = true;
822 prediction->is_redirected = false;
823 prediction->main_frame_key = main_frame_url.host();
824 }
825 return true;
826 }
827
828 return false;
773 } 829 }
774 830
775 bool ResourcePrefetchPredictor::PopulatePrefetcherRequest( 831 bool ResourcePrefetchPredictor::PopulatePrefetcherRequest(
776 const std::string& main_frame_key, 832 const std::string& main_frame_key,
777 const PrefetchDataMap& data_map, 833 const PrefetchDataMap& data_map,
778 std::vector<GURL>* urls) const { 834 std::vector<GURL>* urls) const {
779 PrefetchDataMap::const_iterator it = data_map.find(main_frame_key); 835 PrefetchDataMap::const_iterator it = data_map.find(main_frame_key);
780 if (it == data_map.end()) 836 if (it == data_map.end())
781 return false; 837 return false;
782 838
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 TestObserver::~TestObserver() { 1393 TestObserver::~TestObserver() {
1338 predictor_->SetObserverForTesting(nullptr); 1394 predictor_->SetObserverForTesting(nullptr);
1339 } 1395 }
1340 1396
1341 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) 1397 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor)
1342 : predictor_(predictor) { 1398 : predictor_(predictor) {
1343 predictor_->SetObserverForTesting(this); 1399 predictor_->SetObserverForTesting(this);
1344 } 1400 }
1345 1401
1346 } // namespace predictors 1402 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698