Index: chrome/browser/predictors/resource_prefetch_predictor.cc |
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.cc b/chrome/browser/predictors/resource_prefetch_predictor.cc |
index 65f3f90a68533dc541111e060820f3b160dcd2b4..ae43153e0766b36ef49860b8a4b58aa80dff5f8f 100644 |
--- a/chrome/browser/predictors/resource_prefetch_predictor.cc |
+++ b/chrome/browser/predictors/resource_prefetch_predictor.cc |
@@ -100,6 +100,12 @@ void InitializeOriginStatFromOriginRequestSummary( |
origin->set_accessed_network(summary.accessed_network); |
} |
+bool IsManifestTooOld(const precache::PrecacheManifest& manifest) { |
+ const base::TimeDelta kMaxManifestAge = base::TimeDelta::FromDays(5); |
+ return base::Time::Now() - base::Time::FromDoubleT(manifest.id().id()) > |
+ kMaxManifestAge; |
+} |
+ |
// Used to fetch the visit count for a URL from the History database. |
class GetUrlVisitCountTask : public history::HistoryDBTask { |
public: |
@@ -898,16 +904,33 @@ bool ResourcePrefetchPredictor::GetPrefetchData( |
// Use host data if the URL-based prediction isn't available. |
std::string main_frame_url_host = main_frame_url.host(); |
if (GetRedirectEndpoint(main_frame_url_host, *host_redirect_table_cache_, |
- &redirect_endpoint) && |
- PopulatePrefetcherRequest(redirect_endpoint, *host_table_cache_, urls)) { |
- if (prediction) { |
- prediction->is_host = true; |
- prediction->main_frame_key = redirect_endpoint; |
- prediction->is_redirected = (redirect_endpoint != main_frame_url_host); |
+ &redirect_endpoint)) { |
+ if (PopulatePrefetcherRequest(redirect_endpoint, *host_table_cache_, |
+ urls)) { |
+ if (prediction) { |
+ prediction->is_host = true; |
+ prediction->main_frame_key = redirect_endpoint; |
+ prediction->is_redirected = (redirect_endpoint != main_frame_url_host); |
+ } |
+ return true; |
} |
- return true; |
- } |
+ if (config_.is_manifests_enabled) { |
+ // Use manifest data for host if available. |
+ std::string manifest_host = redirect_endpoint; |
+ if (base::StartsWith(manifest_host, "www.", base::CompareCase::SENSITIVE)) |
+ manifest_host.assign(manifest_host, 4, std::string::npos); |
+ if (PopulateFromManifest(manifest_host, urls)) { |
+ if (prediction) { |
+ prediction->is_host = true; |
+ prediction->main_frame_key = redirect_endpoint; |
+ prediction->is_redirected = |
+ (redirect_endpoint != main_frame_url_host); |
+ } |
+ return true; |
+ } |
+ } |
+ } |
return false; |
} |
@@ -931,6 +954,46 @@ bool ResourcePrefetchPredictor::PopulatePrefetcherRequest( |
return has_prefetchable_resource; |
} |
+bool ResourcePrefetchPredictor::PopulateFromManifest( |
+ const std::string& manifest_host, |
+ std::vector<GURL>* urls) const { |
+ auto it = manifest_table_cache_->find(manifest_host); |
+ if (it == manifest_table_cache_->end()) |
+ return false; |
+ |
+ const precache::PrecacheManifest& manifest = it->second; |
+ |
+ if (IsManifestTooOld(manifest)) |
+ return false; |
+ |
+ // This is roughly in line with the threshold we use for resource confidence. |
+ const float kMinWeight = 0.7f; |
+ |
+ // Don't prefetch resource if it has false bit in any of the following |
+ // bitsets. All bits assumed to be true if an optional has no value. |
+ base::Optional<std::vector<bool>> not_unused = |
+ precache::GetResourceBitset(manifest, internal::kUnusedRemovedExperiment); |
+ base::Optional<std::vector<bool>> not_versioned = precache::GetResourceBitset( |
+ manifest, internal::kVersionedRemovedExperiment); |
+ base::Optional<std::vector<bool>> not_no_store = precache::GetResourceBitset( |
+ manifest, internal::kNoStoreRemovedExperiment); |
+ |
+ bool has_prefetchable_resource = false; |
+ for (int i = 0; i < manifest.resource_size(); ++i) { |
+ const precache::PrecacheResource& resource = manifest.resource(i); |
+ if (resource.weight_ratio() > kMinWeight && |
+ (!not_unused.has_value() || not_unused.value()[i]) && |
+ (!not_versioned.has_value() || not_versioned.value()[i]) && |
+ (!not_no_store.has_value() || not_no_store.value()[i])) { |
+ has_prefetchable_resource = true; |
+ if (urls) |
+ urls->emplace_back(resource.url()); |
+ } |
+ } |
+ |
+ return has_prefetchable_resource; |
+} |
+ |
void ResourcePrefetchPredictor::CreateCaches( |
std::unique_ptr<PrefetchDataMap> url_data_map, |
std::unique_ptr<PrefetchDataMap> host_data_map, |
@@ -1637,7 +1700,7 @@ void ResourcePrefetchPredictor::OnManifestFetched( |
if (initialization_state_ != INITIALIZED) |
return; |
- if (!config_.is_manifests_enabled) |
+ if (!config_.is_manifests_enabled || IsManifestTooOld(manifest)) |
return; |
// The manifest host has "www." prefix stripped, the manifest host could |
@@ -1688,10 +1751,11 @@ void ResourcePrefetchPredictor::UpdatePrefetchDataByManifest( |
for (int i = 0; i < manifest.resource_size(); ++i) |
manifest_index.insert({manifest.resource(i).url(), i}); |
- bool was_updated = false; |
- base::Optional<std::vector<bool>> unused_bitset = |
+ base::Optional<std::vector<bool>> not_unused = |
precache::GetResourceBitset(manifest, internal::kUnusedRemovedExperiment); |
- if (unused_bitset.has_value()) { |
+ |
+ bool was_updated = false; |
+ if (not_unused.has_value()) { |
// Remove unused resources from |data|. |
auto new_end = std::remove_if( |
data.mutable_resources()->begin(), data.mutable_resources()->end(), |
@@ -1699,7 +1763,7 @@ void ResourcePrefetchPredictor::UpdatePrefetchDataByManifest( |
auto it = manifest_index.find(x.resource_url()); |
if (it == manifest_index.end()) |
return false; |
- return !unused_bitset.value()[it->second]; |
+ return !not_unused.value()[it->second]; |
}); |
was_updated = new_end != data.mutable_resources()->end(); |
data.mutable_resources()->erase(new_end, data.mutable_resources()->end()); |