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

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

Issue 2397943004: predictors: Use redirect data in prefetch. (Closed)
Patch Set: Refactor GetPrefetchData, get rid of redirects sort. Created 4 years, 2 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 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 std::any_of(std::begin(kFontMimeTypes), std::end(kFontMimeTypes), 203 std::any_of(std::begin(kFontMimeTypes), std::end(kFontMimeTypes),
204 [&mime_type](const std::string& mime) { 204 [&mime_type](const std::string& mime) {
205 return net::MatchesMimeType(mime, mime_type); 205 return net::MatchesMimeType(mime, mime_type);
206 }); 206 });
207 if (found) 207 if (found)
208 return content::RESOURCE_TYPE_FONT_RESOURCE; 208 return content::RESOURCE_TYPE_FONT_RESOURCE;
209 } 209 }
210 return fallback; 210 return fallback;
211 } 211 }
212 212
213 // static
214 bool ResourcePrefetchPredictor::GetFinalRedirect(
215 const std::string& first_redirect,
216 RedirectDataMap* redirect_data_map,
217 std::string* final_redirect) {
218 DCHECK(final_redirect);
219
220 RedirectDataMap::const_iterator it = redirect_data_map->find(first_redirect);
221 if (it == redirect_data_map->end())
222 return false;
223
224 const RedirectData& redirect_data = it->second;
225 int best_redirect_i = -1;
226 float best_confidence = 0.0;
227 for (int i = 0; i < redirect_data.redirect_endpoints_size(); ++i) {
228 const RedirectStat& redirect = redirect_data.redirect_endpoints(i);
229 float confidence =
230 (redirect.number_of_hits() + 0.0) /
231 (redirect.number_of_hits() + redirect.number_of_misses());
232 if (confidence > best_confidence) {
233 best_redirect_i = i;
234 best_confidence = confidence;
235 }
236 }
237
238 if (best_redirect_i == -1)
239 return false;
240
241 const RedirectStat& best_redirect =
pasko 2016/10/07 13:44:27 std::max_element?
alexilin 2016/10/07 14:29:05 Well, it will lead to small overhead : we'll have
pasko 2016/10/07 15:42:44 Did you mean we would re-compute the confidence 2
alexilin 2016/10/07 16:33:44 I meant that std::max_element accepts comparer as
pasko 2016/10/07 17:18:54 Ah, sorry, you are right, this has a comparator, h
alexilin 2016/10/11 13:14:41 Done.
242 redirect_data.redirect_endpoints(best_redirect_i);
243 const float kMinRedirectConfidenceToTriggerPrefetch = 0.7f;
244 const int kMinRedirectHitsToTriggerPrefetch = 2;
245
246 if (best_confidence < kMinRedirectConfidenceToTriggerPrefetch ||
247 best_redirect.number_of_hits() < kMinRedirectHitsToTriggerPrefetch)
248 return false;
249
250 *final_redirect = best_redirect.url();
251 return true;
252 }
253
213 //////////////////////////////////////////////////////////////////////////////// 254 ////////////////////////////////////////////////////////////////////////////////
214 // ResourcePrefetchPredictor nested types. 255 // ResourcePrefetchPredictor nested types.
215 256
216 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary() 257 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary()
217 : resource_type(content::RESOURCE_TYPE_LAST_TYPE), 258 : resource_type(content::RESOURCE_TYPE_LAST_TYPE),
218 priority(net::IDLE), 259 priority(net::IDLE),
219 was_cached(false), 260 was_cached(false),
220 has_validators(false), 261 has_validators(false),
221 always_revalidate(false) {} 262 always_revalidate(false) {}
222 263
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 if (initialization_state_ != INITIALIZED) 453 if (initialization_state_ != INITIALIZED)
413 return; 454 return;
414 455
415 StopPrefetching(response.navigation_id.main_frame_url); 456 StopPrefetching(response.navigation_id.main_frame_url);
416 } 457 }
417 458
418 void ResourcePrefetchPredictor::OnMainFrameRedirect( 459 void ResourcePrefetchPredictor::OnMainFrameRedirect(
419 const URLRequestSummary& response) { 460 const URLRequestSummary& response) {
420 DCHECK_CURRENTLY_ON(BrowserThread::UI); 461 DCHECK_CURRENTLY_ON(BrowserThread::UI);
421 462
422 // Stop any inflight prefetching. Remove the older navigation.
423 StopPrefetching(response.navigation_id.main_frame_url);
424
425 std::unique_ptr<PageRequestSummary> summary; 463 std::unique_ptr<PageRequestSummary> summary;
426 NavigationMap::iterator nav_it = 464 NavigationMap::iterator nav_it =
427 inflight_navigations_.find(response.navigation_id); 465 inflight_navigations_.find(response.navigation_id);
428 if (nav_it != inflight_navigations_.end()) { 466 if (nav_it != inflight_navigations_.end()) {
429 summary.reset(nav_it->second.release()); 467 summary.reset(nav_it->second.release());
430 inflight_navigations_.erase(nav_it); 468 inflight_navigations_.erase(nav_it);
431 } 469 }
432 470
433 // The redirect url may be empty if the URL was invalid. 471 // The redirect url may be empty if the URL was invalid.
434 if (response.redirect_url.is_empty()) 472 if (response.redirect_url.is_empty())
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( 523 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask(
486 navigation_id, std::move(summary), 524 navigation_id, std::move(summary),
487 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, 525 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup,
488 AsWeakPtr()))), 526 AsWeakPtr()))),
489 &history_lookup_consumer_); 527 &history_lookup_consumer_);
490 } 528 }
491 529
492 bool ResourcePrefetchPredictor::GetPrefetchData(const GURL& main_frame_url, 530 bool ResourcePrefetchPredictor::GetPrefetchData(const GURL& main_frame_url,
493 std::vector<GURL>* urls) { 531 std::vector<GURL>* urls) {
494 DCHECK(urls); 532 DCHECK(urls);
495 533 DCHECK(urls->empty());
496 bool use_url_data = config_.IsPrefetchingEnabled(profile_) ? 534 bool use_url_data = config_.IsPrefetchingEnabled(profile_) ?
497 config_.IsURLPrefetchingEnabled(profile_) : 535 config_.IsURLPrefetchingEnabled(profile_) :
498 config_.IsURLLearningEnabled(); 536 config_.IsURLLearningEnabled();
499 if (use_url_data) {
500 PrefetchDataMap::const_iterator iterator =
501 url_table_cache_->find(main_frame_url.spec());
502 if (iterator != url_table_cache_->end())
503 PopulatePrefetcherRequest(iterator->second, urls);
504 }
505 if (!urls->empty())
506 return true;
507
508 bool use_host_data = config_.IsPrefetchingEnabled(profile_) ? 537 bool use_host_data = config_.IsPrefetchingEnabled(profile_) ?
509 config_.IsHostPrefetchingEnabled(profile_) : 538 config_.IsHostPrefetchingEnabled(profile_) :
510 config_.IsHostLearningEnabled(); 539 config_.IsHostLearningEnabled();
511 if (use_host_data) { 540
512 PrefetchDataMap::const_iterator iterator = 541 if (use_url_data && PopulatePrefetcherRequest(main_frame_url.spec(),
513 host_table_cache_->find(main_frame_url.host()); 542 url_table_cache_.get(), urls))
514 if (iterator != host_table_cache_->end()) 543 return true;
515 PopulatePrefetcherRequest(iterator->second, urls); 544
545 if (use_host_data && PopulatePrefetcherRequest(main_frame_url.host(),
546 host_table_cache_.get(), urls))
547 return true;
548
549 std::string final_redirect;
550 if (GetFinalRedirect(main_frame_url.spec(), url_redirect_table_cache_.get(),
551 &final_redirect)) {
552 GURL redirect_url(final_redirect);
553
554 if (use_url_data && PopulatePrefetcherRequest(redirect_url.spec(),
555 url_table_cache_.get(), urls))
556 return true;
557
558 if (use_host_data &&
559 PopulatePrefetcherRequest(redirect_url.host(), host_table_cache_.get(),
560 urls))
561 return true;
516 } 562 }
517 563
518 return !urls->empty(); 564 return use_host_data &&
565 GetFinalRedirect(main_frame_url.host(),
566 host_redirect_table_cache_.get(), &final_redirect) &&
567 PopulatePrefetcherRequest(final_redirect, host_table_cache_.get(),
568 urls);
519 } 569 }
520 570
521 void ResourcePrefetchPredictor::PopulatePrefetcherRequest( 571 bool ResourcePrefetchPredictor::PopulatePrefetcherRequest(
522 const PrefetchData& data, 572 const std::string& main_frame_key,
573 PrefetchDataMap* data_map,
523 std::vector<GURL>* urls) { 574 std::vector<GURL>* urls) {
524 for (const ResourceData& resource : data.resources()) { 575 DCHECK(data_map);
576 DCHECK(urls);
577 PrefetchDataMap::const_iterator it = data_map->find(main_frame_key);
578 if (it == data_map->end())
579 return false;
580
581 size_t initial_size = urls->size();
582 for (const ResourceData& resource : it->second.resources()) {
525 float confidence = 583 float confidence =
526 static_cast<float>(resource.number_of_hits()) / 584 static_cast<float>(resource.number_of_hits()) /
527 (resource.number_of_hits() + resource.number_of_misses()); 585 (resource.number_of_hits() + resource.number_of_misses());
528 if (confidence < config_.min_resource_confidence_to_trigger_prefetch || 586 if (confidence < config_.min_resource_confidence_to_trigger_prefetch ||
529 resource.number_of_hits() < 587 resource.number_of_hits() <
530 config_.min_resource_hits_to_trigger_prefetch) { 588 config_.min_resource_hits_to_trigger_prefetch)
531 continue; 589 continue;
532 }
533 590
534 urls->push_back(GURL(resource.resource_url())); 591 urls->push_back(GURL(resource.resource_url()));
535 } 592 }
593
594 return urls->size() > initial_size;
536 } 595 }
537 596
538 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url) { 597 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url) {
539 if (!prefetch_manager_.get()) // Prefetching not enabled. 598 if (!prefetch_manager_.get()) // Prefetching not enabled.
540 return; 599 return;
541 600
542 std::vector<GURL> subresource_urls; 601 std::vector<GURL> subresource_urls;
543 if (!GetPrefetchData(url, &subresource_urls)) { 602 if (!GetPrefetchData(url, &subresource_urls)) {
544 // No prefetching data at host or URL level. 603 // No prefetching data at host or URL level.
545 return; 604 return;
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 } 1052 }
994 1053
995 if (need_to_add) { 1054 if (need_to_add) {
996 RedirectStat* redirect_to_add = data.add_redirect_endpoints(); 1055 RedirectStat* redirect_to_add = data.add_redirect_endpoints();
997 redirect_to_add->set_url(final_redirect); 1056 redirect_to_add->set_url(final_redirect);
998 redirect_to_add->set_number_of_hits(1); 1057 redirect_to_add->set_number_of_hits(1);
999 } 1058 }
1000 } 1059 }
1001 1060
1002 RedirectData& data = cache_entry->second; 1061 RedirectData& data = cache_entry->second;
1003 // Trim and sort the redirects after the update. 1062 // Trim the redirects after the update.
1004 ResourcePrefetchPredictorTables::TrimRedirects( 1063 ResourcePrefetchPredictorTables::TrimRedirects(
1005 &data, config_.max_consecutive_misses); 1064 &data, config_.max_consecutive_misses);
1006 ResourcePrefetchPredictorTables::SortRedirects(&data);
1007 1065
1008 if (data.redirect_endpoints_size() == 0) { 1066 if (data.redirect_endpoints_size() == 0) {
1009 redirect_map->erase(cache_entry); 1067 redirect_map->erase(cache_entry);
1010 BrowserThread::PostTask( 1068 BrowserThread::PostTask(
1011 BrowserThread::DB, FROM_HERE, 1069 BrowserThread::DB, FROM_HERE,
1012 base::Bind( 1070 base::Bind(
1013 &ResourcePrefetchPredictorTables::DeleteSingleRedirectDataPoint, 1071 &ResourcePrefetchPredictorTables::DeleteSingleRedirectDataPoint,
1014 tables_, key, key_type)); 1072 tables_, key, key_type));
1015 } else { 1073 } else {
1016 RedirectData empty_redirect_data; 1074 RedirectData empty_redirect_data;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 // HistoryService is already loaded. Continue with Initialization. 1126 // HistoryService is already loaded. Continue with Initialization.
1069 OnHistoryAndCacheLoaded(); 1127 OnHistoryAndCacheLoaded();
1070 return; 1128 return;
1071 } 1129 }
1072 DCHECK(!history_service_observer_.IsObserving(history_service)); 1130 DCHECK(!history_service_observer_.IsObserving(history_service));
1073 history_service_observer_.Add(history_service); 1131 history_service_observer_.Add(history_service);
1074 return; 1132 return;
1075 } 1133 }
1076 1134
1077 } // namespace predictors 1135 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698