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

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

Issue 2887133003: predictors: Refactor resource_prefetch_predictor triggering. (Closed)
Patch Set: Rebase. 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 610 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 CHECK_EQ(request.resource_type, content::RESOURCE_TYPE_MAIN_FRAME); 621 CHECK_EQ(request.resource_type, content::RESOURCE_TYPE_MAIN_FRAME);
622 OnMainFrameRequest(request); 622 OnMainFrameRequest(request);
623 } 623 }
624 624
625 void ResourcePrefetchPredictor::RecordURLResponse( 625 void ResourcePrefetchPredictor::RecordURLResponse(
626 const URLRequestSummary& response) { 626 const URLRequestSummary& response) {
627 DCHECK_CURRENTLY_ON(BrowserThread::UI); 627 DCHECK_CURRENTLY_ON(BrowserThread::UI);
628 if (initialization_state_ != INITIALIZED) 628 if (initialization_state_ != INITIALIZED)
629 return; 629 return;
630 630
631 if (response.resource_type == content::RESOURCE_TYPE_MAIN_FRAME) 631 if (response.resource_type != content::RESOURCE_TYPE_MAIN_FRAME)
632 OnMainFrameResponse(response);
633 else
634 OnSubresourceResponse(response); 632 OnSubresourceResponse(response);
635 } 633 }
636 634
637 void ResourcePrefetchPredictor::RecordURLRedirect( 635 void ResourcePrefetchPredictor::RecordURLRedirect(
638 const URLRequestSummary& response) { 636 const URLRequestSummary& response) {
639 DCHECK_CURRENTLY_ON(BrowserThread::UI); 637 DCHECK_CURRENTLY_ON(BrowserThread::UI);
640 if (initialization_state_ != INITIALIZED) 638 if (initialization_state_ != INITIALIZED)
641 return; 639 return;
642 640
643 if (response.resource_type == content::RESOURCE_TYPE_MAIN_FRAME) 641 if (response.resource_type == content::RESOURCE_TYPE_MAIN_FRAME)
(...skipping 27 matching lines...) Expand all
671 const base::TimeTicks& first_contentful_paint) { 669 const base::TimeTicks& first_contentful_paint) {
672 DCHECK_CURRENTLY_ON(BrowserThread::UI); 670 DCHECK_CURRENTLY_ON(BrowserThread::UI);
673 if (initialization_state_ != INITIALIZED) 671 if (initialization_state_ != INITIALIZED)
674 return; 672 return;
675 673
676 NavigationMap::iterator nav_it = inflight_navigations_.find(navigation_id); 674 NavigationMap::iterator nav_it = inflight_navigations_.find(navigation_id);
677 if (nav_it != inflight_navigations_.end()) 675 if (nav_it != inflight_navigations_.end())
678 nav_it->second->first_contentful_paint = first_contentful_paint; 676 nav_it->second->first_contentful_paint = first_contentful_paint;
679 } 677 }
680 678
681 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url,
682 HintOrigin origin) {
683 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StartPrefetching", "url",
684 url.spec());
685 // Save prefetch start time to report prefetching duration.
686 if (inflight_prefetches_.find(url) == inflight_prefetches_.end() &&
687 IsUrlPrefetchable(url)) {
688 inflight_prefetches_.insert(std::make_pair(url, base::TimeTicks::Now()));
689 }
690
691 if (!prefetch_manager_.get()) // Prefetching not enabled.
692 return;
693 if (!config_.IsPrefetchingEnabledForOrigin(profile_, origin))
694 return;
695
696 ResourcePrefetchPredictor::Prediction prediction;
697 if (!GetPrefetchData(url, &prediction))
698 return;
699
700 BrowserThread::PostTask(
701 BrowserThread::IO, FROM_HERE,
702 base::BindOnce(&ResourcePrefetcherManager::MaybeAddPrefetch,
703 prefetch_manager_, url, prediction.subresource_urls));
704
705 if (observer_)
706 observer_->OnPrefetchingStarted(url);
707 }
708
709 void ResourcePrefetchPredictor::StopPrefetching(const GURL& url) {
710 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StopPrefetching", "url",
711 url.spec());
712 auto it = inflight_prefetches_.find(url);
713 if (it != inflight_prefetches_.end()) {
714 UMA_HISTOGRAM_TIMES(
715 internal::kResourcePrefetchPredictorPrefetchingDurationHistogram,
716 base::TimeTicks::Now() - it->second);
717 inflight_prefetches_.erase(it);
718 }
719 if (!prefetch_manager_.get()) // Not enabled.
720 return;
721
722 BrowserThread::PostTask(
723 BrowserThread::IO, FROM_HERE,
724 base::BindOnce(&ResourcePrefetcherManager::MaybeRemovePrefetch,
725 prefetch_manager_, url));
726
727 if (observer_)
728 observer_->OnPrefetchingStopped(url);
729 }
730
731 void ResourcePrefetchPredictor::OnPrefetchingFinished( 679 void ResourcePrefetchPredictor::OnPrefetchingFinished(
732 const GURL& main_frame_url, 680 const GURL& main_frame_url,
733 std::unique_ptr<ResourcePrefetcher::PrefetcherStats> stats) { 681 std::unique_ptr<ResourcePrefetcher::PrefetcherStats> stats) {
734 if (observer_) 682 if (observer_)
735 observer_->OnPrefetchingFinished(main_frame_url); 683 observer_->OnPrefetchingFinished(main_frame_url);
736 684
737 prefetcher_stats_.insert(std::make_pair(main_frame_url, std::move(stats))); 685 prefetcher_stats_.insert(std::make_pair(main_frame_url, std::move(stats)));
738 } 686 }
739 687
740 bool ResourcePrefetchPredictor::IsUrlPrefetchable(const GURL& main_frame_url) { 688 bool ResourcePrefetchPredictor::IsUrlPrefetchable(
689 const GURL& main_frame_url) const {
741 DCHECK_CURRENTLY_ON(BrowserThread::UI); 690 DCHECK_CURRENTLY_ON(BrowserThread::UI);
742 if (initialization_state_ != INITIALIZED) 691 if (initialization_state_ != INITIALIZED)
743 return false; 692 return false;
744 693
745 return GetPrefetchData(main_frame_url, nullptr); 694 return GetPrefetchData(main_frame_url, nullptr);
746 } 695 }
747 696
748 bool ResourcePrefetchPredictor::IsResourcePrefetchable( 697 bool ResourcePrefetchPredictor::IsResourcePrefetchable(
749 const ResourceData& resource) const { 698 const ResourceData& resource) const {
750 float confidence = static_cast<float>(resource.number_of_hits()) / 699 float confidence = static_cast<float>(resource.number_of_hits()) /
(...skipping 13 matching lines...) Expand all
764 prefetch_manager_ = NULL; 713 prefetch_manager_ = NULL;
765 } 714 }
766 history_service_observer_.RemoveAll(); 715 history_service_observer_.RemoveAll();
767 } 716 }
768 717
769 void ResourcePrefetchPredictor::OnMainFrameRequest( 718 void ResourcePrefetchPredictor::OnMainFrameRequest(
770 const URLRequestSummary& request) { 719 const URLRequestSummary& request) {
771 DCHECK_CURRENTLY_ON(BrowserThread::UI); 720 DCHECK_CURRENTLY_ON(BrowserThread::UI);
772 DCHECK_EQ(INITIALIZED, initialization_state_); 721 DCHECK_EQ(INITIALIZED, initialization_state_);
773 722
774 const GURL& main_frame_url = request.navigation_id.main_frame_url;
775 StartPrefetching(main_frame_url, HintOrigin::NAVIGATION);
776
777 CleanupAbandonedNavigations(request.navigation_id); 723 CleanupAbandonedNavigations(request.navigation_id);
778 724
779 // New empty navigation entry. 725 // New empty navigation entry.
780 inflight_navigations_.insert( 726 const GURL& main_frame_url = request.navigation_id.main_frame_url;
781 std::make_pair(request.navigation_id, 727 inflight_navigations_.emplace(
782 base::MakeUnique<PageRequestSummary>(main_frame_url))); 728 request.navigation_id,
783 } 729 base::MakeUnique<PageRequestSummary>(main_frame_url));
784
785 void ResourcePrefetchPredictor::OnMainFrameResponse(
786 const URLRequestSummary& response) {
787 DCHECK_CURRENTLY_ON(BrowserThread::UI);
788 DCHECK_EQ(INITIALIZED, initialization_state_);
789
790 NavigationMap::iterator nav_it =
791 inflight_navigations_.find(response.navigation_id);
792 if (nav_it != inflight_navigations_.end()) {
793 // To match an URL in StartPrefetching().
794 StopPrefetching(nav_it->second->initial_url);
795 } else {
796 StopPrefetching(response.navigation_id.main_frame_url);
797 }
798 } 730 }
799 731
800 void ResourcePrefetchPredictor::OnMainFrameRedirect( 732 void ResourcePrefetchPredictor::OnMainFrameRedirect(
801 const URLRequestSummary& response) { 733 const URLRequestSummary& response) {
802 DCHECK_CURRENTLY_ON(BrowserThread::UI); 734 DCHECK_CURRENTLY_ON(BrowserThread::UI);
803 DCHECK_EQ(INITIALIZED, initialization_state_); 735 DCHECK_EQ(INITIALIZED, initialization_state_);
804 736
805 const GURL& main_frame_url = response.navigation_id.main_frame_url; 737 const GURL& main_frame_url = response.navigation_id.main_frame_url;
806 std::unique_ptr<PageRequestSummary> summary; 738 std::unique_ptr<PageRequestSummary> summary;
807 NavigationMap::iterator nav_it = 739 NavigationMap::iterator nav_it =
(...skipping 10 matching lines...) Expand all
818 // If we lost the information about the first hop for some reason. 750 // If we lost the information about the first hop for some reason.
819 if (!summary) { 751 if (!summary) {
820 summary = base::MakeUnique<PageRequestSummary>(main_frame_url); 752 summary = base::MakeUnique<PageRequestSummary>(main_frame_url);
821 } 753 }
822 754
823 // A redirect will not lead to another OnMainFrameRequest call, so record the 755 // A redirect will not lead to another OnMainFrameRequest call, so record the
824 // redirect url as a new navigation id and save the initial url. 756 // redirect url as a new navigation id and save the initial url.
825 NavigationID navigation_id(response.navigation_id); 757 NavigationID navigation_id(response.navigation_id);
826 navigation_id.main_frame_url = response.redirect_url; 758 navigation_id.main_frame_url = response.redirect_url;
827 summary->main_frame_url = response.redirect_url; 759 summary->main_frame_url = response.redirect_url;
828 inflight_navigations_.insert( 760 inflight_navigations_.emplace(navigation_id, std::move(summary));
829 std::make_pair(navigation_id, std::move(summary)));
830 } 761 }
831 762
832 void ResourcePrefetchPredictor::OnSubresourceResponse( 763 void ResourcePrefetchPredictor::OnSubresourceResponse(
833 const URLRequestSummary& response) { 764 const URLRequestSummary& response) {
834 DCHECK_CURRENTLY_ON(BrowserThread::UI); 765 DCHECK_CURRENTLY_ON(BrowserThread::UI);
835 DCHECK_EQ(INITIALIZED, initialization_state_); 766 DCHECK_EQ(INITIALIZED, initialization_state_);
836 767
837 NavigationMap::const_iterator nav_it = 768 NavigationMap::const_iterator nav_it =
838 inflight_navigations_.find(response.navigation_id); 769 inflight_navigations_.find(response.navigation_id);
839 if (nav_it == inflight_navigations_.end()) 770 if (nav_it == inflight_navigations_.end())
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
1072 for (NavigationMap::iterator it = inflight_navigations_.begin(); 1003 for (NavigationMap::iterator it = inflight_navigations_.begin();
1073 it != inflight_navigations_.end();) { 1004 it != inflight_navigations_.end();) {
1074 if ((it->first.tab_id == navigation_id.tab_id) || 1005 if ((it->first.tab_id == navigation_id.tab_id) ||
1075 (time_now - it->first.creation_time > max_navigation_age)) { 1006 (time_now - it->first.creation_time > max_navigation_age)) {
1076 inflight_navigations_.erase(it++); 1007 inflight_navigations_.erase(it++);
1077 } else { 1008 } else {
1078 ++it; 1009 ++it;
1079 } 1010 }
1080 } 1011 }
1081 1012
1082 for (auto it = inflight_prefetches_.begin();
1083 it != inflight_prefetches_.end();) {
1084 base::TimeDelta prefetch_age = time_now - it->second;
1085 if (prefetch_age > max_navigation_age) {
1086 // It goes to the last bucket meaning that the duration was unlimited.
1087 UMA_HISTOGRAM_TIMES(
1088 internal::kResourcePrefetchPredictorPrefetchingDurationHistogram,
1089 prefetch_age);
1090 it = inflight_prefetches_.erase(it);
1091 } else {
1092 ++it;
1093 }
1094 }
1095
1096 // Remove old prefetches that haven't been claimed. 1013 // Remove old prefetches that haven't been claimed.
1097 for (auto stats_it = prefetcher_stats_.begin(); 1014 for (auto stats_it = prefetcher_stats_.begin();
1098 stats_it != prefetcher_stats_.end();) { 1015 stats_it != prefetcher_stats_.end();) {
1099 if (time_now - stats_it->second->start_time > max_navigation_age) { 1016 if (time_now - stats_it->second->start_time > max_navigation_age) {
1100 // No requests -> everything is a miss. 1017 // No requests -> everything is a miss.
1101 ReportPrefetchAccuracy(*stats_it->second, 1018 ReportPrefetchAccuracy(*stats_it->second,
1102 std::vector<URLRequestSummary>()); 1019 std::vector<URLRequestSummary>());
1103 stats_it = prefetcher_stats_.erase(stats_it); 1020 stats_it = prefetcher_stats_.erase(stats_it);
1104 } else { 1021 } else {
1105 ++stats_it; 1022 ++stats_it;
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
1592 if (!history_service) 1509 if (!history_service)
1593 return; 1510 return;
1594 DCHECK(!history_service_observer_.IsObserving(history_service)); 1511 DCHECK(!history_service_observer_.IsObserving(history_service));
1595 history_service_observer_.Add(history_service); 1512 history_service_observer_.Add(history_service);
1596 if (history_service->BackendLoaded()) { 1513 if (history_service->BackendLoaded()) {
1597 // HistoryService is already loaded. Continue with Initialization. 1514 // HistoryService is already loaded. Continue with Initialization.
1598 OnHistoryAndCacheLoaded(); 1515 OnHistoryAndCacheLoaded();
1599 } 1516 }
1600 } 1517 }
1601 1518
1519 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url) {
1520 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StartPrefetching", "url",
1521 url.spec());
1522 if (!prefetch_manager_.get()) // Not enabled.
1523 return;
1524
1525 ResourcePrefetchPredictor::Prediction prediction;
1526 bool has_data = GetPrefetchData(url, &prediction);
1527 DCHECK(has_data);
1528
1529 BrowserThread::PostTask(
1530 BrowserThread::IO, FROM_HERE,
1531 base::BindOnce(&ResourcePrefetcherManager::MaybeAddPrefetch,
1532 prefetch_manager_, url, prediction.subresource_urls));
1533
1534 if (observer_)
1535 observer_->OnPrefetchingStarted(url);
1536 return;
alexilin 2017/05/31 16:02:03 nit: Delete this line.
Benoit L 2017/06/01 08:32:50 Done.
1537 }
1538
1539 void ResourcePrefetchPredictor::StopPrefetching(const GURL& url) {
1540 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StopPrefetching", "url",
1541 url.spec());
1542 if (!prefetch_manager_.get()) // Not enabled.
1543 return;
1544
1545 BrowserThread::PostTask(
1546 BrowserThread::IO, FROM_HERE,
1547 base::BindOnce(&ResourcePrefetcherManager::MaybeRemovePrefetch,
1548 prefetch_manager_, url));
1549
1550 if (observer_)
1551 observer_->OnPrefetchingStopped(url);
1552 }
1553
1602 //////////////////////////////////////////////////////////////////////////////// 1554 ////////////////////////////////////////////////////////////////////////////////
1603 // TestObserver. 1555 // TestObserver.
1604 1556
1605 TestObserver::~TestObserver() { 1557 TestObserver::~TestObserver() {
1606 predictor_->SetObserverForTesting(nullptr); 1558 predictor_->SetObserverForTesting(nullptr);
1607 } 1559 }
1608 1560
1609 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) 1561 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor)
1610 : predictor_(predictor) { 1562 : predictor_(predictor) {
1611 predictor_->SetObserverForTesting(this); 1563 predictor_->SetObserverForTesting(this);
1612 } 1564 }
1613 1565
1614 } // namespace predictors 1566 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698