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

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

Issue 2625063002: predictors: Add ResourcePrefetchPredictor database readiness histogram. (Closed)
Patch Set: Change histogram description. Created 3 years, 11 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
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/metrics/sparse_histogram.h" 15 #include "base/metrics/sparse_histogram.h"
16 #include "base/rand_util.h"
16 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
17 #include "base/time/time.h" 18 #include "base/time/time.h"
18 #include "base/trace_event/trace_event.h" 19 #include "base/trace_event/trace_event.h"
19 #include "chrome/browser/history/history_service_factory.h" 20 #include "chrome/browser/history/history_service_factory.h"
20 #include "chrome/browser/predictors/predictor_database.h" 21 #include "chrome/browser/predictors/predictor_database.h"
21 #include "chrome/browser/predictors/predictor_database_factory.h" 22 #include "chrome/browser/predictors/predictor_database_factory.h"
22 #include "chrome/browser/predictors/resource_prefetcher_manager.h" 23 #include "chrome/browser/predictors/resource_prefetcher_manager.h"
23 #include "chrome/browser/profiles/profile.h" 24 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/common/chrome_switches.h" 25 #include "chrome/common/chrome_switches.h"
25 #include "chrome/common/url_constants.h" 26 #include "chrome/common/url_constants.h"
(...skipping 23 matching lines...) Expand all
49 "application/font-woff2", 50 "application/font-woff2",
50 "font/x-woff", 51 "font/x-woff",
51 "application/x-font-ttf", 52 "application/x-font-ttf",
52 "font/woff", 53 "font/woff",
53 "font/ttf", 54 "font/ttf",
54 "application/x-font-otf", 55 "application/x-font-otf",
55 "x-font/woff", 56 "x-font/woff",
56 "application/font-sfnt", 57 "application/font-sfnt",
57 "application/font-ttf"}; 58 "application/font-ttf"};
58 59
60 const size_t kNumSampleHosts = 50;
61 const size_t kReportReadinessThreshold = 50;
62
59 // For reporting events of interest that are not tied to any navigation. 63 // For reporting events of interest that are not tied to any navigation.
60 enum ReportingEvent { 64 enum ReportingEvent {
61 REPORTING_EVENT_ALL_HISTORY_CLEARED = 0, 65 REPORTING_EVENT_ALL_HISTORY_CLEARED = 0,
62 REPORTING_EVENT_PARTIAL_HISTORY_CLEARED = 1, 66 REPORTING_EVENT_PARTIAL_HISTORY_CLEARED = 1,
63 REPORTING_EVENT_COUNT = 2 67 REPORTING_EVENT_COUNT = 2
64 }; 68 };
65 69
66 float ComputeRedirectConfidence(const predictors::RedirectStat& redirect) { 70 float ComputeRedirectConfidence(const predictors::RedirectStat& redirect) {
67 return (redirect.number_of_hits() + 0.0) / 71 return (redirect.number_of_hits() + 0.0) /
68 (redirect.number_of_hits() + redirect.number_of_misses()); 72 (redirect.number_of_hits() + redirect.number_of_misses());
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 history::HistoryService* history_service = 606 history::HistoryService* history_service =
603 HistoryServiceFactory::GetForProfile(profile_, 607 HistoryServiceFactory::GetForProfile(profile_,
604 ServiceAccessType::EXPLICIT_ACCESS); 608 ServiceAccessType::EXPLICIT_ACCESS);
605 DCHECK(history_service); 609 DCHECK(history_service);
606 history_service->ScheduleDBTask( 610 history_service->ScheduleDBTask(
607 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( 611 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask(
608 std::move(summary), 612 std::move(summary),
609 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, 613 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup,
610 AsWeakPtr()))), 614 AsWeakPtr()))),
611 &history_lookup_consumer_); 615 &history_lookup_consumer_);
616
617 // Report readiness metric with 20% probability.
Ilya Sherman 2017/01/12 21:10:39 What's the reason for sampling?
alexilin 2017/01/12 22:53:13 Because of relatively high computation cost. We ne
Ilya Sherman 2017/01/12 23:08:08 Okay, fair enough!
618 if (base::RandInt(1, 5) == 5) {
619 history_service->TopHosts(
620 kNumSampleHosts,
621 base::Bind(&ResourcePrefetchPredictor::ReportDatabaseReadiness,
622 AsWeakPtr()));
623 }
612 } 624 }
613 625
614 bool ResourcePrefetchPredictor::GetPrefetchData(const GURL& main_frame_url, 626 bool ResourcePrefetchPredictor::GetPrefetchData(const GURL& main_frame_url,
615 std::vector<GURL>* urls) { 627 std::vector<GURL>* urls) {
616 DCHECK(urls); 628 DCHECK(urls);
617 DCHECK(urls->empty()); 629 DCHECK(urls->empty());
618 630
619 // Fetch URLs based on a redirect endpoint for URL/host first. 631 // Fetch URLs based on a redirect endpoint for URL/host first.
620 std::string redirect_endpoint; 632 std::string redirect_endpoint;
621 if (GetRedirectEndpoint(main_frame_url.spec(), *url_redirect_table_cache_, 633 if (GetRedirectEndpoint(main_frame_url.spec(), *url_redirect_table_cache_,
(...skipping 22 matching lines...) Expand all
644 const std::string& main_frame_key, 656 const std::string& main_frame_key,
645 const PrefetchDataMap& data_map, 657 const PrefetchDataMap& data_map,
646 std::vector<GURL>* urls) { 658 std::vector<GURL>* urls) {
647 DCHECK(urls); 659 DCHECK(urls);
648 PrefetchDataMap::const_iterator it = data_map.find(main_frame_key); 660 PrefetchDataMap::const_iterator it = data_map.find(main_frame_key);
649 if (it == data_map.end()) 661 if (it == data_map.end())
650 return false; 662 return false;
651 663
652 size_t initial_size = urls->size(); 664 size_t initial_size = urls->size();
653 for (const ResourceData& resource : it->second.resources()) { 665 for (const ResourceData& resource : it->second.resources()) {
654 float confidence = 666 if (IsResourcePrefetchable(resource))
655 static_cast<float>(resource.number_of_hits()) / 667 urls->push_back(GURL(resource.resource_url()));
656 (resource.number_of_hits() + resource.number_of_misses());
657 if (confidence < config_.min_resource_confidence_to_trigger_prefetch ||
658 resource.number_of_hits() <
659 config_.min_resource_hits_to_trigger_prefetch)
660 continue;
661
662 urls->push_back(GURL(resource.resource_url()));
663 } 668 }
664 669
665 return urls->size() > initial_size; 670 return urls->size() > initial_size;
666 } 671 }
667 672
668 void ResourcePrefetchPredictor::CreateCaches( 673 void ResourcePrefetchPredictor::CreateCaches(
669 std::unique_ptr<PrefetchDataMap> url_data_map, 674 std::unique_ptr<PrefetchDataMap> url_data_map,
670 std::unique_ptr<PrefetchDataMap> host_data_map, 675 std::unique_ptr<PrefetchDataMap> host_data_map,
671 std::unique_ptr<RedirectDataMap> url_redirect_data_map, 676 std::unique_ptr<RedirectDataMap> url_redirect_data_map,
672 std::unique_ptr<RedirectDataMap> host_redirect_data_map) { 677 std::unique_ptr<RedirectDataMap> host_redirect_data_map) {
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 const RedirectData& url_redirect_data = 1103 const RedirectData& url_redirect_data =
1099 is_host ? empty_redirect_data : data; 1104 is_host ? empty_redirect_data : data;
1100 BrowserThread::PostTask( 1105 BrowserThread::PostTask(
1101 BrowserThread::DB, FROM_HERE, 1106 BrowserThread::DB, FROM_HERE,
1102 base::Bind(&ResourcePrefetchPredictorTables::UpdateData, tables_, 1107 base::Bind(&ResourcePrefetchPredictorTables::UpdateData, tables_,
1103 empty_data, empty_data, url_redirect_data, 1108 empty_data, empty_data, url_redirect_data,
1104 host_redirect_data)); 1109 host_redirect_data));
1105 } 1110 }
1106 } 1111 }
1107 1112
1113 bool ResourcePrefetchPredictor::IsDataPrefetchable(
1114 const std::string& main_frame_key,
1115 const PrefetchDataMap& data_map) const {
1116 PrefetchDataMap::const_iterator it = data_map.find(main_frame_key);
1117 if (it == data_map.end())
1118 return false;
1119
1120 return std::any_of(it->second.resources().begin(),
1121 it->second.resources().end(),
1122 [this](const ResourceData& resource) {
1123 return IsResourcePrefetchable(resource);
1124 });
1125 }
1126
1127 bool ResourcePrefetchPredictor::IsResourcePrefetchable(
1128 const ResourceData& resource) const {
1129 float confidence = static_cast<float>(resource.number_of_hits()) /
1130 (resource.number_of_hits() + resource.number_of_misses());
1131 return confidence >= config_.min_resource_confidence_to_trigger_prefetch &&
1132 resource.number_of_hits() >=
1133 config_.min_resource_hits_to_trigger_prefetch;
1134 }
1135
1136 void ResourcePrefetchPredictor::ReportDatabaseReadiness(
1137 const history::TopHostsList& top_hosts) const {
1138 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1139 if (top_hosts.size() == 0)
1140 return;
1141
1142 size_t count_in_cache = 0;
1143 size_t total_visits = 0;
1144 for (const std::pair<std::string, int>& top_host : top_hosts) {
1145 const std::string& host = top_host.first;
1146 total_visits += top_host.second;
1147
1148 // Hostnames in TopHostsLists are stripped of their 'www.' prefix. We
1149 // assume that www.foo.com entry from |host_table_cache_| is also suitable
1150 // for foo.com.
1151 if (IsDataPrefetchable(host, *host_table_cache_) ||
1152 (!base::StartsWith(host, "www.", base::CompareCase::SENSITIVE) &&
1153 IsDataPrefetchable("www." + host, *host_table_cache_))) {
1154 ++count_in_cache;
1155 }
1156 }
1157
1158 // Filter users that don't have the rich browsing history.
1159 if (total_visits > kReportReadinessThreshold) {
1160 UMA_HISTOGRAM_PERCENTAGE("ResourcePrefetchPredictor.DatabaseReadiness",
1161 100 * count_in_cache / top_hosts.size());
1162 }
1163 }
1164
1108 void ResourcePrefetchPredictor::OnURLsDeleted( 1165 void ResourcePrefetchPredictor::OnURLsDeleted(
1109 history::HistoryService* history_service, 1166 history::HistoryService* history_service,
1110 bool all_history, 1167 bool all_history,
1111 bool expired, 1168 bool expired,
1112 const history::URLRows& deleted_rows, 1169 const history::URLRows& deleted_rows,
1113 const std::set<GURL>& favicon_urls) { 1170 const std::set<GURL>& favicon_urls) {
1114 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1171 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1115 DCHECK(initialization_state_ == INITIALIZED); 1172 DCHECK(initialization_state_ == INITIALIZED);
1116 1173
1117 if (all_history) { 1174 if (all_history) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 TestObserver::~TestObserver() { 1212 TestObserver::~TestObserver() {
1156 predictor_->SetObserverForTesting(nullptr); 1213 predictor_->SetObserverForTesting(nullptr);
1157 } 1214 }
1158 1215
1159 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) 1216 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor)
1160 : predictor_(predictor) { 1217 : predictor_(predictor) {
1161 predictor_->SetObserverForTesting(this); 1218 predictor_->SetObserverForTesting(this);
1162 } 1219 }
1163 1220
1164 } // namespace predictors 1221 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698