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

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

Issue 2825693002: predictors: Prefetch resources from manifest. (Closed)
Patch Set: Add comment. 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 // This is roughly in line with the threshold we use for resource confidence.
970 const float kMinWeight = 0.7f;
971
972 // Don't prefetch resource if it has false bit in any of the following
973 // bitsets. All bits assumed to be true if an optional has no value.
974 base::Optional<std::vector<bool>> not_unused =
975 precache::GetResourceBitset(manifest, internal::kUnusedRemovedExperiment);
976 base::Optional<std::vector<bool>> not_versioned = precache::GetResourceBitset(
977 manifest, internal::kVersionedRemovedExperiment);
978 base::Optional<std::vector<bool>> not_no_store = precache::GetResourceBitset(
979 manifest, internal::kNoStoreRemovedExperiment);
980
981 bool has_prefetchable_resource = false;
982 for (int i = 0; i < manifest.resource_size(); ++i) {
983 const precache::PrecacheResource& resource = manifest.resource(i);
984 if (resource.weight_ratio() > kMinWeight &&
985 (!not_unused.has_value() || not_unused.value()[i]) &&
986 (!not_versioned.has_value() || not_versioned.value()[i]) &&
987 (!not_no_store.has_value() || not_no_store.value()[i])) {
988 has_prefetchable_resource = true;
989 if (urls)
990 urls->emplace_back(resource.url());
991 }
992 }
993
994 return has_prefetchable_resource;
995 }
996
934 void ResourcePrefetchPredictor::CreateCaches( 997 void ResourcePrefetchPredictor::CreateCaches(
935 std::unique_ptr<PrefetchDataMap> url_data_map, 998 std::unique_ptr<PrefetchDataMap> url_data_map,
936 std::unique_ptr<PrefetchDataMap> host_data_map, 999 std::unique_ptr<PrefetchDataMap> host_data_map,
937 std::unique_ptr<RedirectDataMap> url_redirect_data_map, 1000 std::unique_ptr<RedirectDataMap> url_redirect_data_map,
938 std::unique_ptr<RedirectDataMap> host_redirect_data_map, 1001 std::unique_ptr<RedirectDataMap> host_redirect_data_map,
939 std::unique_ptr<ManifestDataMap> manifest_data_map, 1002 std::unique_ptr<ManifestDataMap> manifest_data_map,
940 std::unique_ptr<OriginDataMap> origin_data_map) { 1003 std::unique_ptr<OriginDataMap> origin_data_map) {
941 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1004 DCHECK_CURRENTLY_ON(BrowserThread::UI);
942 1005
943 DCHECK_EQ(INITIALIZING, initialization_state_); 1006 DCHECK_EQ(INITIALIZING, initialization_state_);
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after
1630 } 1693 }
1631 } 1694 }
1632 1695
1633 void ResourcePrefetchPredictor::OnManifestFetched( 1696 void ResourcePrefetchPredictor::OnManifestFetched(
1634 const std::string& host, 1697 const std::string& host,
1635 const precache::PrecacheManifest& manifest) { 1698 const precache::PrecacheManifest& manifest) {
1636 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1699 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1637 if (initialization_state_ != INITIALIZED) 1700 if (initialization_state_ != INITIALIZED)
1638 return; 1701 return;
1639 1702
1640 if (!config_.is_manifests_enabled) 1703 if (!config_.is_manifests_enabled || IsManifestTooOld(manifest))
1641 return; 1704 return;
1642 1705
1643 // The manifest host has "www." prefix stripped, the manifest host could 1706 // The manifest host has "www." prefix stripped, the manifest host could
1644 // correspond to two different hosts in the prefetch database. 1707 // correspond to two different hosts in the prefetch database.
1645 UpdatePrefetchDataByManifest(host, PREFETCH_KEY_TYPE_HOST, 1708 UpdatePrefetchDataByManifest(host, PREFETCH_KEY_TYPE_HOST,
1646 host_table_cache_.get(), manifest); 1709 host_table_cache_.get(), manifest);
1647 UpdatePrefetchDataByManifest("www." + host, PREFETCH_KEY_TYPE_HOST, 1710 UpdatePrefetchDataByManifest("www." + host, PREFETCH_KEY_TYPE_HOST,
1648 host_table_cache_.get(), manifest); 1711 host_table_cache_.get(), manifest);
1649 1712
1650 // The manifest is too large to store. 1713 // The manifest is too large to store.
(...skipping 30 matching lines...) Expand all
1681 1744
1682 auto resource_entry = data_map->find(key); 1745 auto resource_entry = data_map->find(key);
1683 if (resource_entry == data_map->end()) 1746 if (resource_entry == data_map->end())
1684 return; 1747 return;
1685 1748
1686 PrefetchData& data = resource_entry->second; 1749 PrefetchData& data = resource_entry->second;
1687 std::map<std::string, int> manifest_index; 1750 std::map<std::string, int> manifest_index;
1688 for (int i = 0; i < manifest.resource_size(); ++i) 1751 for (int i = 0; i < manifest.resource_size(); ++i)
1689 manifest_index.insert({manifest.resource(i).url(), i}); 1752 manifest_index.insert({manifest.resource(i).url(), i});
1690 1753
1754 base::Optional<std::vector<bool>> not_unused =
1755 precache::GetResourceBitset(manifest, internal::kUnusedRemovedExperiment);
1756
1691 bool was_updated = false; 1757 bool was_updated = false;
1692 base::Optional<std::vector<bool>> unused_bitset = 1758 if (not_unused.has_value()) {
1693 precache::GetResourceBitset(manifest, internal::kUnusedRemovedExperiment);
1694 if (unused_bitset.has_value()) {
1695 // Remove unused resources from |data|. 1759 // Remove unused resources from |data|.
1696 auto new_end = std::remove_if( 1760 auto new_end = std::remove_if(
1697 data.mutable_resources()->begin(), data.mutable_resources()->end(), 1761 data.mutable_resources()->begin(), data.mutable_resources()->end(),
1698 [&](const ResourceData& x) { 1762 [&](const ResourceData& x) {
1699 auto it = manifest_index.find(x.resource_url()); 1763 auto it = manifest_index.find(x.resource_url());
1700 if (it == manifest_index.end()) 1764 if (it == manifest_index.end())
1701 return false; 1765 return false;
1702 return !unused_bitset.value()[it->second]; 1766 return !not_unused.value()[it->second];
1703 }); 1767 });
1704 was_updated = new_end != data.mutable_resources()->end(); 1768 was_updated = new_end != data.mutable_resources()->end();
1705 data.mutable_resources()->erase(new_end, data.mutable_resources()->end()); 1769 data.mutable_resources()->erase(new_end, data.mutable_resources()->end());
1706 } 1770 }
1707 1771
1708 if (was_updated) { 1772 if (was_updated) {
1709 BrowserThread::PostTask( 1773 BrowserThread::PostTask(
1710 BrowserThread::DB, FROM_HERE, 1774 BrowserThread::DB, FROM_HERE,
1711 base::Bind(&ResourcePrefetchPredictorTables::UpdateResourceData, 1775 base::Bind(&ResourcePrefetchPredictorTables::UpdateResourceData,
1712 tables_, data, key_type)); 1776 tables_, data, key_type));
(...skipping 21 matching lines...) Expand all
1734 TestObserver::~TestObserver() { 1798 TestObserver::~TestObserver() {
1735 predictor_->SetObserverForTesting(nullptr); 1799 predictor_->SetObserverForTesting(nullptr);
1736 } 1800 }
1737 1801
1738 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) 1802 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor)
1739 : predictor_(predictor) { 1803 : predictor_(predictor) {
1740 predictor_->SetObserverForTesting(this); 1804 predictor_->SetObserverForTesting(this);
1741 } 1805 }
1742 1806
1743 } // namespace predictors 1807 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698