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

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

Issue 2887133003: predictors: Refactor resource_prefetch_predictor triggering. (Closed)
Patch Set: . Created 3 years, 6 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 600 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 CHECK_EQ(request.resource_type, content::RESOURCE_TYPE_MAIN_FRAME); 611 CHECK_EQ(request.resource_type, content::RESOURCE_TYPE_MAIN_FRAME);
612 OnMainFrameRequest(request); 612 OnMainFrameRequest(request);
613 } 613 }
614 614
615 void ResourcePrefetchPredictor::RecordURLResponse( 615 void ResourcePrefetchPredictor::RecordURLResponse(
616 const URLRequestSummary& response) { 616 const URLRequestSummary& response) {
617 DCHECK_CURRENTLY_ON(BrowserThread::UI); 617 DCHECK_CURRENTLY_ON(BrowserThread::UI);
618 if (initialization_state_ != INITIALIZED) 618 if (initialization_state_ != INITIALIZED)
619 return; 619 return;
620 620
621 if (response.resource_type == content::RESOURCE_TYPE_MAIN_FRAME) 621 if (response.resource_type != content::RESOURCE_TYPE_MAIN_FRAME)
622 OnMainFrameResponse(response);
623 else
624 OnSubresourceResponse(response); 622 OnSubresourceResponse(response);
625 } 623 }
626 624
627 void ResourcePrefetchPredictor::RecordURLRedirect( 625 void ResourcePrefetchPredictor::RecordURLRedirect(
628 const URLRequestSummary& response) { 626 const URLRequestSummary& response) {
629 DCHECK_CURRENTLY_ON(BrowserThread::UI); 627 DCHECK_CURRENTLY_ON(BrowserThread::UI);
630 if (initialization_state_ != INITIALIZED) 628 if (initialization_state_ != INITIALIZED)
631 return; 629 return;
632 630
633 if (response.resource_type == content::RESOURCE_TYPE_MAIN_FRAME) 631 if (response.resource_type == content::RESOURCE_TYPE_MAIN_FRAME)
(...skipping 27 matching lines...) Expand all
661 const base::TimeTicks& first_contentful_paint) { 659 const base::TimeTicks& first_contentful_paint) {
662 DCHECK_CURRENTLY_ON(BrowserThread::UI); 660 DCHECK_CURRENTLY_ON(BrowserThread::UI);
663 if (initialization_state_ != INITIALIZED) 661 if (initialization_state_ != INITIALIZED)
664 return; 662 return;
665 663
666 NavigationMap::iterator nav_it = inflight_navigations_.find(navigation_id); 664 NavigationMap::iterator nav_it = inflight_navigations_.find(navigation_id);
667 if (nav_it != inflight_navigations_.end()) 665 if (nav_it != inflight_navigations_.end())
668 nav_it->second->first_contentful_paint = first_contentful_paint; 666 nav_it->second->first_contentful_paint = first_contentful_paint;
669 } 667 }
670 668
671 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url,
672 HintOrigin origin) {
673 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StartPrefetching", "url",
674 url.spec());
675 // Save prefetch start time to report prefetching duration.
676 if (inflight_prefetches_.find(url) == inflight_prefetches_.end() &&
677 IsUrlPrefetchable(url)) {
678 inflight_prefetches_.insert(std::make_pair(url, base::TimeTicks::Now()));
679 }
680
681 if (!prefetch_manager_.get()) // Prefetching not enabled.
682 return;
683 if (!config_.IsPrefetchingEnabledForOrigin(profile_, origin))
684 return;
685
686 ResourcePrefetchPredictor::Prediction prediction;
687 if (!GetPrefetchData(url, &prediction))
688 return;
689
690 BrowserThread::PostTask(
691 BrowserThread::IO, FROM_HERE,
692 base::BindOnce(&ResourcePrefetcherManager::MaybeAddPrefetch,
693 prefetch_manager_, url, prediction.subresource_urls));
694
695 if (observer_)
696 observer_->OnPrefetchingStarted(url);
697 }
698
699 void ResourcePrefetchPredictor::StopPrefetching(const GURL& url) {
700 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StopPrefetching", "url",
701 url.spec());
702 auto it = inflight_prefetches_.find(url);
703 if (it != inflight_prefetches_.end()) {
704 UMA_HISTOGRAM_TIMES(
705 internal::kResourcePrefetchPredictorPrefetchingDurationHistogram,
706 base::TimeTicks::Now() - it->second);
707 inflight_prefetches_.erase(it);
708 }
709 if (!prefetch_manager_.get()) // Not enabled.
710 return;
711
712 BrowserThread::PostTask(
713 BrowserThread::IO, FROM_HERE,
714 base::BindOnce(&ResourcePrefetcherManager::MaybeRemovePrefetch,
715 prefetch_manager_, url));
716
717 if (observer_)
718 observer_->OnPrefetchingStopped(url);
719 }
720
721 void ResourcePrefetchPredictor::OnPrefetchingFinished( 669 void ResourcePrefetchPredictor::OnPrefetchingFinished(
722 const GURL& main_frame_url, 670 const GURL& main_frame_url,
723 std::unique_ptr<ResourcePrefetcher::PrefetcherStats> stats) { 671 std::unique_ptr<ResourcePrefetcher::PrefetcherStats> stats) {
724 if (observer_) 672 if (observer_)
725 observer_->OnPrefetchingFinished(main_frame_url); 673 observer_->OnPrefetchingFinished(main_frame_url);
726 674
727 prefetcher_stats_.insert(std::make_pair(main_frame_url, std::move(stats))); 675 prefetcher_stats_.insert(std::make_pair(main_frame_url, std::move(stats)));
728 } 676 }
729 677
730 bool ResourcePrefetchPredictor::IsUrlPrefetchable(const GURL& main_frame_url) { 678 bool ResourcePrefetchPredictor::IsUrlPrefetchable(
679 const GURL& main_frame_url) const {
731 DCHECK_CURRENTLY_ON(BrowserThread::UI); 680 DCHECK_CURRENTLY_ON(BrowserThread::UI);
732 if (initialization_state_ != INITIALIZED) 681 if (initialization_state_ != INITIALIZED)
733 return false; 682 return false;
734 683
735 return GetPrefetchData(main_frame_url, nullptr); 684 return GetPrefetchData(main_frame_url, nullptr);
736 } 685 }
737 686
738 bool ResourcePrefetchPredictor::IsResourcePrefetchable( 687 bool ResourcePrefetchPredictor::IsResourcePrefetchable(
739 const ResourceData& resource) const { 688 const ResourceData& resource) const {
740 float confidence = static_cast<float>(resource.number_of_hits()) / 689 float confidence = static_cast<float>(resource.number_of_hits()) /
(...skipping 13 matching lines...) Expand all
754 prefetch_manager_ = NULL; 703 prefetch_manager_ = NULL;
755 } 704 }
756 history_service_observer_.RemoveAll(); 705 history_service_observer_.RemoveAll();
757 } 706 }
758 707
759 void ResourcePrefetchPredictor::OnMainFrameRequest( 708 void ResourcePrefetchPredictor::OnMainFrameRequest(
760 const URLRequestSummary& request) { 709 const URLRequestSummary& request) {
761 DCHECK_CURRENTLY_ON(BrowserThread::UI); 710 DCHECK_CURRENTLY_ON(BrowserThread::UI);
762 DCHECK_EQ(INITIALIZED, initialization_state_); 711 DCHECK_EQ(INITIALIZED, initialization_state_);
763 712
764 const GURL& main_frame_url = request.navigation_id.main_frame_url;
765 StartPrefetching(main_frame_url, HintOrigin::NAVIGATION);
766
767 CleanupAbandonedNavigations(request.navigation_id); 713 CleanupAbandonedNavigations(request.navigation_id);
768 714
769 // New empty navigation entry. 715 // New empty navigation entry.
770 inflight_navigations_.insert( 716 const GURL& main_frame_url = request.navigation_id.main_frame_url;
771 std::make_pair(request.navigation_id, 717 inflight_navigations_.emplace(
772 base::MakeUnique<PageRequestSummary>(main_frame_url))); 718 request.navigation_id,
773 } 719 base::MakeUnique<PageRequestSummary>(main_frame_url));
774
775 void ResourcePrefetchPredictor::OnMainFrameResponse(
776 const URLRequestSummary& response) {
777 DCHECK_CURRENTLY_ON(BrowserThread::UI);
778 DCHECK_EQ(INITIALIZED, initialization_state_);
779
780 NavigationMap::iterator nav_it =
781 inflight_navigations_.find(response.navigation_id);
782 if (nav_it != inflight_navigations_.end()) {
783 // To match an URL in StartPrefetching().
784 StopPrefetching(nav_it->second->initial_url);
785 } else {
786 StopPrefetching(response.navigation_id.main_frame_url);
787 }
788 } 720 }
789 721
790 void ResourcePrefetchPredictor::OnMainFrameRedirect( 722 void ResourcePrefetchPredictor::OnMainFrameRedirect(
791 const URLRequestSummary& response) { 723 const URLRequestSummary& response) {
792 DCHECK_CURRENTLY_ON(BrowserThread::UI); 724 DCHECK_CURRENTLY_ON(BrowserThread::UI);
793 DCHECK_EQ(INITIALIZED, initialization_state_); 725 DCHECK_EQ(INITIALIZED, initialization_state_);
794 726
795 const GURL& main_frame_url = response.navigation_id.main_frame_url; 727 const GURL& main_frame_url = response.navigation_id.main_frame_url;
796 std::unique_ptr<PageRequestSummary> summary; 728 std::unique_ptr<PageRequestSummary> summary;
797 NavigationMap::iterator nav_it = 729 NavigationMap::iterator nav_it =
(...skipping 10 matching lines...) Expand all
808 // If we lost the information about the first hop for some reason. 740 // If we lost the information about the first hop for some reason.
809 if (!summary) { 741 if (!summary) {
810 summary = base::MakeUnique<PageRequestSummary>(main_frame_url); 742 summary = base::MakeUnique<PageRequestSummary>(main_frame_url);
811 } 743 }
812 744
813 // A redirect will not lead to another OnMainFrameRequest call, so record the 745 // A redirect will not lead to another OnMainFrameRequest call, so record the
814 // redirect url as a new navigation id and save the initial url. 746 // redirect url as a new navigation id and save the initial url.
815 NavigationID navigation_id(response.navigation_id); 747 NavigationID navigation_id(response.navigation_id);
816 navigation_id.main_frame_url = response.redirect_url; 748 navigation_id.main_frame_url = response.redirect_url;
817 summary->main_frame_url = response.redirect_url; 749 summary->main_frame_url = response.redirect_url;
818 inflight_navigations_.insert( 750 inflight_navigations_.emplace(navigation_id, std::move(summary));
819 std::make_pair(navigation_id, std::move(summary)));
820 } 751 }
821 752
822 void ResourcePrefetchPredictor::OnSubresourceResponse( 753 void ResourcePrefetchPredictor::OnSubresourceResponse(
823 const URLRequestSummary& response) { 754 const URLRequestSummary& response) {
824 DCHECK_CURRENTLY_ON(BrowserThread::UI); 755 DCHECK_CURRENTLY_ON(BrowserThread::UI);
825 DCHECK_EQ(INITIALIZED, initialization_state_); 756 DCHECK_EQ(INITIALIZED, initialization_state_);
826 757
827 NavigationMap::const_iterator nav_it = 758 NavigationMap::const_iterator nav_it =
828 inflight_navigations_.find(response.navigation_id); 759 inflight_navigations_.find(response.navigation_id);
829 if (nav_it == inflight_navigations_.end()) 760 if (nav_it == inflight_navigations_.end())
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
1092 for (NavigationMap::iterator it = inflight_navigations_.begin(); 1023 for (NavigationMap::iterator it = inflight_navigations_.begin();
1093 it != inflight_navigations_.end();) { 1024 it != inflight_navigations_.end();) {
1094 if ((it->first.tab_id == navigation_id.tab_id) || 1025 if ((it->first.tab_id == navigation_id.tab_id) ||
1095 (time_now - it->first.creation_time > max_navigation_age)) { 1026 (time_now - it->first.creation_time > max_navigation_age)) {
1096 inflight_navigations_.erase(it++); 1027 inflight_navigations_.erase(it++);
1097 } else { 1028 } else {
1098 ++it; 1029 ++it;
1099 } 1030 }
1100 } 1031 }
1101 1032
1102 for (auto it = inflight_prefetches_.begin();
1103 it != inflight_prefetches_.end();) {
1104 base::TimeDelta prefetch_age = time_now - it->second;
1105 if (prefetch_age > max_navigation_age) {
1106 // It goes to the last bucket meaning that the duration was unlimited.
1107 UMA_HISTOGRAM_TIMES(
1108 internal::kResourcePrefetchPredictorPrefetchingDurationHistogram,
1109 prefetch_age);
1110 it = inflight_prefetches_.erase(it);
1111 } else {
1112 ++it;
1113 }
1114 }
1115
1116 // Remove old prefetches that haven't been claimed. 1033 // Remove old prefetches that haven't been claimed.
1117 for (auto stats_it = prefetcher_stats_.begin(); 1034 for (auto stats_it = prefetcher_stats_.begin();
1118 stats_it != prefetcher_stats_.end();) { 1035 stats_it != prefetcher_stats_.end();) {
1119 if (time_now - stats_it->second->start_time > max_navigation_age) { 1036 if (time_now - stats_it->second->start_time > max_navigation_age) {
1120 // No requests -> everything is a miss. 1037 // No requests -> everything is a miss.
1121 ReportPrefetchAccuracy(*stats_it->second, 1038 ReportPrefetchAccuracy(*stats_it->second,
1122 std::vector<URLRequestSummary>()); 1039 std::vector<URLRequestSummary>());
1123 stats_it = prefetcher_stats_.erase(stats_it); 1040 stats_it = prefetcher_stats_.erase(stats_it);
1124 } else { 1041 } else {
1125 ++stats_it; 1042 ++stats_it;
(...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after
1838 if (!history_service) 1755 if (!history_service)
1839 return; 1756 return;
1840 DCHECK(!history_service_observer_.IsObserving(history_service)); 1757 DCHECK(!history_service_observer_.IsObserving(history_service));
1841 history_service_observer_.Add(history_service); 1758 history_service_observer_.Add(history_service);
1842 if (history_service->BackendLoaded()) { 1759 if (history_service->BackendLoaded()) {
1843 // HistoryService is already loaded. Continue with Initialization. 1760 // HistoryService is already loaded. Continue with Initialization.
1844 OnHistoryAndCacheLoaded(); 1761 OnHistoryAndCacheLoaded();
1845 } 1762 }
1846 } 1763 }
1847 1764
1765 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url) {
1766 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StartPrefetching", "url",
1767 url.spec());
1768 if (!prefetch_manager_.get()) // Not enabled.
1769 return;
1770
1771 ResourcePrefetchPredictor::Prediction prediction;
1772 bool has_data = GetPrefetchData(url, &prediction);
1773 DCHECK(has_data);
1774
1775 BrowserThread::PostTask(
1776 BrowserThread::IO, FROM_HERE,
1777 base::BindOnce(&ResourcePrefetcherManager::MaybeAddPrefetch,
1778 prefetch_manager_, url, prediction.subresource_urls));
1779
1780 if (observer_)
1781 observer_->OnPrefetchingStarted(url);
1782 return;
1783 }
1784
1785 void ResourcePrefetchPredictor::StopPrefetching(const GURL& url) {
1786 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StopPrefetching", "url",
1787 url.spec());
1788 if (!prefetch_manager_.get()) // Not enabled.
1789 return;
1790
1791 BrowserThread::PostTask(
1792 BrowserThread::IO, FROM_HERE,
1793 base::BindOnce(&ResourcePrefetcherManager::MaybeRemovePrefetch,
1794 prefetch_manager_, url));
1795
1796 if (observer_)
1797 observer_->OnPrefetchingStopped(url);
1798 }
1799
1848 //////////////////////////////////////////////////////////////////////////////// 1800 ////////////////////////////////////////////////////////////////////////////////
1849 // TestObserver. 1801 // TestObserver.
1850 1802
1851 TestObserver::~TestObserver() { 1803 TestObserver::~TestObserver() {
1852 predictor_->SetObserverForTesting(nullptr); 1804 predictor_->SetObserverForTesting(nullptr);
1853 } 1805 }
1854 1806
1855 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) 1807 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor)
1856 : predictor_(predictor) { 1808 : predictor_(predictor) {
1857 predictor_->SetObserverForTesting(this); 1809 predictor_->SetObserverForTesting(this);
1858 } 1810 }
1859 1811
1860 } // namespace predictors 1812 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698