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 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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::GetRedirectEndpoint( | |
| 215 const std::string& first_redirect, | |
| 216 const 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 = | |
| 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 Loading... | |
| 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 Loading... | |
| 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 && |
|
pasko
2016/10/07 15:42:44
add a comment above:
// Attempt to fetch URLs base
alexilin
2016/10/07 16:33:44
Done.
| |
| 513 host_table_cache_->find(main_frame_url.host()); | 542 PopulatePrefetcherRequest(main_frame_url.spec(), *url_table_cache_, 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_, urls)) | |
| 547 return true; | |
| 548 | |
| 549 std::string redirect_endpoint; | |
|
pasko
2016/10/07 15:42:44
Add a comment 1 line above saying:
// Fallback to
alexilin
2016/10/07 16:33:44
Done.
| |
| 550 if (GetRedirectEndpoint(main_frame_url.spec(), *url_redirect_table_cache_, | |
| 551 &redirect_endpoint)) { | |
| 552 GURL redirect_endpoint_url(redirect_endpoint); | |
| 553 | |
| 554 if (use_url_data && PopulatePrefetcherRequest(redirect_endpoint_url.spec(), | |
| 555 *url_table_cache_, urls)) | |
|
pasko
2016/10/07 15:42:44
if the condition takes multiple lines, it requires
alexilin
2016/10/07 16:33:44
Oh, I've thought that this rule is applied only fo
pasko
2016/10/07 17:18:54
I was curious ... because I actually prefer always
alexilin
2016/10/11 13:14:41
Benoit has already forced me to remove brackets in
pasko
2016/10/11 14:16:19
Sorry for the fires :)
I am with Benoit on one-li
alexilin
2016/10/11 15:24:29
Yeah, I see that this is another case.
To summariz
pasko
2016/10/11 15:57:55
not only that, there are more stupid rules regardi
| |
| 556 return true; | |
| 557 | |
| 558 if (use_host_data && PopulatePrefetcherRequest(redirect_endpoint_url.host(), | |
|
pasko
2016/10/07 15:42:45
Using URL-based redirects for host-based prefetch
alexilin
2016/10/07 16:33:44
It wasn't discussed yet so this is only my opinion
pasko
2016/10/07 17:18:54
Im, interesting and reasonable.
Theoretically ..
alexilin
2016/10/11 13:14:41
Done.
| |
| 559 *host_table_cache_, urls)) | |
| 560 return true; | |
| 516 } | 561 } |
| 517 | 562 |
| 518 return !urls->empty(); | 563 return use_host_data && |
| 564 GetRedirectEndpoint(main_frame_url.host(), *host_redirect_table_cache_, | |
| 565 &redirect_endpoint) && | |
| 566 PopulatePrefetcherRequest(redirect_endpoint, *host_table_cache_, urls); | |
| 519 } | 567 } |
| 520 | 568 |
| 521 void ResourcePrefetchPredictor::PopulatePrefetcherRequest( | 569 bool ResourcePrefetchPredictor::PopulatePrefetcherRequest( |
| 522 const PrefetchData& data, | 570 const std::string& main_frame_key, |
| 571 const PrefetchDataMap& data_map, | |
| 523 std::vector<GURL>* urls) { | 572 std::vector<GURL>* urls) { |
| 524 for (const ResourceData& resource : data.resources()) { | 573 DCHECK(urls); |
| 574 PrefetchDataMap::const_iterator it = data_map.find(main_frame_key); | |
| 575 if (it == data_map.end()) | |
| 576 return false; | |
| 577 | |
| 578 size_t initial_size = urls->size(); | |
| 579 for (const ResourceData& resource : it->second.resources()) { | |
| 525 float confidence = | 580 float confidence = |
| 526 static_cast<float>(resource.number_of_hits()) / | 581 static_cast<float>(resource.number_of_hits()) / |
| 527 (resource.number_of_hits() + resource.number_of_misses()); | 582 (resource.number_of_hits() + resource.number_of_misses()); |
| 528 if (confidence < config_.min_resource_confidence_to_trigger_prefetch || | 583 if (confidence < config_.min_resource_confidence_to_trigger_prefetch || |
| 529 resource.number_of_hits() < | 584 resource.number_of_hits() < |
| 530 config_.min_resource_hits_to_trigger_prefetch) { | 585 config_.min_resource_hits_to_trigger_prefetch) |
| 531 continue; | 586 continue; |
| 532 } | |
| 533 | 587 |
| 534 urls->push_back(GURL(resource.resource_url())); | 588 urls->push_back(GURL(resource.resource_url())); |
| 535 } | 589 } |
| 590 | |
| 591 return urls->size() > initial_size; | |
| 536 } | 592 } |
| 537 | 593 |
| 538 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url) { | 594 void ResourcePrefetchPredictor::StartPrefetching(const GURL& url) { |
| 539 if (!prefetch_manager_.get()) // Prefetching not enabled. | 595 if (!prefetch_manager_.get()) // Prefetching not enabled. |
| 540 return; | 596 return; |
| 541 | 597 |
| 542 std::vector<GURL> subresource_urls; | 598 std::vector<GURL> subresource_urls; |
| 543 if (!GetPrefetchData(url, &subresource_urls)) { | 599 if (!GetPrefetchData(url, &subresource_urls)) { |
| 544 // No prefetching data at host or URL level. | 600 // No prefetching data at host or URL level. |
| 545 return; | 601 return; |
| (...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 993 } | 1049 } |
| 994 | 1050 |
| 995 if (need_to_add) { | 1051 if (need_to_add) { |
| 996 RedirectStat* redirect_to_add = data.add_redirect_endpoints(); | 1052 RedirectStat* redirect_to_add = data.add_redirect_endpoints(); |
| 997 redirect_to_add->set_url(final_redirect); | 1053 redirect_to_add->set_url(final_redirect); |
| 998 redirect_to_add->set_number_of_hits(1); | 1054 redirect_to_add->set_number_of_hits(1); |
| 999 } | 1055 } |
| 1000 } | 1056 } |
| 1001 | 1057 |
| 1002 RedirectData& data = cache_entry->second; | 1058 RedirectData& data = cache_entry->second; |
| 1003 // Trim and sort the redirects after the update. | 1059 // Trim the redirects after the update. |
| 1004 ResourcePrefetchPredictorTables::TrimRedirects( | 1060 ResourcePrefetchPredictorTables::TrimRedirects( |
| 1005 &data, config_.max_consecutive_misses); | 1061 &data, config_.max_consecutive_misses); |
| 1006 ResourcePrefetchPredictorTables::SortRedirects(&data); | |
| 1007 | 1062 |
| 1008 if (data.redirect_endpoints_size() == 0) { | 1063 if (data.redirect_endpoints_size() == 0) { |
| 1009 redirect_map->erase(cache_entry); | 1064 redirect_map->erase(cache_entry); |
| 1010 BrowserThread::PostTask( | 1065 BrowserThread::PostTask( |
| 1011 BrowserThread::DB, FROM_HERE, | 1066 BrowserThread::DB, FROM_HERE, |
| 1012 base::Bind( | 1067 base::Bind( |
| 1013 &ResourcePrefetchPredictorTables::DeleteSingleRedirectDataPoint, | 1068 &ResourcePrefetchPredictorTables::DeleteSingleRedirectDataPoint, |
| 1014 tables_, key, key_type)); | 1069 tables_, key, key_type)); |
| 1015 } else { | 1070 } else { |
| 1016 RedirectData empty_redirect_data; | 1071 RedirectData empty_redirect_data; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1068 // HistoryService is already loaded. Continue with Initialization. | 1123 // HistoryService is already loaded. Continue with Initialization. |
| 1069 OnHistoryAndCacheLoaded(); | 1124 OnHistoryAndCacheLoaded(); |
| 1070 return; | 1125 return; |
| 1071 } | 1126 } |
| 1072 DCHECK(!history_service_observer_.IsObserving(history_service)); | 1127 DCHECK(!history_service_observer_.IsObserving(history_service)); |
| 1073 history_service_observer_.Add(history_service); | 1128 history_service_observer_.Add(history_service); |
| 1074 return; | 1129 return; |
| 1075 } | 1130 } |
| 1076 | 1131 |
| 1077 } // namespace predictors | 1132 } // namespace predictors |
| OLD | NEW |