Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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); | |
|
alexilin
2017/04/18 07:05:03
I don't feel strongly about this.
Probably, it wo
| |
| 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 Loading... | |
| 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)) | |
|
Benoit L
2017/04/18 16:28:39
is www systematically stripped from the manifest k
alexilin
2017/04/19 07:59:25
Yes. (See history::HostForTopHosts and how it's us
| |
| 922 manifest_host.assign(manifest_host, 4, std::string::npos); | |
| 923 if (PopulatePrefetcherRequestByManifest(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::PopulatePrefetcherRequestByManifest( | |
| 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 kMinPrecacheResourceWeightToTriggerPrefetch = 0.7f; | |
|
Benoit L
2017/04/18 16:28:39
Have you looked at the practical meaning of this t
alexilin
2017/04/19 07:59:25
Roughly speaking, it's percentage of host pages wh
Benoit L
2017/04/19 14:48:54
Ok, so can you add a comment saying that this is r
alexilin
2017/04/19 15:35:11
Done.
| |
| 970 | |
| 971 base::Optional<std::vector<bool>> unused_bitset = | |
| 972 precache::GetResourceBitset(manifest, internal::kUnusedRemovedExperiment); | |
| 973 base::Optional<std::vector<bool>> versioned_bitset = | |
| 974 precache::GetResourceBitset(manifest, | |
| 975 internal::kVersionedRemovedExperiment); | |
| 976 base::Optional<std::vector<bool>> no_store_bitset = | |
| 977 precache::GetResourceBitset(manifest, | |
| 978 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() > kMinPrecacheResourceWeightToTriggerPrefetch && | |
| 984 (!unused_bitset.has_value() || unused_bitset.value()[i]) && | |
|
Benoit L
2017/04/18 16:28:39
what is the meaning of the bits?
if unused, versi
alexilin
2017/04/19 07:59:25
Renamed and commented.
Done.
| |
| 985 (!versioned_bitset.has_value() || versioned_bitset.value()[i]) && | |
| 986 (!no_store_bitset.has_value() || no_store_bitset.value()[i])) { | |
| 987 has_prefetchable_resource = true; | |
| 988 if (urls) | |
| 989 urls->push_back(GURL(resource.url())); | |
|
Benoit L
2017/04/18 16:28:39
useless_nit: emplace_back?
alexilin
2017/04/19 07:59:25
Done.
| |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| 1691 bool was_updated = false; | |
| 1692 base::Optional<std::vector<bool>> unused_bitset = | 1753 base::Optional<std::vector<bool>> unused_bitset = |
| 1693 precache::GetResourceBitset(manifest, internal::kUnusedRemovedExperiment); | 1754 precache::GetResourceBitset(manifest, internal::kUnusedRemovedExperiment); |
| 1755 | |
| 1756 bool was_updated = false; | |
| 1694 if (unused_bitset.has_value()) { | 1757 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 !unused_bitset.value()[it->second]; |
| 1703 }); | 1766 }); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 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 |
| OLD | NEW |