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

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

Issue 2825693002: predictors: Prefetch resources from manifest. (Closed)
Patch Set: Address comments. Created 3 years, 8 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 void InitializeOriginStatFromOriginRequestSummary( 93 void InitializeOriginStatFromOriginRequestSummary(
94 OriginStat* origin, 94 OriginStat* origin,
95 const ResourcePrefetchPredictor::OriginRequestSummary& summary) { 95 const ResourcePrefetchPredictor::OriginRequestSummary& summary) {
96 origin->set_origin(summary.origin.spec()); 96 origin->set_origin(summary.origin.spec());
97 origin->set_number_of_hits(1); 97 origin->set_number_of_hits(1);
98 origin->set_average_position(summary.first_occurrence + 1); 98 origin->set_average_position(summary.first_occurrence + 1);
99 origin->set_always_access_network(summary.always_access_network); 99 origin->set_always_access_network(summary.always_access_network);
100 origin->set_accessed_network(summary.accessed_network); 100 origin->set_accessed_network(summary.accessed_network);
101 } 101 }
102 102
103 bool IsManifestTooOld(const precache::PrecacheManifest& manifest) {
104 const base::TimeDelta kMaxManifestAge = base::TimeDelta::FromDays(5);
105 return base::Time::Now() - base::Time::FromDoubleT(manifest.id().id()) >
106 kMaxManifestAge;
107 }
108
103 // Used to fetch the visit count for a URL from the History database. 109 // Used to fetch the visit count for a URL from the History database.
104 class GetUrlVisitCountTask : public history::HistoryDBTask { 110 class GetUrlVisitCountTask : public history::HistoryDBTask {
105 public: 111 public:
106 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary; 112 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary;
107 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; 113 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary;
108 typedef base::Callback<void(size_t, // URL visit count. 114 typedef base::Callback<void(size_t, // URL visit count.
109 const PageRequestSummary&)> 115 const PageRequestSummary&)>
110 VisitInfoCallback; 116 VisitInfoCallback;
111 117
112 GetUrlVisitCountTask(std::unique_ptr<PageRequestSummary> summary, 118 GetUrlVisitCountTask(std::unique_ptr<PageRequestSummary> summary,
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 prediction->is_host = false; 897 prediction->is_host = false;
892 prediction->main_frame_key = redirect_endpoint; 898 prediction->main_frame_key = redirect_endpoint;
893 prediction->is_redirected = (redirect_endpoint != main_frame_url_spec); 899 prediction->is_redirected = (redirect_endpoint != main_frame_url_spec);
894 } 900 }
895 return true; 901 return true;
896 } 902 }
897 903
898 // Use host data if the URL-based prediction isn't available. 904 // Use host data if the URL-based prediction isn't available.
899 std::string main_frame_url_host = main_frame_url.host(); 905 std::string main_frame_url_host = main_frame_url.host();
900 if (GetRedirectEndpoint(main_frame_url_host, *host_redirect_table_cache_, 906 if (GetRedirectEndpoint(main_frame_url_host, *host_redirect_table_cache_,
901 &redirect_endpoint) && 907 &redirect_endpoint)) {
902 PopulatePrefetcherRequest(redirect_endpoint, *host_table_cache_, urls)) { 908 if (PopulatePrefetcherRequest(redirect_endpoint, *host_table_cache_,
903 if (prediction) { 909 urls)) {
904 prediction->is_host = true; 910 if (prediction) {
905 prediction->main_frame_key = redirect_endpoint; 911 prediction->is_host = true;
906 prediction->is_redirected = (redirect_endpoint != main_frame_url_host); 912 prediction->main_frame_key = redirect_endpoint;
913 prediction->is_redirected = (redirect_endpoint != main_frame_url_host);
914 }
915 return true;
907 } 916 }
908 return true; 917
918 if (config_.is_manifests_enabled) {
919 // Use manifest data for host if available.
920 std::string manifest_host = redirect_endpoint;
921 if (base::StartsWith(manifest_host, "www.", base::CompareCase::SENSITIVE))
922 manifest_host.assign(manifest_host, 4, std::string::npos);
923 if (PopulateFromManifest(manifest_host, urls)) {
924 if (prediction) {
925 prediction->is_host = true;
926 prediction->main_frame_key = redirect_endpoint;
927 prediction->is_redirected =
928 (redirect_endpoint != main_frame_url_host);
929 }
930 return true;
931 }
932 }
909 } 933 }
910
911 return false; 934 return false;
912 } 935 }
913 936
914 bool ResourcePrefetchPredictor::PopulatePrefetcherRequest( 937 bool ResourcePrefetchPredictor::PopulatePrefetcherRequest(
915 const std::string& main_frame_key, 938 const std::string& main_frame_key,
916 const PrefetchDataMap& data_map, 939 const PrefetchDataMap& data_map,
917 std::vector<GURL>* urls) const { 940 std::vector<GURL>* urls) const {
918 PrefetchDataMap::const_iterator it = data_map.find(main_frame_key); 941 PrefetchDataMap::const_iterator it = data_map.find(main_frame_key);
919 if (it == data_map.end()) 942 if (it == data_map.end())
920 return false; 943 return false;
921 944
922 bool has_prefetchable_resource = false; 945 bool has_prefetchable_resource = false;
923 for (const ResourceData& resource : it->second.resources()) { 946 for (const ResourceData& resource : it->second.resources()) {
924 if (IsResourcePrefetchable(resource)) { 947 if (IsResourcePrefetchable(resource)) {
925 has_prefetchable_resource = true; 948 has_prefetchable_resource = true;
926 if (urls) 949 if (urls)
927 urls->push_back(GURL(resource.resource_url())); 950 urls->push_back(GURL(resource.resource_url()));
928 } 951 }
929 } 952 }
930 953
931 return has_prefetchable_resource; 954 return has_prefetchable_resource;
932 } 955 }
933 956
957 bool ResourcePrefetchPredictor::PopulateFromManifest(
958 const std::string& manifest_host,
959 std::vector<GURL>* urls) const {
960 auto it = manifest_table_cache_->find(manifest_host);
961 if (it == manifest_table_cache_->end())
962 return false;
963
964 const precache::PrecacheManifest& manifest = it->second;
965
966 if (IsManifestTooOld(manifest))
967 return false;
968
969 const float kMinWeight = 0.7f;
970
971 // Don't prefetch resource if it has false bit in any of the following
972 // bitsets. All bits assumed to be true if an optional has no value.
973 base::Optional<std::vector<bool>> not_unused =
974 precache::GetResourceBitset(manifest, internal::kUnusedRemovedExperiment);
975 base::Optional<std::vector<bool>> not_versioned = precache::GetResourceBitset(
976 manifest, internal::kVersionedRemovedExperiment);
977 base::Optional<std::vector<bool>> not_no_store = precache::GetResourceBitset(
978 manifest, internal::kNoStoreRemovedExperiment);
979
980 bool has_prefetchable_resource = false;
981 for (int i = 0; i < manifest.resource_size(); ++i) {
982 const precache::PrecacheResource& resource = manifest.resource(i);
983 if (resource.weight_ratio() > kMinWeight &&
984 (!not_unused.has_value() || not_unused.value()[i]) &&
985 (!not_versioned.has_value() || not_versioned.value()[i]) &&
986 (!not_no_store.has_value() || not_no_store.value()[i])) {
987 has_prefetchable_resource = true;
988 if (urls)
989 urls->emplace_back(resource.url());
990 }
991 }
992
993 return has_prefetchable_resource;
994 }
995
934 void ResourcePrefetchPredictor::CreateCaches( 996 void ResourcePrefetchPredictor::CreateCaches(
935 std::unique_ptr<PrefetchDataMap> url_data_map, 997 std::unique_ptr<PrefetchDataMap> url_data_map,
936 std::unique_ptr<PrefetchDataMap> host_data_map, 998 std::unique_ptr<PrefetchDataMap> host_data_map,
937 std::unique_ptr<RedirectDataMap> url_redirect_data_map, 999 std::unique_ptr<RedirectDataMap> url_redirect_data_map,
938 std::unique_ptr<RedirectDataMap> host_redirect_data_map, 1000 std::unique_ptr<RedirectDataMap> host_redirect_data_map,
939 std::unique_ptr<ManifestDataMap> manifest_data_map, 1001 std::unique_ptr<ManifestDataMap> manifest_data_map,
940 std::unique_ptr<OriginDataMap> origin_data_map) { 1002 std::unique_ptr<OriginDataMap> origin_data_map) {
941 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1003 DCHECK_CURRENTLY_ON(BrowserThread::UI);
942 1004
943 DCHECK_EQ(INITIALIZING, initialization_state_); 1005 DCHECK_EQ(INITIALIZING, initialization_state_);
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after
1630 } 1692 }
1631 } 1693 }
1632 1694
1633 void ResourcePrefetchPredictor::OnManifestFetched( 1695 void ResourcePrefetchPredictor::OnManifestFetched(
1634 const std::string& host, 1696 const std::string& host,
1635 const precache::PrecacheManifest& manifest) { 1697 const precache::PrecacheManifest& manifest) {
1636 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1698 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1637 if (initialization_state_ != INITIALIZED) 1699 if (initialization_state_ != INITIALIZED)
1638 return; 1700 return;
1639 1701
1640 if (!config_.is_manifests_enabled) 1702 if (!config_.is_manifests_enabled || IsManifestTooOld(manifest))
1641 return; 1703 return;
1642 1704
1643 // The manifest host has "www." prefix stripped, the manifest host could 1705 // The manifest host has "www." prefix stripped, the manifest host could
1644 // correspond to two different hosts in the prefetch database. 1706 // correspond to two different hosts in the prefetch database.
1645 UpdatePrefetchDataByManifest(host, PREFETCH_KEY_TYPE_HOST, 1707 UpdatePrefetchDataByManifest(host, PREFETCH_KEY_TYPE_HOST,
1646 host_table_cache_.get(), manifest); 1708 host_table_cache_.get(), manifest);
1647 UpdatePrefetchDataByManifest("www." + host, PREFETCH_KEY_TYPE_HOST, 1709 UpdatePrefetchDataByManifest("www." + host, PREFETCH_KEY_TYPE_HOST,
1648 host_table_cache_.get(), manifest); 1710 host_table_cache_.get(), manifest);
1649 1711
1650 // The manifest is too large to store. 1712 // The manifest is too large to store.
(...skipping 30 matching lines...) Expand all
1681 1743
1682 auto resource_entry = data_map->find(key); 1744 auto resource_entry = data_map->find(key);
1683 if (resource_entry == data_map->end()) 1745 if (resource_entry == data_map->end())
1684 return; 1746 return;
1685 1747
1686 PrefetchData& data = resource_entry->second; 1748 PrefetchData& data = resource_entry->second;
1687 std::map<std::string, int> manifest_index; 1749 std::map<std::string, int> manifest_index;
1688 for (int i = 0; i < manifest.resource_size(); ++i) 1750 for (int i = 0; i < manifest.resource_size(); ++i)
1689 manifest_index.insert({manifest.resource(i).url(), i}); 1751 manifest_index.insert({manifest.resource(i).url(), i});
1690 1752
1753 base::Optional<std::vector<bool>> not_unused =
1754 precache::GetResourceBitset(manifest, internal::kUnusedRemovedExperiment);
1755
1691 bool was_updated = false; 1756 bool was_updated = false;
1692 base::Optional<std::vector<bool>> unused_bitset = 1757 if (not_unused.has_value()) {
1693 precache::GetResourceBitset(manifest, internal::kUnusedRemovedExperiment);
1694 if (unused_bitset.has_value()) {
1695 // Remove unused resources from |data|. 1758 // Remove unused resources from |data|.
1696 auto new_end = std::remove_if( 1759 auto new_end = std::remove_if(
1697 data.mutable_resources()->begin(), data.mutable_resources()->end(), 1760 data.mutable_resources()->begin(), data.mutable_resources()->end(),
1698 [&](const ResourceData& x) { 1761 [&](const ResourceData& x) {
1699 auto it = manifest_index.find(x.resource_url()); 1762 auto it = manifest_index.find(x.resource_url());
1700 if (it == manifest_index.end()) 1763 if (it == manifest_index.end())
1701 return false; 1764 return false;
1702 return !unused_bitset.value()[it->second]; 1765 return !not_unused.value()[it->second];
1703 }); 1766 });
1704 was_updated = new_end != data.mutable_resources()->end(); 1767 was_updated = new_end != data.mutable_resources()->end();
1705 data.mutable_resources()->erase(new_end, data.mutable_resources()->end()); 1768 data.mutable_resources()->erase(new_end, data.mutable_resources()->end());
1706 } 1769 }
1707 1770
1708 if (was_updated) { 1771 if (was_updated) {
1709 BrowserThread::PostTask( 1772 BrowserThread::PostTask(
1710 BrowserThread::DB, FROM_HERE, 1773 BrowserThread::DB, FROM_HERE,
1711 base::Bind(&ResourcePrefetchPredictorTables::UpdateResourceData, 1774 base::Bind(&ResourcePrefetchPredictorTables::UpdateResourceData,
1712 tables_, data, key_type)); 1775 tables_, data, key_type));
(...skipping 21 matching lines...) Expand all
1734 TestObserver::~TestObserver() { 1797 TestObserver::~TestObserver() {
1735 predictor_->SetObserverForTesting(nullptr); 1798 predictor_->SetObserverForTesting(nullptr);
1736 } 1799 }
1737 1800
1738 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) 1801 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor)
1739 : predictor_(predictor) { 1802 : predictor_(predictor) {
1740 predictor_->SetObserverForTesting(this); 1803 predictor_->SetObserverForTesting(this);
1741 } 1804 }
1742 1805
1743 } // namespace predictors 1806 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698