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 |
| 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/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
| 14 #include "base/metrics/sparse_histogram.h" | 15 #include "base/metrics/sparse_histogram.h" |
| 15 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
| 16 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
| 17 #include "base/time/time.h" | 18 #include "base/time/time.h" |
| 18 #include "chrome/browser/history/history_service_factory.h" | 19 #include "chrome/browser/history/history_service_factory.h" |
| 19 #include "chrome/browser/predictors/predictor_database.h" | 20 #include "chrome/browser/predictors/predictor_database.h" |
| 20 #include "chrome/browser/predictors/predictor_database_factory.h" | 21 #include "chrome/browser/predictors/predictor_database_factory.h" |
| 21 #include "chrome/browser/predictors/resource_prefetcher_manager.h" | 22 #include "chrome/browser/predictors/resource_prefetcher_manager.h" |
| 22 #include "chrome/browser/profiles/profile.h" | 23 #include "chrome/browser/profiles/profile.h" |
| 23 #include "chrome/common/chrome_switches.h" | 24 #include "chrome/common/chrome_switches.h" |
| 24 #include "chrome/common/url_constants.h" | 25 #include "chrome/common/url_constants.h" |
| 25 #include "components/history/core/browser/history_database.h" | 26 #include "components/history/core/browser/history_database.h" |
| 26 #include "components/history/core/browser/history_db_task.h" | |
| 27 #include "components/history/core/browser/history_service.h" | 27 #include "components/history/core/browser/history_service.h" |
| 28 #include "components/mime_util/mime_util.h" | 28 #include "components/mime_util/mime_util.h" |
| 29 #include "content/public/browser/browser_thread.h" | 29 #include "content/public/browser/browser_thread.h" |
| 30 #include "content/public/browser/navigation_controller.h" | 30 #include "content/public/browser/navigation_controller.h" |
| 31 #include "content/public/browser/resource_request_info.h" | 31 #include "content/public/browser/resource_request_info.h" |
| 32 #include "content/public/browser/web_contents.h" | 32 #include "content/public/browser/web_contents.h" |
| 33 #include "net/base/mime_util.h" | 33 #include "net/base/mime_util.h" |
| 34 #include "net/base/network_change_notifier.h" | 34 #include "net/base/network_change_notifier.h" |
| 35 #include "net/http/http_response_headers.h" | 35 #include "net/http/http_response_headers.h" |
| 36 #include "net/url_request/url_request.h" | 36 #include "net/url_request/url_request.h" |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 58 enum ReportingEvent { | 58 enum ReportingEvent { |
| 59 REPORTING_EVENT_ALL_HISTORY_CLEARED = 0, | 59 REPORTING_EVENT_ALL_HISTORY_CLEARED = 0, |
| 60 REPORTING_EVENT_PARTIAL_HISTORY_CLEARED = 1, | 60 REPORTING_EVENT_PARTIAL_HISTORY_CLEARED = 1, |
| 61 REPORTING_EVENT_COUNT = 2 | 61 REPORTING_EVENT_COUNT = 2 |
| 62 }; | 62 }; |
| 63 | 63 |
| 64 } // namespace | 64 } // namespace |
| 65 | 65 |
| 66 namespace predictors { | 66 namespace predictors { |
| 67 | 67 |
| 68 //////////////////////////////////////////////////////////////////////////////// | 68 const int kMaxRedirectsPerEntry = 20; |
| 69 // History lookup task. | |
| 70 | |
| 71 // Used to fetch the visit count for a URL from the History database. | |
| 72 class GetUrlVisitCountTask : public history::HistoryDBTask { | |
| 73 public: | |
| 74 typedef ResourcePrefetchPredictor::URLRequestSummary URLRequestSummary; | |
| 75 typedef base::Callback<void( | |
| 76 size_t, // Visit count. | |
| 77 const NavigationID&, | |
| 78 const std::vector<URLRequestSummary>&)> VisitInfoCallback; | |
| 79 | |
| 80 GetUrlVisitCountTask( | |
| 81 const NavigationID& navigation_id, | |
| 82 std::vector<URLRequestSummary>* requests, | |
| 83 VisitInfoCallback callback) | |
| 84 : visit_count_(0), | |
| 85 navigation_id_(navigation_id), | |
| 86 requests_(requests), | |
| 87 callback_(callback) { | |
| 88 DCHECK(requests_.get()); | |
| 89 } | |
| 90 | |
| 91 bool RunOnDBThread(history::HistoryBackend* backend, | |
| 92 history::HistoryDatabase* db) override { | |
| 93 history::URLRow url_row; | |
| 94 if (db->GetRowForURL(navigation_id_.main_frame_url, &url_row)) | |
| 95 visit_count_ = url_row.visit_count(); | |
| 96 return true; | |
| 97 } | |
| 98 | |
| 99 void DoneRunOnMainThread() override { | |
| 100 callback_.Run(visit_count_, navigation_id_, *requests_); | |
| 101 } | |
| 102 | |
| 103 private: | |
| 104 ~GetUrlVisitCountTask() override {} | |
| 105 | |
| 106 int visit_count_; | |
| 107 NavigationID navigation_id_; | |
| 108 std::unique_ptr<std::vector<URLRequestSummary>> requests_; | |
| 109 VisitInfoCallback callback_; | |
| 110 | |
| 111 DISALLOW_COPY_AND_ASSIGN(GetUrlVisitCountTask); | |
| 112 }; | |
| 113 | 69 |
| 114 //////////////////////////////////////////////////////////////////////////////// | 70 //////////////////////////////////////////////////////////////////////////////// |
| 115 // ResourcePrefetchPredictor static functions. | 71 // ResourcePrefetchPredictor static functions. |
| 116 | 72 |
| 117 // static | 73 // static |
| 118 bool ResourcePrefetchPredictor::ShouldRecordRequest( | 74 bool ResourcePrefetchPredictor::ShouldRecordRequest( |
| 119 net::URLRequest* request, | 75 net::URLRequest* request, |
| 120 content::ResourceType resource_type) { | 76 content::ResourceType resource_type) { |
| 121 const content::ResourceRequestInfo* request_info = | 77 const content::ResourceRequestInfo* request_info = |
| 122 content::ResourceRequestInfo::ForRequest(request); | 78 content::ResourceRequestInfo::ForRequest(request); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 250 [&mime_type](const std::string& mime) { | 206 [&mime_type](const std::string& mime) { |
| 251 return net::MatchesMimeType(mime, mime_type); | 207 return net::MatchesMimeType(mime, mime_type); |
| 252 }); | 208 }); |
| 253 if (found) | 209 if (found) |
| 254 return content::RESOURCE_TYPE_FONT_RESOURCE; | 210 return content::RESOURCE_TYPE_FONT_RESOURCE; |
| 255 } | 211 } |
| 256 return fallback; | 212 return fallback; |
| 257 } | 213 } |
| 258 | 214 |
| 259 //////////////////////////////////////////////////////////////////////////////// | 215 //////////////////////////////////////////////////////////////////////////////// |
| 260 // ResourcePrefetchPredictor structs. | 216 // ResourcePrefetchPredictor nested types. |
| 261 | 217 |
| 262 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary() | 218 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary() |
| 263 : resource_type(content::RESOURCE_TYPE_LAST_TYPE), | 219 : resource_type(content::RESOURCE_TYPE_LAST_TYPE), |
| 264 priority(net::IDLE), | 220 priority(net::IDLE), |
| 265 was_cached(false), | 221 was_cached(false), |
| 266 has_validators(false), | 222 has_validators(false), |
| 267 always_revalidate(false) {} | 223 always_revalidate(false) {} |
| 268 | 224 |
| 269 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary( | 225 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary( |
| 270 const URLRequestSummary& other) | 226 const URLRequestSummary& other) |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 311 summary->has_validators = headers->HasValidators(); | 267 summary->has_validators = headers->HasValidators(); |
| 312 // RFC 2616, section 14.9. | 268 // RFC 2616, section 14.9. |
| 313 summary->always_revalidate = | 269 summary->always_revalidate = |
| 314 headers->HasHeaderValue("cache-control", "no-cache") || | 270 headers->HasHeaderValue("cache-control", "no-cache") || |
| 315 headers->HasHeaderValue("pragma", "no-cache") || | 271 headers->HasHeaderValue("pragma", "no-cache") || |
| 316 headers->HasHeaderValue("vary", "*"); | 272 headers->HasHeaderValue("vary", "*"); |
| 317 } | 273 } |
| 318 return true; | 274 return true; |
| 319 } | 275 } |
| 320 | 276 |
| 277 ResourcePrefetchPredictor::GetUrlVisitCountTask::GetUrlVisitCountTask( | |
| 278 const NavigationID& navigation_id, | |
| 279 std::unique_ptr<PageRequestSummary> summary, | |
| 280 VisitInfoCallback callback) | |
| 281 : visit_count_(0), | |
| 282 navigation_id_(navigation_id), | |
| 283 summary_(std::move(summary)), | |
| 284 callback_(callback) { | |
| 285 DCHECK(summary_.get()); | |
| 286 } | |
| 287 | |
| 288 bool ResourcePrefetchPredictor::GetUrlVisitCountTask::RunOnDBThread( | |
| 289 history::HistoryBackend* backend, | |
| 290 history::HistoryDatabase* db) { | |
| 291 history::URLRow url_row; | |
| 292 if (db->GetRowForURL(navigation_id_.main_frame_url, &url_row)) | |
| 293 visit_count_ = url_row.visit_count(); | |
| 294 return true; | |
| 295 } | |
| 296 | |
| 297 void ResourcePrefetchPredictor::GetUrlVisitCountTask::DoneRunOnMainThread() { | |
| 298 callback_.Run(visit_count_, navigation_id_, *summary_); | |
| 299 } | |
| 300 | |
| 301 ResourcePrefetchPredictor::GetUrlVisitCountTask::~GetUrlVisitCountTask() {} | |
| 302 | |
| 303 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( | |
| 304 const GURL& i_initial_url) | |
| 305 : initial_url(i_initial_url) {} | |
| 306 | |
| 307 ResourcePrefetchPredictor::PageRequestSummary::~PageRequestSummary() {} | |
| 308 | |
| 321 //////////////////////////////////////////////////////////////////////////////// | 309 //////////////////////////////////////////////////////////////////////////////// |
| 322 // ResourcePrefetchPredictor. | 310 // ResourcePrefetchPredictor. |
| 323 | 311 |
| 324 ResourcePrefetchPredictor::ResourcePrefetchPredictor( | 312 ResourcePrefetchPredictor::ResourcePrefetchPredictor( |
| 325 const ResourcePrefetchPredictorConfig& config, | 313 const ResourcePrefetchPredictorConfig& config, |
| 326 Profile* profile) | 314 Profile* profile) |
| 327 : profile_(profile), | 315 : profile_(profile), |
| 328 config_(config), | 316 config_(config), |
| 329 initialization_state_(NOT_INITIALIZED), | 317 initialization_state_(NOT_INITIALIZED), |
| 330 tables_(PredictorDatabaseFactory::GetForProfile(profile) | 318 tables_(PredictorDatabaseFactory::GetForProfile(profile) |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 407 const URLRequestSummary& request) { | 395 const URLRequestSummary& request) { |
| 408 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 396 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 409 DCHECK_EQ(INITIALIZED, initialization_state_); | 397 DCHECK_EQ(INITIALIZED, initialization_state_); |
| 410 | 398 |
| 411 StartPrefetching(request.navigation_id); | 399 StartPrefetching(request.navigation_id); |
| 412 | 400 |
| 413 // Cleanup older navigations. | 401 // Cleanup older navigations. |
| 414 CleanupAbandonedNavigations(request.navigation_id); | 402 CleanupAbandonedNavigations(request.navigation_id); |
| 415 | 403 |
| 416 // New empty navigation entry. | 404 // New empty navigation entry. |
| 417 inflight_navigations_.insert(std::make_pair( | 405 const GURL& initial_url = request.navigation_id.main_frame_url; |
| 418 request.navigation_id, | 406 inflight_navigations_.insert( |
| 419 make_linked_ptr(new std::vector<URLRequestSummary>()))); | 407 std::make_pair(request.navigation_id, |
| 408 base::MakeUnique<PageRequestSummary>(initial_url))); | |
| 420 } | 409 } |
| 421 | 410 |
| 422 void ResourcePrefetchPredictor::OnMainFrameResponse( | 411 void ResourcePrefetchPredictor::OnMainFrameResponse( |
| 423 const URLRequestSummary& response) { | 412 const URLRequestSummary& response) { |
| 424 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 413 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 425 if (initialization_state_ != INITIALIZED) | 414 if (initialization_state_ != INITIALIZED) |
| 426 return; | 415 return; |
| 427 | 416 |
| 428 StopPrefetching(response.navigation_id); | 417 StopPrefetching(response.navigation_id); |
| 429 } | 418 } |
| 430 | 419 |
| 431 void ResourcePrefetchPredictor::OnMainFrameRedirect( | 420 void ResourcePrefetchPredictor::OnMainFrameRedirect( |
| 432 const URLRequestSummary& response) { | 421 const URLRequestSummary& response) { |
| 433 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 422 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 434 | 423 |
| 435 // TODO(shishir): There are significant gains to be had here if we can use the | |
| 436 // start URL in a redirect chain as the key to start prefetching. We can save | |
| 437 // of redirect times considerably assuming that the redirect chains do not | |
| 438 // change. | |
| 439 | |
| 440 // Stop any inflight prefetching. Remove the older navigation. | 424 // Stop any inflight prefetching. Remove the older navigation. |
| 441 StopPrefetching(response.navigation_id); | 425 StopPrefetching(response.navigation_id); |
| 442 inflight_navigations_.erase(response.navigation_id); | |
| 443 | 426 |
| 444 // A redirect will not lead to another OnMainFrameRequest call, so record the | 427 std::unique_ptr<PageRequestSummary> summary; |
| 445 // redirect url as a new navigation. | 428 NavigationMap::iterator nav_it = |
| 429 inflight_navigations_.find(response.navigation_id); | |
| 430 if (nav_it != inflight_navigations_.end()) { | |
| 431 summary.reset(nav_it->second.release()); | |
| 432 inflight_navigations_.erase(nav_it); | |
| 433 } | |
| 446 | 434 |
| 447 // The redirect url may be empty if the URL was invalid. | 435 // The redirect url may be empty if the URL was invalid. |
| 448 if (response.redirect_url.is_empty()) | 436 if (response.redirect_url.is_empty()) |
| 449 return; | 437 return; |
| 450 | 438 |
| 439 // If we lost the information about the first hop for some reason. | |
|
pasko
2016/09/27 16:21:27
In what circumstances does this happen?
alexilin
2016/09/27 18:11:08
See https://codereview.chromium.org/2355273002/dif
| |
| 440 if (!summary) { | |
| 441 const GURL& initial_url = response.navigation_id.main_frame_url; | |
| 442 summary = base::MakeUnique<PageRequestSummary>(initial_url); | |
| 443 } | |
| 444 | |
| 445 // A redirect will not lead to another OnMainFrameRequest call, so record the | |
| 446 // redirect url as a new navigation id and save the initial url. | |
| 451 NavigationID navigation_id(response.navigation_id); | 447 NavigationID navigation_id(response.navigation_id); |
| 452 navigation_id.main_frame_url = response.redirect_url; | 448 navigation_id.main_frame_url = response.redirect_url; |
| 453 inflight_navigations_.insert(std::make_pair( | 449 inflight_navigations_.insert( |
| 454 navigation_id, | 450 std::make_pair(navigation_id, std::move(summary))); |
| 455 make_linked_ptr(new std::vector<URLRequestSummary>()))); | |
| 456 } | 451 } |
| 457 | 452 |
| 458 void ResourcePrefetchPredictor::OnSubresourceResponse( | 453 void ResourcePrefetchPredictor::OnSubresourceResponse( |
| 459 const URLRequestSummary& response) { | 454 const URLRequestSummary& response) { |
| 460 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 455 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 461 | 456 |
| 462 NavigationMap::const_iterator nav_it = | 457 NavigationMap::const_iterator nav_it = |
| 463 inflight_navigations_.find(response.navigation_id); | 458 inflight_navigations_.find(response.navigation_id); |
| 464 if (nav_it == inflight_navigations_.end()) { | 459 if (nav_it == inflight_navigations_.end()) { |
| 465 return; | 460 return; |
| 466 } | 461 } |
| 467 | 462 |
| 468 nav_it->second->push_back(response); | 463 nav_it->second->subresource_requests.push_back(response); |
| 469 } | 464 } |
| 470 | 465 |
| 471 void ResourcePrefetchPredictor::OnNavigationComplete( | 466 void ResourcePrefetchPredictor::OnNavigationComplete( |
| 472 const NavigationID& nav_id_without_timing_info) { | 467 const NavigationID& nav_id_without_timing_info) { |
| 473 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 468 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 474 | 469 |
| 475 NavigationMap::iterator nav_it = | 470 NavigationMap::iterator nav_it = |
| 476 inflight_navigations_.find(nav_id_without_timing_info); | 471 inflight_navigations_.find(nav_id_without_timing_info); |
| 477 if (nav_it == inflight_navigations_.end()) | 472 if (nav_it == inflight_navigations_.end()) |
| 478 return; | 473 return; |
| 479 | 474 |
| 480 const NavigationID navigation_id(nav_it->first); | 475 const NavigationID navigation_id(nav_it->first); |
| 481 | 476 |
| 482 // Remove the navigation from the inflight navigations. | 477 // Remove the navigation from the inflight navigations. |
| 483 std::vector<URLRequestSummary>* requests = (nav_it->second).release(); | 478 std::unique_ptr<PageRequestSummary> summary = std::move(nav_it->second); |
| 484 inflight_navigations_.erase(nav_it); | 479 inflight_navigations_.erase(nav_it); |
| 485 | 480 |
| 486 // Kick off history lookup to determine if we should record the URL. | 481 // Kick off history lookup to determine if we should record the URL. |
| 487 history::HistoryService* history_service = | 482 history::HistoryService* history_service = |
| 488 HistoryServiceFactory::GetForProfile(profile_, | 483 HistoryServiceFactory::GetForProfile(profile_, |
| 489 ServiceAccessType::EXPLICIT_ACCESS); | 484 ServiceAccessType::EXPLICIT_ACCESS); |
| 490 DCHECK(history_service); | 485 DCHECK(history_service); |
| 491 history_service->ScheduleDBTask( | 486 history_service->ScheduleDBTask( |
| 492 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( | 487 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( |
| 493 navigation_id, requests, | 488 navigation_id, std::move(summary), |
| 494 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, | 489 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, |
| 495 AsWeakPtr()))), | 490 AsWeakPtr()))), |
| 496 &history_lookup_consumer_); | 491 &history_lookup_consumer_); |
| 497 } | 492 } |
| 498 | 493 |
| 499 bool ResourcePrefetchPredictor::GetPrefetchData( | 494 bool ResourcePrefetchPredictor::GetPrefetchData( |
| 500 const NavigationID& navigation_id, | 495 const NavigationID& navigation_id, |
| 501 std::vector<GURL>* urls, | 496 std::vector<GURL>* urls, |
| 502 PrefetchKeyType* key_type) { | 497 PrefetchKeyType* key_type) { |
| 503 DCHECK(urls); | 498 DCHECK(urls); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 579 navigation_id)); | 574 navigation_id)); |
| 580 } | 575 } |
| 581 | 576 |
| 582 void ResourcePrefetchPredictor::StartInitialization() { | 577 void ResourcePrefetchPredictor::StartInitialization() { |
| 583 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 578 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 584 | 579 |
| 585 DCHECK_EQ(NOT_INITIALIZED, initialization_state_); | 580 DCHECK_EQ(NOT_INITIALIZED, initialization_state_); |
| 586 initialization_state_ = INITIALIZING; | 581 initialization_state_ = INITIALIZING; |
| 587 | 582 |
| 588 // Create local caches using the database as loaded. | 583 // Create local caches using the database as loaded. |
| 589 std::unique_ptr<PrefetchDataMap> url_data_map(new PrefetchDataMap()); | 584 auto url_data_map = base::MakeUnique<PrefetchDataMap>(); |
| 590 std::unique_ptr<PrefetchDataMap> host_data_map(new PrefetchDataMap()); | 585 auto host_data_map = base::MakeUnique<PrefetchDataMap>(); |
| 591 PrefetchDataMap* url_data_ptr = url_data_map.get(); | 586 auto url_redirect_data_map = base::MakeUnique<RedirectDataMap>(); |
| 592 PrefetchDataMap* host_data_ptr = host_data_map.get(); | 587 auto host_redirect_data_map = base::MakeUnique<RedirectDataMap>(); |
| 593 | 588 |
| 594 BrowserThread::PostTaskAndReply( | 589 BrowserThread::PostTaskAndReply( |
| 595 BrowserThread::DB, FROM_HERE, | 590 BrowserThread::DB, FROM_HERE, |
| 596 base::Bind(&ResourcePrefetchPredictorTables::GetAllData, | 591 base::Bind(&ResourcePrefetchPredictorTables::GetAllData, tables_, |
| 597 tables_, url_data_ptr, host_data_ptr), | 592 url_data_map.get(), host_data_map.get(), |
| 593 url_redirect_data_map.get(), host_redirect_data_map.get()), | |
| 598 base::Bind(&ResourcePrefetchPredictor::CreateCaches, AsWeakPtr(), | 594 base::Bind(&ResourcePrefetchPredictor::CreateCaches, AsWeakPtr(), |
| 599 base::Passed(&url_data_map), base::Passed(&host_data_map))); | 595 base::Passed(&url_data_map), base::Passed(&host_data_map), |
| 596 base::Passed(&url_redirect_data_map), | |
| 597 base::Passed(&host_redirect_data_map))); | |
| 600 } | 598 } |
| 601 | 599 |
| 602 void ResourcePrefetchPredictor::CreateCaches( | 600 void ResourcePrefetchPredictor::CreateCaches( |
| 603 std::unique_ptr<PrefetchDataMap> url_data_map, | 601 std::unique_ptr<PrefetchDataMap> url_data_map, |
| 604 std::unique_ptr<PrefetchDataMap> host_data_map) { | 602 std::unique_ptr<PrefetchDataMap> host_data_map, |
| 603 std::unique_ptr<RedirectDataMap> url_redirect_data_map, | |
| 604 std::unique_ptr<RedirectDataMap> host_redirect_data_map) { | |
| 605 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 605 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 606 | 606 |
| 607 DCHECK_EQ(INITIALIZING, initialization_state_); | 607 DCHECK_EQ(INITIALIZING, initialization_state_); |
| 608 DCHECK(!url_table_cache_); | 608 DCHECK(!url_table_cache_); |
| 609 DCHECK(!host_table_cache_); | 609 DCHECK(!host_table_cache_); |
| 610 DCHECK(!url_redirect_table_cache_); | |
| 611 DCHECK(!host_redirect_table_cache_); | |
| 610 DCHECK(inflight_navigations_.empty()); | 612 DCHECK(inflight_navigations_.empty()); |
| 611 | 613 |
| 612 url_table_cache_.reset(url_data_map.release()); | 614 url_table_cache_.reset(url_data_map.release()); |
| 613 host_table_cache_.reset(host_data_map.release()); | 615 host_table_cache_.reset(host_data_map.release()); |
| 616 url_redirect_table_cache_.reset(url_redirect_data_map.release()); | |
| 617 host_redirect_table_cache_.reset(host_redirect_data_map.release()); | |
| 614 | 618 |
| 615 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.UrlTableMainFrameUrlCount", | 619 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.UrlTableMainFrameUrlCount", |
| 616 url_table_cache_->size()); | 620 url_table_cache_->size()); |
| 617 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostTableHostCount", | 621 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostTableHostCount", |
| 618 host_table_cache_->size()); | 622 host_table_cache_->size()); |
| 619 | 623 |
| 620 ConnectToHistoryService(); | 624 ConnectToHistoryService(); |
| 621 } | 625 } |
| 622 | 626 |
| 623 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() { | 627 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() { |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 646 } else { | 650 } else { |
| 647 ++it; | 651 ++it; |
| 648 } | 652 } |
| 649 } | 653 } |
| 650 } | 654 } |
| 651 | 655 |
| 652 void ResourcePrefetchPredictor::DeleteAllUrls() { | 656 void ResourcePrefetchPredictor::DeleteAllUrls() { |
| 653 inflight_navigations_.clear(); | 657 inflight_navigations_.clear(); |
| 654 url_table_cache_->clear(); | 658 url_table_cache_->clear(); |
| 655 host_table_cache_->clear(); | 659 host_table_cache_->clear(); |
| 660 url_redirect_table_cache_->clear(); | |
| 661 host_redirect_table_cache_->clear(); | |
| 656 | 662 |
| 657 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, | 663 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, |
| 658 base::Bind(&ResourcePrefetchPredictorTables::DeleteAllData, tables_)); | 664 base::Bind(&ResourcePrefetchPredictorTables::DeleteAllData, tables_)); |
| 659 } | 665 } |
| 660 | 666 |
| 661 void ResourcePrefetchPredictor::DeleteUrls(const history::URLRows& urls) { | 667 void ResourcePrefetchPredictor::DeleteUrls(const history::URLRows& urls) { |
| 662 // Check all the urls in the database and pick out the ones that are present | 668 // Check all the urls in the database and pick out the ones that are present |
| 663 // in the cache. | 669 // in the cache. |
| 664 std::vector<std::string> urls_to_delete, hosts_to_delete; | 670 std::vector<std::string> urls_to_delete, hosts_to_delete; |
| 671 std::vector<std::string> url_redirects_to_delete, host_redirects_to_delete; | |
| 665 | 672 |
| 666 for (const auto& it : urls) { | 673 for (const auto& it : urls) { |
| 667 const std::string& url_spec = it.url().spec(); | 674 const std::string& url_spec = it.url().spec(); |
| 668 if (url_table_cache_->find(url_spec) != url_table_cache_->end()) { | 675 if (url_table_cache_->find(url_spec) != url_table_cache_->end()) { |
| 669 urls_to_delete.push_back(url_spec); | 676 urls_to_delete.push_back(url_spec); |
| 670 url_table_cache_->erase(url_spec); | 677 url_table_cache_->erase(url_spec); |
| 671 } | 678 } |
| 672 | 679 |
| 680 if (url_redirect_table_cache_->find(url_spec) != | |
| 681 url_redirect_table_cache_->end()) { | |
| 682 url_redirects_to_delete.push_back(url_spec); | |
| 683 url_redirect_table_cache_->erase(url_spec); | |
| 684 } | |
| 685 | |
| 673 const std::string& host = it.url().host(); | 686 const std::string& host = it.url().host(); |
| 674 if (host_table_cache_->find(host) != host_table_cache_->end()) { | 687 if (host_table_cache_->find(host) != host_table_cache_->end()) { |
| 675 hosts_to_delete.push_back(host); | 688 hosts_to_delete.push_back(host); |
| 676 host_table_cache_->erase(host); | 689 host_table_cache_->erase(host); |
| 677 } | 690 } |
| 691 | |
| 692 if (host_redirect_table_cache_->find(host) != | |
| 693 host_redirect_table_cache_->end()) { | |
| 694 host_redirects_to_delete.push_back(host); | |
| 695 host_redirect_table_cache_->erase(host); | |
| 696 } | |
| 678 } | 697 } |
| 679 | 698 |
| 680 if (!urls_to_delete.empty() || !hosts_to_delete.empty()) { | 699 if (!urls_to_delete.empty() || !hosts_to_delete.empty()) { |
| 681 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, | 700 BrowserThread::PostTask( |
| 682 base::Bind(&ResourcePrefetchPredictorTables::DeleteData, | 701 BrowserThread::DB, FROM_HERE, |
| 683 tables_, | 702 base::Bind(&ResourcePrefetchPredictorTables::DeleteResourceData, |
| 684 urls_to_delete, | 703 tables_, urls_to_delete, hosts_to_delete)); |
| 685 hosts_to_delete)); | 704 } |
| 705 | |
| 706 if (!url_redirects_to_delete.empty() || !host_redirects_to_delete.empty()) { | |
| 707 BrowserThread::PostTask( | |
| 708 BrowserThread::DB, FROM_HERE, | |
| 709 base::Bind(&ResourcePrefetchPredictorTables::DeleteRedirectData, | |
| 710 tables_, url_redirects_to_delete, host_redirects_to_delete)); | |
| 686 } | 711 } |
| 687 } | 712 } |
| 688 | 713 |
| 689 void ResourcePrefetchPredictor::RemoveOldestEntryInPrefetchDataMap( | 714 void ResourcePrefetchPredictor::RemoveOldestEntryInPrefetchDataMap( |
| 690 PrefetchKeyType key_type, | 715 PrefetchKeyType key_type, |
| 691 PrefetchDataMap* data_map) { | 716 PrefetchDataMap* data_map) { |
| 692 if (data_map->empty()) | 717 if (data_map->empty()) |
| 693 return; | 718 return; |
| 694 | 719 |
| 695 base::Time oldest_time; | 720 base::Time oldest_time; |
| 696 std::string key_to_delete; | 721 std::string key_to_delete; |
| 697 for (PrefetchDataMap::iterator it = data_map->begin(); | 722 for (PrefetchDataMap::iterator it = data_map->begin(); |
| 698 it != data_map->end(); ++it) { | 723 it != data_map->end(); ++it) { |
| 699 if (key_to_delete.empty() || it->second.last_visit < oldest_time) { | 724 if (key_to_delete.empty() || it->second.last_visit < oldest_time) { |
| 700 key_to_delete = it->first; | 725 key_to_delete = it->first; |
| 701 oldest_time = it->second.last_visit; | 726 oldest_time = it->second.last_visit; |
| 702 } | 727 } |
| 703 } | 728 } |
| 704 | 729 |
| 705 data_map->erase(key_to_delete); | 730 data_map->erase(key_to_delete); |
| 706 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, | 731 BrowserThread::PostTask( |
| 707 base::Bind(&ResourcePrefetchPredictorTables::DeleteSingleDataPoint, | 732 BrowserThread::DB, FROM_HERE, |
| 708 tables_, | 733 base::Bind( |
| 709 key_to_delete, | 734 &ResourcePrefetchPredictorTables::DeleteSingleResourceDataPoint, |
| 710 key_type)); | 735 tables_, key_to_delete, key_type)); |
| 736 } | |
| 737 | |
| 738 void ResourcePrefetchPredictor::RemoveOldestEntryInRedirectDataMap( | |
| 739 PrefetchKeyType key_type, | |
| 740 RedirectDataMap* data_map) { | |
| 741 if (data_map->empty()) | |
| 742 return; | |
| 743 | |
| 744 uint64_t oldest_time; | |
| 745 std::string key_to_delete; | |
| 746 for (const auto& kv : *data_map) { | |
| 747 const RedirectData& data = kv.second; | |
| 748 if (key_to_delete.empty() || data.last_visit_time() < oldest_time) { | |
| 749 key_to_delete = data.primary_key(); | |
| 750 oldest_time = data.last_visit_time(); | |
| 751 } | |
| 752 } | |
| 753 | |
| 754 data_map->erase(key_to_delete); | |
| 755 BrowserThread::PostTask( | |
| 756 BrowserThread::DB, FROM_HERE, | |
| 757 base::Bind( | |
| 758 &ResourcePrefetchPredictorTables::DeleteSingleRedirectDataPoint, | |
| 759 tables_, key_to_delete, key_type)); | |
| 711 } | 760 } |
| 712 | 761 |
| 713 void ResourcePrefetchPredictor::OnVisitCountLookup( | 762 void ResourcePrefetchPredictor::OnVisitCountLookup( |
| 714 size_t visit_count, | 763 size_t visit_count, |
| 715 const NavigationID& navigation_id, | 764 const NavigationID& navigation_id, |
| 716 const std::vector<URLRequestSummary>& requests) { | 765 const PageRequestSummary& summary) { |
| 717 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 766 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 718 | 767 |
| 719 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HistoryVisitCountForUrl", | 768 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HistoryVisitCountForUrl", |
| 720 visit_count); | 769 visit_count); |
| 721 | 770 |
| 722 // URL level data - merge only if we are already saving the data, or we it | 771 // TODO(alexilin) make only one request to DB thread. |
|
pasko
2016/09/27 16:21:27
TODO(alexilin):
alexilin
2016/09/27 18:11:08
Done.
| |
| 772 | |
| 773 // URL level data - merge only if we already saved the data, or it | |
| 723 // meets the cutoff requirement. | 774 // meets the cutoff requirement. |
| 724 const std::string url_spec = navigation_id.main_frame_url.spec(); | 775 const std::string url_spec = navigation_id.main_frame_url.spec(); |
| 725 bool already_tracking = url_table_cache_->find(url_spec) != | 776 bool already_tracking = url_table_cache_->find(url_spec) != |
| 726 url_table_cache_->end(); | 777 url_table_cache_->end(); |
| 727 bool should_track_url = already_tracking || | 778 bool should_track_url = already_tracking || |
| 728 (visit_count >= config_.min_url_visit_count); | 779 (visit_count >= config_.min_url_visit_count); |
| 729 | 780 |
| 730 if (should_track_url && config_.IsURLLearningEnabled()) { | 781 if (should_track_url && config_.IsURLLearningEnabled()) { |
| 731 LearnNavigation(url_spec, PREFETCH_KEY_TYPE_URL, requests, | 782 LearnNavigation(url_spec, PREFETCH_KEY_TYPE_URL, |
| 732 config_.max_urls_to_track, url_table_cache_.get()); | 783 summary.subresource_requests, config_.max_urls_to_track, |
| 784 url_table_cache_.get(), summary.initial_url.spec(), | |
| 785 url_redirect_table_cache_.get()); | |
| 733 } | 786 } |
| 734 | 787 |
| 735 // Host level data - no cutoff, always learn the navigation if enabled. | 788 // Host level data - no cutoff, always learn the navigation if enabled. |
| 736 if (config_.IsHostLearningEnabled()) { | 789 if (config_.IsHostLearningEnabled()) { |
| 737 LearnNavigation(navigation_id.main_frame_url.host(), | 790 const std::string host = navigation_id.main_frame_url.host(); |
| 738 PREFETCH_KEY_TYPE_HOST, | 791 LearnNavigation(host, PREFETCH_KEY_TYPE_HOST, summary.subresource_requests, |
| 739 requests, | 792 config_.max_hosts_to_track, host_table_cache_.get(), |
| 740 config_.max_hosts_to_track, | 793 summary.initial_url.host(), |
| 741 host_table_cache_.get()); | 794 host_redirect_table_cache_.get()); |
| 742 } | 795 } |
| 743 } | 796 } |
| 744 | 797 |
| 745 void ResourcePrefetchPredictor::LearnNavigation( | 798 void ResourcePrefetchPredictor::LearnNavigation( |
| 746 const std::string& key, | 799 const std::string& key, |
| 747 PrefetchKeyType key_type, | 800 PrefetchKeyType key_type, |
| 748 const std::vector<URLRequestSummary>& new_resources, | 801 const std::vector<URLRequestSummary>& new_resources, |
| 749 size_t max_data_map_size, | 802 size_t max_data_map_size, |
| 750 PrefetchDataMap* data_map) { | 803 PrefetchDataMap* data_map, |
| 804 const std::string& key_before_redirects, | |
| 805 RedirectDataMap* redirect_map) { | |
| 751 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 806 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 752 | 807 |
| 753 // If the primary key is too long reject it. | 808 // If the primary key is too long reject it. |
| 754 if (key.length() > ResourcePrefetchPredictorTables::kMaxStringLength) | 809 if (key.length() > ResourcePrefetchPredictorTables::kMaxStringLength) |
| 755 return; | 810 return; |
| 756 | 811 |
| 757 PrefetchDataMap::iterator cache_entry = data_map->find(key); | 812 PrefetchDataMap::iterator cache_entry = data_map->find(key); |
| 758 if (cache_entry == data_map->end()) { | 813 if (cache_entry == data_map->end()) { |
| 759 if (data_map->size() >= max_data_map_size) { | 814 // If the table is full, delete an entry. |
| 760 // The table is full, delete an entry. | 815 if (data_map->size() >= max_data_map_size) |
| 761 RemoveOldestEntryInPrefetchDataMap(key_type, data_map); | 816 RemoveOldestEntryInPrefetchDataMap(key_type, data_map); |
| 762 } | |
| 763 | 817 |
| 764 cache_entry = data_map->insert(std::make_pair( | 818 cache_entry = data_map->insert(std::make_pair( |
| 765 key, PrefetchData(key_type, key))).first; | 819 key, PrefetchData(key_type, key))).first; |
| 766 cache_entry->second.last_visit = base::Time::Now(); | 820 cache_entry->second.last_visit = base::Time::Now(); |
| 767 size_t new_resources_size = new_resources.size(); | 821 size_t new_resources_size = new_resources.size(); |
| 768 std::set<GURL> resources_seen; | 822 std::set<GURL> resources_seen; |
| 769 for (size_t i = 0; i < new_resources_size; ++i) { | 823 for (size_t i = 0; i < new_resources_size; ++i) { |
| 770 if (resources_seen.find(new_resources[i].resource_url) != | 824 if (resources_seen.find(new_resources[i].resource_url) != |
| 771 resources_seen.end()) { | 825 resources_seen.end()) { |
| 772 continue; | 826 continue; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 872 ResourcePrefetchPredictorTables::SortResources(&resources); | 926 ResourcePrefetchPredictorTables::SortResources(&resources); |
| 873 if (resources.size() > config_.max_resources_per_entry) | 927 if (resources.size() > config_.max_resources_per_entry) |
| 874 resources.resize(config_.max_resources_per_entry); | 928 resources.resize(config_.max_resources_per_entry); |
| 875 | 929 |
| 876 // If the row has no resources, remove it from the cache and delete the | 930 // If the row has no resources, remove it from the cache and delete the |
| 877 // entry in the database. Else update the database. | 931 // entry in the database. Else update the database. |
| 878 if (resources.empty()) { | 932 if (resources.empty()) { |
| 879 data_map->erase(key); | 933 data_map->erase(key); |
| 880 BrowserThread::PostTask( | 934 BrowserThread::PostTask( |
| 881 BrowserThread::DB, FROM_HERE, | 935 BrowserThread::DB, FROM_HERE, |
| 882 base::Bind(&ResourcePrefetchPredictorTables::DeleteSingleDataPoint, | 936 base::Bind( |
| 883 tables_, | 937 &ResourcePrefetchPredictorTables::DeleteSingleResourceDataPoint, |
| 884 key, | 938 tables_, key, key_type)); |
| 885 key_type)); | |
| 886 } else { | 939 } else { |
| 887 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; | 940 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; |
| 888 PrefetchData empty_data( | 941 PrefetchData empty_data( |
| 889 !is_host ? PREFETCH_KEY_TYPE_HOST : PREFETCH_KEY_TYPE_URL, | 942 !is_host ? PREFETCH_KEY_TYPE_HOST : PREFETCH_KEY_TYPE_URL, |
| 890 std::string()); | 943 std::string()); |
| 944 RedirectData empty_redirect_data; | |
| 891 const PrefetchData& host_data = is_host ? cache_entry->second : empty_data; | 945 const PrefetchData& host_data = is_host ? cache_entry->second : empty_data; |
| 892 const PrefetchData& url_data = is_host ? empty_data : cache_entry->second; | 946 const PrefetchData& url_data = is_host ? empty_data : cache_entry->second; |
| 893 BrowserThread::PostTask( | 947 BrowserThread::PostTask( |
| 894 BrowserThread::DB, FROM_HERE, | 948 BrowserThread::DB, FROM_HERE, |
| 895 base::Bind(&ResourcePrefetchPredictorTables::UpdateData, | 949 base::Bind(&ResourcePrefetchPredictorTables::UpdateData, tables_, |
| 896 tables_, | 950 url_data, host_data, empty_redirect_data, |
| 897 url_data, | 951 empty_redirect_data)); |
| 898 host_data)); | 952 } |
| 953 | |
| 954 if (key != key_before_redirects) { | |
| 955 LearnRedirect(key_before_redirects, key_type, key, max_data_map_size, | |
| 956 redirect_map); | |
| 899 } | 957 } |
| 900 } | 958 } |
| 901 | 959 |
| 960 void ResourcePrefetchPredictor::LearnRedirect(const std::string& key, | |
| 961 PrefetchKeyType key_type, | |
| 962 const std::string& final_redirect, | |
| 963 size_t max_redirect_map_size, | |
| 964 RedirectDataMap* redirect_map) { | |
| 965 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 966 | |
| 967 RedirectDataMap::iterator cache_entry = redirect_map->find(key); | |
| 968 if (cache_entry == redirect_map->end()) { | |
| 969 if (redirect_map->size() >= max_redirect_map_size) | |
| 970 RemoveOldestEntryInRedirectDataMap(key_type, redirect_map); | |
| 971 | |
| 972 RedirectData new_data; | |
| 973 new_data.set_primary_key(key); | |
| 974 cache_entry = redirect_map->insert(std::make_pair(key, new_data)).first; | |
| 975 cache_entry->second.set_last_visit_time( | |
| 976 base::Time::Now().ToInternalValue()); | |
| 977 RedirectStat* redirect_to_add = | |
| 978 cache_entry->second.add_redirect_endpoints(); | |
| 979 redirect_to_add->set_url(final_redirect); | |
| 980 redirect_to_add->set_number_of_hits(1); | |
| 981 } else { | |
| 982 bool need_to_add = true; | |
| 983 cache_entry->second.set_last_visit_time( | |
| 984 base::Time::Now().ToInternalValue()); | |
| 985 | |
| 986 for (RedirectStat& redirect : | |
| 987 *(cache_entry->second.mutable_redirect_endpoints())) { | |
| 988 if (redirect.url() == final_redirect) { | |
| 989 need_to_add = false; | |
| 990 redirect.set_number_of_hits(redirect.number_of_hits() + 1); | |
| 991 redirect.set_consecutive_misses(0); | |
| 992 } else { | |
| 993 redirect.set_number_of_misses(redirect.number_of_misses() + 1); | |
| 994 redirect.set_consecutive_misses(redirect.consecutive_misses() + 1); | |
| 995 } | |
| 996 } | |
| 997 | |
| 998 if (need_to_add) { | |
| 999 RedirectStat* redirect_to_add = | |
| 1000 cache_entry->second.add_redirect_endpoints(); | |
| 1001 redirect_to_add->set_url(final_redirect); | |
| 1002 redirect_to_add->set_number_of_hits(1); | |
| 1003 } | |
| 1004 } | |
| 1005 | |
| 1006 // Trim and sort redirects after update. | |
| 1007 std::vector<RedirectStat> redirects; | |
| 1008 redirects.reserve(cache_entry->second.redirect_endpoints_size()); | |
| 1009 for (const RedirectStat& redirect : | |
| 1010 cache_entry->second.redirect_endpoints()) { | |
| 1011 if (redirect.consecutive_misses() < config_.max_consecutive_misses) | |
| 1012 redirects.push_back(redirect); | |
| 1013 } | |
| 1014 ResourcePrefetchPredictorTables::SortRedirects(&redirects); | |
| 1015 | |
| 1016 if (redirects.size() > kMaxRedirectsPerEntry) | |
| 1017 redirects.resize(kMaxRedirectsPerEntry); | |
| 1018 | |
| 1019 cache_entry->second.clear_redirect_endpoints(); | |
| 1020 for (const RedirectStat& redirect : redirects) | |
| 1021 cache_entry->second.add_redirect_endpoints()->CopyFrom(redirect); | |
| 1022 | |
| 1023 if (redirects.empty()) { | |
| 1024 redirect_map->erase(cache_entry); | |
| 1025 BrowserThread::PostTask( | |
| 1026 BrowserThread::DB, FROM_HERE, | |
| 1027 base::Bind( | |
| 1028 &ResourcePrefetchPredictorTables::DeleteSingleRedirectDataPoint, | |
| 1029 tables_, key, key_type)); | |
| 1030 } else { | |
| 1031 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; | |
| 1032 RedirectData empty_redirect_data; | |
| 1033 PrefetchData empty_url_data(PREFETCH_KEY_TYPE_URL, std::string()); | |
| 1034 PrefetchData empty_host_data(PREFETCH_KEY_TYPE_HOST, std::string()); | |
| 1035 const RedirectData& host_redirect_data = | |
| 1036 is_host ? cache_entry->second : empty_redirect_data; | |
| 1037 const RedirectData& url_redirect_data = | |
| 1038 is_host ? empty_redirect_data : cache_entry->second; | |
| 1039 BrowserThread::PostTask( | |
| 1040 BrowserThread::DB, FROM_HERE, | |
| 1041 base::Bind(&ResourcePrefetchPredictorTables::UpdateData, tables_, | |
| 1042 empty_url_data, empty_host_data, url_redirect_data, | |
| 1043 host_redirect_data)); | |
| 1044 } | |
| 1045 } | |
| 1046 | |
| 902 void ResourcePrefetchPredictor::OnURLsDeleted( | 1047 void ResourcePrefetchPredictor::OnURLsDeleted( |
| 903 history::HistoryService* history_service, | 1048 history::HistoryService* history_service, |
| 904 bool all_history, | 1049 bool all_history, |
| 905 bool expired, | 1050 bool expired, |
| 906 const history::URLRows& deleted_rows, | 1051 const history::URLRows& deleted_rows, |
| 907 const std::set<GURL>& favicon_urls) { | 1052 const std::set<GURL>& favicon_urls) { |
| 908 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1053 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 909 if (INITIALIZED != initialization_state_) | 1054 if (INITIALIZED != initialization_state_) |
| 910 return; | 1055 return; |
| 911 | 1056 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 939 // HistoryService is already loaded. Continue with Initialization. | 1084 // HistoryService is already loaded. Continue with Initialization. |
| 940 OnHistoryAndCacheLoaded(); | 1085 OnHistoryAndCacheLoaded(); |
| 941 return; | 1086 return; |
| 942 } | 1087 } |
| 943 DCHECK(!history_service_observer_.IsObserving(history_service)); | 1088 DCHECK(!history_service_observer_.IsObserving(history_service)); |
| 944 history_service_observer_.Add(history_service); | 1089 history_service_observer_.Add(history_service); |
| 945 return; | 1090 return; |
| 946 } | 1091 } |
| 947 | 1092 |
| 948 } // namespace predictors | 1093 } // namespace predictors |
| OLD | NEW |