| 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 REPORTING_EVENT_ALL_HISTORY_CLEARED = 0, | 60 REPORTING_EVENT_ALL_HISTORY_CLEARED = 0, |
| 61 REPORTING_EVENT_PARTIAL_HISTORY_CLEARED = 1, | 61 REPORTING_EVENT_PARTIAL_HISTORY_CLEARED = 1, |
| 62 REPORTING_EVENT_COUNT = 2 | 62 REPORTING_EVENT_COUNT = 2 |
| 63 }; | 63 }; |
| 64 | 64 |
| 65 float ComputeRedirectConfidence(const predictors::RedirectStat& redirect) { | 65 float ComputeRedirectConfidence(const predictors::RedirectStat& redirect) { |
| 66 return (redirect.number_of_hits() + 0.0) / | 66 return (redirect.number_of_hits() + 0.0) / |
| 67 (redirect.number_of_hits() + redirect.number_of_misses()); | 67 (redirect.number_of_hits() + redirect.number_of_misses()); |
| 68 } | 68 } |
| 69 | 69 |
| 70 void UpdateOrAddToOrigins( |
| 71 std::map<GURL, ResourcePrefetchPredictor::OriginRequestSummary>* summaries, |
| 72 const ResourcePrefetchPredictor::URLRequestSummary& request_summary) { |
| 73 DCHECK(request_summary.resource_url.is_valid()); |
| 74 if (!request_summary.resource_url.is_valid()) |
| 75 return; |
| 76 |
| 77 GURL origin = request_summary.resource_url.GetOrigin(); |
| 78 auto it = summaries->find(origin); |
| 79 if (it == summaries->end()) { |
| 80 ResourcePrefetchPredictor::OriginRequestSummary summary; |
| 81 summary.origin = origin; |
| 82 summary.first_occurrence = summaries->size(); |
| 83 it = summaries->insert({origin, summary}).first; |
| 84 } |
| 85 |
| 86 it->second.always_access_network |= |
| 87 request_summary.always_revalidate || request_summary.is_no_store; |
| 88 it->second.accessed_network |= request_summary.network_accessed; |
| 89 } |
| 90 |
| 91 void InitializeOriginStatFromOriginRequestSummary( |
| 92 OriginStat* origin, |
| 93 const ResourcePrefetchPredictor::OriginRequestSummary& summary) { |
| 94 origin->set_origin(summary.origin.spec()); |
| 95 origin->set_number_of_hits(1); |
| 96 origin->set_average_position(summary.first_occurrence + 1); |
| 97 origin->set_always_access_network(summary.always_access_network); |
| 98 origin->set_accessed_network(summary.accessed_network); |
| 99 } |
| 100 |
| 70 // Used to fetch the visit count for a URL from the History database. | 101 // Used to fetch the visit count for a URL from the History database. |
| 71 class GetUrlVisitCountTask : public history::HistoryDBTask { | 102 class GetUrlVisitCountTask : public history::HistoryDBTask { |
| 72 public: | 103 public: |
| 73 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary; | 104 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary; |
| 74 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; | 105 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; |
| 75 typedef base::Callback<void(size_t, // URL visit count. | 106 typedef base::Callback<void(size_t, // URL visit count. |
| 76 const PageRequestSummary&)> | 107 const PageRequestSummary&)> |
| 77 VisitInfoCallback; | 108 VisitInfoCallback; |
| 78 | 109 |
| 79 GetUrlVisitCountTask(std::unique_ptr<PageRequestSummary> summary, | 110 GetUrlVisitCountTask(std::unique_ptr<PageRequestSummary> summary, |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 | 302 |
| 272 content::ResourceType resource_type = request_info->GetResourceType(); | 303 content::ResourceType resource_type = request_info->GetResourceType(); |
| 273 return resource_type == content::RESOURCE_TYPE_MAIN_FRAME | 304 return resource_type == content::RESOURCE_TYPE_MAIN_FRAME |
| 274 ? IsHandledMainPage(response) | 305 ? IsHandledMainPage(response) |
| 275 : IsHandledSubresource(response, resource_type); | 306 : IsHandledSubresource(response, resource_type); |
| 276 } | 307 } |
| 277 | 308 |
| 278 // static | 309 // static |
| 279 bool ResourcePrefetchPredictor::ShouldRecordRedirect( | 310 bool ResourcePrefetchPredictor::ShouldRecordRedirect( |
| 280 net::URLRequest* response) { | 311 net::URLRequest* response) { |
| 281 const content::ResourceRequestInfo* request_info = | 312 return ShouldRecordResponse(response); |
| 282 content::ResourceRequestInfo::ForRequest(response); | |
| 283 if (!request_info) | |
| 284 return false; | |
| 285 | |
| 286 if (!request_info->IsMainFrame()) | |
| 287 return false; | |
| 288 | |
| 289 return request_info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME && | |
| 290 IsHandledMainPage(response); | |
| 291 } | 313 } |
| 292 | 314 |
| 293 // static | 315 // static |
| 294 bool ResourcePrefetchPredictor::IsHandledMainPage(net::URLRequest* request) { | 316 bool ResourcePrefetchPredictor::IsHandledMainPage(net::URLRequest* request) { |
| 295 const GURL& url = request->url(); | 317 const GURL& url = request->url(); |
| 296 bool bad_port = !g_allow_port_in_urls && url.has_port(); | 318 bool bad_port = !g_allow_port_in_urls && url.has_port(); |
| 297 return url.SchemeIsHTTPOrHTTPS() && !bad_port; | 319 return url.SchemeIsHTTPOrHTTPS() && !bad_port; |
| 298 } | 320 } |
| 299 | 321 |
| 300 // static | 322 // static |
| (...skipping 13 matching lines...) Expand all Loading... |
| 314 return false; | 336 return false; |
| 315 | 337 |
| 316 if (response->method() != "GET") | 338 if (response->method() != "GET") |
| 317 return false; | 339 return false; |
| 318 | 340 |
| 319 if (response->original_url().spec().length() > | 341 if (response->original_url().spec().length() > |
| 320 ResourcePrefetchPredictorTables::kMaxStringLength) { | 342 ResourcePrefetchPredictorTables::kMaxStringLength) { |
| 321 return false; | 343 return false; |
| 322 } | 344 } |
| 323 | 345 |
| 324 if (!response->response_info().headers.get() || IsNoStore(response)) | 346 if (!response->response_info().headers.get()) |
| 325 return false; | 347 return false; |
| 326 | 348 |
| 327 return true; | 349 return true; |
| 328 } | 350 } |
| 329 | 351 |
| 330 // static | 352 // static |
| 331 bool ResourcePrefetchPredictor::IsHandledResourceType( | 353 bool ResourcePrefetchPredictor::IsHandledResourceType( |
| 332 content::ResourceType resource_type, | 354 content::ResourceType resource_type, |
| 333 const std::string& mime_type) { | 355 const std::string& mime_type) { |
| 334 content::ResourceType actual_resource_type = | 356 content::ResourceType actual_resource_type = |
| (...skipping 14 matching lines...) Expand all Loading... |
| 349 if (resource_type == content::RESOURCE_TYPE_PREFETCH || | 371 if (resource_type == content::RESOURCE_TYPE_PREFETCH || |
| 350 resource_type == content::RESOURCE_TYPE_SUB_RESOURCE || | 372 resource_type == content::RESOURCE_TYPE_SUB_RESOURCE || |
| 351 resource_type == content::RESOURCE_TYPE_XHR) { | 373 resource_type == content::RESOURCE_TYPE_XHR) { |
| 352 return GetResourceTypeFromMimeType(mime_type, | 374 return GetResourceTypeFromMimeType(mime_type, |
| 353 content::RESOURCE_TYPE_LAST_TYPE); | 375 content::RESOURCE_TYPE_LAST_TYPE); |
| 354 } | 376 } |
| 355 return resource_type; | 377 return resource_type; |
| 356 } | 378 } |
| 357 | 379 |
| 358 // static | 380 // static |
| 359 bool ResourcePrefetchPredictor::IsNoStore(const net::URLRequest* response) { | 381 bool ResourcePrefetchPredictor::IsNoStore(const net::URLRequest& response) { |
| 360 if (response->was_cached()) | 382 if (response.was_cached()) |
| 361 return false; | 383 return false; |
| 362 | 384 |
| 363 const net::HttpResponseInfo& response_info = response->response_info(); | 385 const net::HttpResponseInfo& response_info = response.response_info(); |
| 364 if (!response_info.headers.get()) | 386 if (!response_info.headers.get()) |
| 365 return false; | 387 return false; |
| 366 return response_info.headers->HasHeaderValue("cache-control", "no-store"); | 388 return response_info.headers->HasHeaderValue("cache-control", "no-store"); |
| 367 } | 389 } |
| 368 | 390 |
| 369 // static | 391 // static |
| 370 content::ResourceType ResourcePrefetchPredictor::GetResourceTypeFromMimeType( | 392 content::ResourceType ResourcePrefetchPredictor::GetResourceTypeFromMimeType( |
| 371 const std::string& mime_type, | 393 const std::string& mime_type, |
| 372 content::ResourceType fallback) { | 394 content::ResourceType fallback) { |
| 373 if (mime_type.empty()) { | 395 if (mime_type.empty()) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 } | 445 } |
| 424 | 446 |
| 425 // static | 447 // static |
| 426 void ResourcePrefetchPredictor::SetAllowPortInUrlsForTesting(bool state) { | 448 void ResourcePrefetchPredictor::SetAllowPortInUrlsForTesting(bool state) { |
| 427 g_allow_port_in_urls = state; | 449 g_allow_port_in_urls = state; |
| 428 } | 450 } |
| 429 | 451 |
| 430 //////////////////////////////////////////////////////////////////////////////// | 452 //////////////////////////////////////////////////////////////////////////////// |
| 431 // ResourcePrefetchPredictor nested types. | 453 // ResourcePrefetchPredictor nested types. |
| 432 | 454 |
| 455 ResourcePrefetchPredictor::OriginRequestSummary::OriginRequestSummary() |
| 456 : origin(), |
| 457 always_access_network(false), |
| 458 accessed_network(false), |
| 459 first_occurrence(0) {} |
| 460 |
| 461 ResourcePrefetchPredictor::OriginRequestSummary::OriginRequestSummary( |
| 462 const OriginRequestSummary& other) = default; |
| 463 |
| 464 ResourcePrefetchPredictor::OriginRequestSummary::~OriginRequestSummary() {} |
| 465 |
| 433 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary() | 466 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary() |
| 434 : resource_type(content::RESOURCE_TYPE_LAST_TYPE), | 467 : resource_type(content::RESOURCE_TYPE_LAST_TYPE), |
| 435 priority(net::IDLE), | 468 priority(net::IDLE), |
| 436 was_cached(false), | 469 was_cached(false), |
| 437 has_validators(false), | 470 has_validators(false), |
| 438 always_revalidate(false) {} | 471 always_revalidate(false), |
| 472 is_no_store(false), |
| 473 network_accessed(false) {} |
| 439 | 474 |
| 440 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary( | 475 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary( |
| 441 const URLRequestSummary& other) | 476 const URLRequestSummary& other) = default; |
| 442 : navigation_id(other.navigation_id), | |
| 443 resource_url(other.resource_url), | |
| 444 resource_type(other.resource_type), | |
| 445 priority(other.priority), | |
| 446 mime_type(other.mime_type), | |
| 447 was_cached(other.was_cached), | |
| 448 redirect_url(other.redirect_url), | |
| 449 has_validators(other.has_validators), | |
| 450 always_revalidate(other.always_revalidate) {} | |
| 451 | 477 |
| 452 ResourcePrefetchPredictor::URLRequestSummary::~URLRequestSummary() { | 478 ResourcePrefetchPredictor::URLRequestSummary::~URLRequestSummary() { |
| 453 } | 479 } |
| 454 | 480 |
| 455 // static | 481 // static |
| 456 bool ResourcePrefetchPredictor::URLRequestSummary::SummarizeResponse( | 482 bool ResourcePrefetchPredictor::URLRequestSummary::SummarizeResponse( |
| 457 const net::URLRequest& request, | 483 const net::URLRequest& request, |
| 458 URLRequestSummary* summary) { | 484 URLRequestSummary* summary) { |
| 459 const content::ResourceRequestInfo* request_info = | 485 const content::ResourceRequestInfo* request_info = |
| 460 content::ResourceRequestInfo::ForRequest(&request); | 486 content::ResourceRequestInfo::ForRequest(&request); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 472 | 498 |
| 473 scoped_refptr<net::HttpResponseHeaders> headers = | 499 scoped_refptr<net::HttpResponseHeaders> headers = |
| 474 request.response_info().headers; | 500 request.response_info().headers; |
| 475 if (headers.get()) { | 501 if (headers.get()) { |
| 476 summary->has_validators = headers->HasValidators(); | 502 summary->has_validators = headers->HasValidators(); |
| 477 // RFC 2616, section 14.9. | 503 // RFC 2616, section 14.9. |
| 478 summary->always_revalidate = | 504 summary->always_revalidate = |
| 479 headers->HasHeaderValue("cache-control", "no-cache") || | 505 headers->HasHeaderValue("cache-control", "no-cache") || |
| 480 headers->HasHeaderValue("pragma", "no-cache") || | 506 headers->HasHeaderValue("pragma", "no-cache") || |
| 481 headers->HasHeaderValue("vary", "*"); | 507 headers->HasHeaderValue("vary", "*"); |
| 508 summary->is_no_store = IsNoStore(request); |
| 482 } | 509 } |
| 510 summary->network_accessed = request.response_info().network_accessed; |
| 483 return true; | 511 return true; |
| 484 } | 512 } |
| 485 | 513 |
| 486 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( | 514 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( |
| 487 const GURL& i_main_frame_url) | 515 const GURL& i_main_frame_url) |
| 488 : main_frame_url(i_main_frame_url), initial_url(i_main_frame_url) {} | 516 : main_frame_url(i_main_frame_url), initial_url(i_main_frame_url) {} |
| 489 | 517 |
| 490 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( | 518 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( |
| 491 const PageRequestSummary& other) = default; | 519 const PageRequestSummary& other) = default; |
| 492 | 520 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 if (initialization_state_ != NOT_INITIALIZED) | 555 if (initialization_state_ != NOT_INITIALIZED) |
| 528 return; | 556 return; |
| 529 initialization_state_ = INITIALIZING; | 557 initialization_state_ = INITIALIZING; |
| 530 | 558 |
| 531 // Create local caches using the database as loaded. | 559 // Create local caches using the database as loaded. |
| 532 auto url_data_map = base::MakeUnique<PrefetchDataMap>(); | 560 auto url_data_map = base::MakeUnique<PrefetchDataMap>(); |
| 533 auto host_data_map = base::MakeUnique<PrefetchDataMap>(); | 561 auto host_data_map = base::MakeUnique<PrefetchDataMap>(); |
| 534 auto url_redirect_data_map = base::MakeUnique<RedirectDataMap>(); | 562 auto url_redirect_data_map = base::MakeUnique<RedirectDataMap>(); |
| 535 auto host_redirect_data_map = base::MakeUnique<RedirectDataMap>(); | 563 auto host_redirect_data_map = base::MakeUnique<RedirectDataMap>(); |
| 536 auto manifest_data_map = base::MakeUnique<ManifestDataMap>(); | 564 auto manifest_data_map = base::MakeUnique<ManifestDataMap>(); |
| 565 auto origin_data_map = base::MakeUnique<OriginDataMap>(); |
| 537 | 566 |
| 538 // Get raw pointers to pass to the first task. Ownership of the unique_ptrs | 567 // Get raw pointers to pass to the first task. Ownership of the unique_ptrs |
| 539 // will be passed to the reply task. | 568 // will be passed to the reply task. |
| 540 auto* url_data_map_ptr = url_data_map.get(); | 569 auto* url_data_map_ptr = url_data_map.get(); |
| 541 auto* host_data_map_ptr = host_data_map.get(); | 570 auto* host_data_map_ptr = host_data_map.get(); |
| 542 auto* url_redirect_data_map_ptr = url_redirect_data_map.get(); | 571 auto* url_redirect_data_map_ptr = url_redirect_data_map.get(); |
| 543 auto* host_redirect_data_map_ptr = host_redirect_data_map.get(); | 572 auto* host_redirect_data_map_ptr = host_redirect_data_map.get(); |
| 544 auto* manifest_data_map_ptr = manifest_data_map.get(); | 573 auto* manifest_data_map_ptr = manifest_data_map.get(); |
| 574 auto* origin_data_map_ptr = origin_data_map.get(); |
| 545 | 575 |
| 546 BrowserThread::PostTaskAndReply( | 576 BrowserThread::PostTaskAndReply( |
| 547 BrowserThread::DB, FROM_HERE, | 577 BrowserThread::DB, FROM_HERE, |
| 548 base::Bind(&ResourcePrefetchPredictorTables::GetAllData, tables_, | 578 base::Bind(&ResourcePrefetchPredictorTables::GetAllData, tables_, |
| 549 url_data_map_ptr, host_data_map_ptr, url_redirect_data_map_ptr, | 579 url_data_map_ptr, host_data_map_ptr, url_redirect_data_map_ptr, |
| 550 host_redirect_data_map_ptr, manifest_data_map_ptr), | 580 host_redirect_data_map_ptr, manifest_data_map_ptr, |
| 581 origin_data_map_ptr), |
| 551 base::Bind(&ResourcePrefetchPredictor::CreateCaches, AsWeakPtr(), | 582 base::Bind(&ResourcePrefetchPredictor::CreateCaches, AsWeakPtr(), |
| 552 base::Passed(&url_data_map), base::Passed(&host_data_map), | 583 base::Passed(&url_data_map), base::Passed(&host_data_map), |
| 553 base::Passed(&url_redirect_data_map), | 584 base::Passed(&url_redirect_data_map), |
| 554 base::Passed(&host_redirect_data_map), | 585 base::Passed(&host_redirect_data_map), |
| 555 base::Passed(&manifest_data_map))); | 586 base::Passed(&manifest_data_map), |
| 587 base::Passed(&origin_data_map))); |
| 556 } | 588 } |
| 557 | 589 |
| 558 void ResourcePrefetchPredictor::RecordURLRequest( | 590 void ResourcePrefetchPredictor::RecordURLRequest( |
| 559 const URLRequestSummary& request) { | 591 const URLRequestSummary& request) { |
| 560 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 592 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 561 if (initialization_state_ != INITIALIZED) | 593 if (initialization_state_ != INITIALIZED) |
| 562 return; | 594 return; |
| 563 | 595 |
| 564 CHECK_EQ(request.resource_type, content::RESOURCE_TYPE_MAIN_FRAME); | 596 CHECK_EQ(request.resource_type, content::RESOURCE_TYPE_MAIN_FRAME); |
| 565 OnMainFrameRequest(request); | 597 OnMainFrameRequest(request); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 576 else | 608 else |
| 577 OnSubresourceResponse(response); | 609 OnSubresourceResponse(response); |
| 578 } | 610 } |
| 579 | 611 |
| 580 void ResourcePrefetchPredictor::RecordURLRedirect( | 612 void ResourcePrefetchPredictor::RecordURLRedirect( |
| 581 const URLRequestSummary& response) { | 613 const URLRequestSummary& response) { |
| 582 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 614 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 583 if (initialization_state_ != INITIALIZED) | 615 if (initialization_state_ != INITIALIZED) |
| 584 return; | 616 return; |
| 585 | 617 |
| 586 CHECK_EQ(response.resource_type, content::RESOURCE_TYPE_MAIN_FRAME); | 618 if (response.resource_type == content::RESOURCE_TYPE_MAIN_FRAME) |
| 587 OnMainFrameRedirect(response); | 619 OnMainFrameRedirect(response); |
| 620 else |
| 621 OnSubresourceRedirect(response); |
| 588 } | 622 } |
| 589 | 623 |
| 590 void ResourcePrefetchPredictor::RecordMainFrameLoadComplete( | 624 void ResourcePrefetchPredictor::RecordMainFrameLoadComplete( |
| 591 const NavigationID& navigation_id) { | 625 const NavigationID& navigation_id) { |
| 592 switch (initialization_state_) { | 626 switch (initialization_state_) { |
| 593 case NOT_INITIALIZED: | 627 case NOT_INITIALIZED: |
| 594 StartInitialization(); | 628 StartInitialization(); |
| 595 break; | 629 break; |
| 596 case INITIALIZING: | 630 case INITIALIZING: |
| 597 break; | 631 break; |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 757 inflight_navigations_.insert( | 791 inflight_navigations_.insert( |
| 758 std::make_pair(navigation_id, std::move(summary))); | 792 std::make_pair(navigation_id, std::move(summary))); |
| 759 } | 793 } |
| 760 | 794 |
| 761 void ResourcePrefetchPredictor::OnSubresourceResponse( | 795 void ResourcePrefetchPredictor::OnSubresourceResponse( |
| 762 const URLRequestSummary& response) { | 796 const URLRequestSummary& response) { |
| 763 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 797 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 764 DCHECK_EQ(INITIALIZED, initialization_state_); | 798 DCHECK_EQ(INITIALIZED, initialization_state_); |
| 765 | 799 |
| 766 NavigationMap::const_iterator nav_it = | 800 NavigationMap::const_iterator nav_it = |
| 767 inflight_navigations_.find(response.navigation_id); | 801 inflight_navigations_.find(response.navigation_id); |
| 768 if (nav_it == inflight_navigations_.end()) { | 802 if (nav_it == inflight_navigations_.end()) |
| 769 return; | 803 return; |
| 770 } | 804 auto& page_request_summary = *nav_it->second; |
| 771 | 805 |
| 772 nav_it->second->subresource_requests.push_back(response); | 806 if (!response.is_no_store) |
| 807 page_request_summary.subresource_requests.push_back(response); |
| 808 |
| 809 if (config_.is_origin_prediction_enabled) |
| 810 UpdateOrAddToOrigins(&page_request_summary.origins, response); |
| 811 } |
| 812 |
| 813 void ResourcePrefetchPredictor::OnSubresourceRedirect( |
| 814 const URLRequestSummary& response) { |
| 815 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 816 DCHECK_EQ(INITIALIZED, initialization_state_); |
| 817 |
| 818 if (!config_.is_origin_prediction_enabled) |
| 819 return; |
| 820 |
| 821 NavigationMap::const_iterator nav_it = |
| 822 inflight_navigations_.find(response.navigation_id); |
| 823 if (nav_it == inflight_navigations_.end()) |
| 824 return; |
| 825 auto& page_request_summary = *nav_it->second; |
| 826 UpdateOrAddToOrigins(&page_request_summary.origins, response); |
| 773 } | 827 } |
| 774 | 828 |
| 775 void ResourcePrefetchPredictor::OnNavigationComplete( | 829 void ResourcePrefetchPredictor::OnNavigationComplete( |
| 776 const NavigationID& nav_id_without_timing_info) { | 830 const NavigationID& nav_id_without_timing_info) { |
| 777 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 831 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 778 DCHECK_EQ(INITIALIZED, initialization_state_); | 832 DCHECK_EQ(INITIALIZED, initialization_state_); |
| 779 | 833 |
| 780 NavigationMap::iterator nav_it = | 834 NavigationMap::iterator nav_it = |
| 781 inflight_navigations_.find(nav_id_without_timing_info); | 835 inflight_navigations_.find(nav_id_without_timing_info); |
| 782 if (nav_it == inflight_navigations_.end()) | 836 if (nav_it == inflight_navigations_.end()) |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 896 } | 950 } |
| 897 | 951 |
| 898 return has_prefetchable_resource; | 952 return has_prefetchable_resource; |
| 899 } | 953 } |
| 900 | 954 |
| 901 void ResourcePrefetchPredictor::CreateCaches( | 955 void ResourcePrefetchPredictor::CreateCaches( |
| 902 std::unique_ptr<PrefetchDataMap> url_data_map, | 956 std::unique_ptr<PrefetchDataMap> url_data_map, |
| 903 std::unique_ptr<PrefetchDataMap> host_data_map, | 957 std::unique_ptr<PrefetchDataMap> host_data_map, |
| 904 std::unique_ptr<RedirectDataMap> url_redirect_data_map, | 958 std::unique_ptr<RedirectDataMap> url_redirect_data_map, |
| 905 std::unique_ptr<RedirectDataMap> host_redirect_data_map, | 959 std::unique_ptr<RedirectDataMap> host_redirect_data_map, |
| 906 std::unique_ptr<ManifestDataMap> manifest_data_map) { | 960 std::unique_ptr<ManifestDataMap> manifest_data_map, |
| 961 std::unique_ptr<OriginDataMap> origin_data_map) { |
| 907 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 962 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 908 | 963 |
| 909 DCHECK_EQ(INITIALIZING, initialization_state_); | 964 DCHECK_EQ(INITIALIZING, initialization_state_); |
| 910 DCHECK(!url_table_cache_); | 965 DCHECK(!url_table_cache_); |
| 911 DCHECK(!host_table_cache_); | 966 DCHECK(!host_table_cache_); |
| 912 DCHECK(!url_redirect_table_cache_); | 967 DCHECK(!url_redirect_table_cache_); |
| 913 DCHECK(!host_redirect_table_cache_); | 968 DCHECK(!host_redirect_table_cache_); |
| 914 DCHECK(!manifest_table_cache_); | 969 DCHECK(!manifest_table_cache_); |
| 970 DCHECK(!origin_table_cache_); |
| 971 |
| 915 DCHECK(inflight_navigations_.empty()); | 972 DCHECK(inflight_navigations_.empty()); |
| 916 | 973 |
| 917 url_table_cache_ = std::move(url_data_map); | 974 url_table_cache_ = std::move(url_data_map); |
| 918 host_table_cache_ = std::move(host_data_map); | 975 host_table_cache_ = std::move(host_data_map); |
| 919 url_redirect_table_cache_ = std::move(url_redirect_data_map); | 976 url_redirect_table_cache_ = std::move(url_redirect_data_map); |
| 920 host_redirect_table_cache_ = std::move(host_redirect_data_map); | 977 host_redirect_table_cache_ = std::move(host_redirect_data_map); |
| 921 manifest_table_cache_ = std::move(manifest_data_map); | 978 manifest_table_cache_ = std::move(manifest_data_map); |
| 979 origin_table_cache_ = std::move(origin_data_map); |
| 922 | 980 |
| 923 ConnectToHistoryService(); | 981 ConnectToHistoryService(); |
| 924 } | 982 } |
| 925 | 983 |
| 926 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() { | 984 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() { |
| 927 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 985 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 928 DCHECK_EQ(INITIALIZING, initialization_state_); | 986 DCHECK_EQ(INITIALIZING, initialization_state_); |
| 929 | 987 |
| 930 // Initialize the prefetch manager only if prefetching is enabled. | 988 // Initialize the prefetch manager only if prefetching is enabled. |
| 931 if (config_.IsPrefetchingEnabledForSomeOrigin(profile_)) { | 989 if (config_.IsPrefetchingEnabledForSomeOrigin(profile_)) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 } | 1040 } |
| 983 } | 1041 } |
| 984 | 1042 |
| 985 void ResourcePrefetchPredictor::DeleteAllUrls() { | 1043 void ResourcePrefetchPredictor::DeleteAllUrls() { |
| 986 inflight_navigations_.clear(); | 1044 inflight_navigations_.clear(); |
| 987 url_table_cache_->clear(); | 1045 url_table_cache_->clear(); |
| 988 host_table_cache_->clear(); | 1046 host_table_cache_->clear(); |
| 989 url_redirect_table_cache_->clear(); | 1047 url_redirect_table_cache_->clear(); |
| 990 host_redirect_table_cache_->clear(); | 1048 host_redirect_table_cache_->clear(); |
| 991 manifest_table_cache_->clear(); | 1049 manifest_table_cache_->clear(); |
| 1050 origin_table_cache_->clear(); |
| 992 | 1051 |
| 993 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, | 1052 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, |
| 994 base::Bind(&ResourcePrefetchPredictorTables::DeleteAllData, tables_)); | 1053 base::Bind(&ResourcePrefetchPredictorTables::DeleteAllData, tables_)); |
| 995 } | 1054 } |
| 996 | 1055 |
| 997 void ResourcePrefetchPredictor::DeleteUrls(const history::URLRows& urls) { | 1056 void ResourcePrefetchPredictor::DeleteUrls(const history::URLRows& urls) { |
| 998 // Check all the urls in the database and pick out the ones that are present | 1057 // Check all the urls in the database and pick out the ones that are present |
| 999 // in the cache. | 1058 // in the cache. |
| 1000 std::vector<std::string> urls_to_delete, hosts_to_delete; | 1059 std::vector<std::string> urls_to_delete, hosts_to_delete; |
| 1001 std::vector<std::string> url_redirects_to_delete, host_redirects_to_delete; | 1060 std::vector<std::string> url_redirects_to_delete, host_redirects_to_delete; |
| 1002 std::vector<std::string> manifest_hosts_to_delete; | 1061 std::vector<std::string> manifest_hosts_to_delete; |
| 1062 std::vector<std::string> origin_hosts_to_delete; |
| 1003 | 1063 |
| 1004 for (const auto& it : urls) { | 1064 for (const auto& it : urls) { |
| 1005 const std::string& url_spec = it.url().spec(); | 1065 const std::string& url_spec = it.url().spec(); |
| 1006 if (url_table_cache_->find(url_spec) != url_table_cache_->end()) { | 1066 if (url_table_cache_->find(url_spec) != url_table_cache_->end()) { |
| 1007 urls_to_delete.push_back(url_spec); | 1067 urls_to_delete.push_back(url_spec); |
| 1008 url_table_cache_->erase(url_spec); | 1068 url_table_cache_->erase(url_spec); |
| 1009 } | 1069 } |
| 1010 | 1070 |
| 1011 if (url_redirect_table_cache_->find(url_spec) != | 1071 if (url_redirect_table_cache_->find(url_spec) != |
| 1012 url_redirect_table_cache_->end()) { | 1072 url_redirect_table_cache_->end()) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1025 host_redirects_to_delete.push_back(host); | 1085 host_redirects_to_delete.push_back(host); |
| 1026 host_redirect_table_cache_->erase(host); | 1086 host_redirect_table_cache_->erase(host); |
| 1027 } | 1087 } |
| 1028 | 1088 |
| 1029 std::string manifest_host = history::HostForTopHosts(it.url()); | 1089 std::string manifest_host = history::HostForTopHosts(it.url()); |
| 1030 if (manifest_table_cache_->find(manifest_host) != | 1090 if (manifest_table_cache_->find(manifest_host) != |
| 1031 manifest_table_cache_->end()) { | 1091 manifest_table_cache_->end()) { |
| 1032 manifest_hosts_to_delete.push_back(manifest_host); | 1092 manifest_hosts_to_delete.push_back(manifest_host); |
| 1033 manifest_table_cache_->erase(manifest_host); | 1093 manifest_table_cache_->erase(manifest_host); |
| 1034 } | 1094 } |
| 1095 |
| 1096 if (origin_table_cache_->find(host) != origin_table_cache_->end()) { |
| 1097 origin_hosts_to_delete.push_back(host); |
| 1098 origin_table_cache_->erase(host); |
| 1099 } |
| 1035 } | 1100 } |
| 1036 | 1101 |
| 1037 if (!urls_to_delete.empty() || !hosts_to_delete.empty()) { | 1102 if (!urls_to_delete.empty() || !hosts_to_delete.empty()) { |
| 1038 BrowserThread::PostTask( | 1103 BrowserThread::PostTask( |
| 1039 BrowserThread::DB, FROM_HERE, | 1104 BrowserThread::DB, FROM_HERE, |
| 1040 base::Bind(&ResourcePrefetchPredictorTables::DeleteResourceData, | 1105 base::Bind(&ResourcePrefetchPredictorTables::DeleteResourceData, |
| 1041 tables_, urls_to_delete, hosts_to_delete)); | 1106 tables_, urls_to_delete, hosts_to_delete)); |
| 1042 } | 1107 } |
| 1043 | 1108 |
| 1044 if (!url_redirects_to_delete.empty() || !host_redirects_to_delete.empty()) { | 1109 if (!url_redirects_to_delete.empty() || !host_redirects_to_delete.empty()) { |
| 1045 BrowserThread::PostTask( | 1110 BrowserThread::PostTask( |
| 1046 BrowserThread::DB, FROM_HERE, | 1111 BrowserThread::DB, FROM_HERE, |
| 1047 base::Bind(&ResourcePrefetchPredictorTables::DeleteRedirectData, | 1112 base::Bind(&ResourcePrefetchPredictorTables::DeleteRedirectData, |
| 1048 tables_, url_redirects_to_delete, host_redirects_to_delete)); | 1113 tables_, url_redirects_to_delete, host_redirects_to_delete)); |
| 1049 } | 1114 } |
| 1050 | 1115 |
| 1051 if (!manifest_hosts_to_delete.empty()) { | 1116 if (!manifest_hosts_to_delete.empty()) { |
| 1052 BrowserThread::PostTask( | 1117 BrowserThread::PostTask( |
| 1053 BrowserThread::DB, FROM_HERE, | 1118 BrowserThread::DB, FROM_HERE, |
| 1054 base::Bind(&ResourcePrefetchPredictorTables::DeleteManifestData, | 1119 base::Bind(&ResourcePrefetchPredictorTables::DeleteManifestData, |
| 1055 tables_, manifest_hosts_to_delete)); | 1120 tables_, manifest_hosts_to_delete)); |
| 1056 } | 1121 } |
| 1122 |
| 1123 if (!origin_hosts_to_delete.empty()) { |
| 1124 BrowserThread::PostTask( |
| 1125 BrowserThread::DB, FROM_HERE, |
| 1126 base::Bind(&ResourcePrefetchPredictorTables::DeleteOriginData, tables_, |
| 1127 origin_hosts_to_delete)); |
| 1128 } |
| 1057 } | 1129 } |
| 1058 | 1130 |
| 1059 void ResourcePrefetchPredictor::RemoveOldestEntryInPrefetchDataMap( | 1131 void ResourcePrefetchPredictor::RemoveOldestEntryInPrefetchDataMap( |
| 1060 PrefetchKeyType key_type, | 1132 PrefetchKeyType key_type, |
| 1061 PrefetchDataMap* data_map) { | 1133 PrefetchDataMap* data_map) { |
| 1062 if (data_map->empty()) | 1134 if (data_map->empty()) |
| 1063 return; | 1135 return; |
| 1064 | 1136 |
| 1065 uint64_t oldest_time = UINT64_MAX; | 1137 uint64_t oldest_time = UINT64_MAX; |
| 1066 std::string key_to_delete; | 1138 std::string key_to_delete; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1117 }); | 1189 }); |
| 1118 | 1190 |
| 1119 std::string key_to_delete = oldest_entry->first; | 1191 std::string key_to_delete = oldest_entry->first; |
| 1120 data_map->erase(oldest_entry); | 1192 data_map->erase(oldest_entry); |
| 1121 BrowserThread::PostTask( | 1193 BrowserThread::PostTask( |
| 1122 BrowserThread::DB, FROM_HERE, | 1194 BrowserThread::DB, FROM_HERE, |
| 1123 base::Bind(&ResourcePrefetchPredictorTables::DeleteManifestData, tables_, | 1195 base::Bind(&ResourcePrefetchPredictorTables::DeleteManifestData, tables_, |
| 1124 std::vector<std::string>({key_to_delete}))); | 1196 std::vector<std::string>({key_to_delete}))); |
| 1125 } | 1197 } |
| 1126 | 1198 |
| 1199 void ResourcePrefetchPredictor::RemoveOldestEntryInOriginDataMap( |
| 1200 OriginDataMap* data_map) { |
| 1201 if (data_map->empty()) |
| 1202 return; |
| 1203 |
| 1204 uint64_t oldest_time = UINT64_MAX; |
| 1205 std::string key_to_delete; |
| 1206 for (const auto& kv : *data_map) { |
| 1207 const OriginData& data = kv.second; |
| 1208 if (key_to_delete.empty() || data.last_visit_time() < oldest_time) { |
| 1209 key_to_delete = kv.first; |
| 1210 oldest_time = data.last_visit_time(); |
| 1211 } |
| 1212 } |
| 1213 |
| 1214 data_map->erase(key_to_delete); |
| 1215 BrowserThread::PostTask( |
| 1216 BrowserThread::DB, FROM_HERE, |
| 1217 base::Bind(&ResourcePrefetchPredictorTables::DeleteOriginData, tables_, |
| 1218 std::vector<std::string>({key_to_delete}))); |
| 1219 } |
| 1220 |
| 1127 void ResourcePrefetchPredictor::OnVisitCountLookup( | 1221 void ResourcePrefetchPredictor::OnVisitCountLookup( |
| 1128 size_t url_visit_count, | 1222 size_t url_visit_count, |
| 1129 const PageRequestSummary& summary) { | 1223 const PageRequestSummary& summary) { |
| 1130 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1224 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1131 | 1225 |
| 1132 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HistoryVisitCountForUrl", | 1226 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HistoryVisitCountForUrl", |
| 1133 url_visit_count); | 1227 url_visit_count); |
| 1134 | 1228 |
| 1135 // TODO(alexilin): make only one request to DB thread. | 1229 // TODO(alexilin): make only one request to DB thread. |
| 1136 | 1230 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1150 url_redirect_table_cache_.get()); | 1244 url_redirect_table_cache_.get()); |
| 1151 } | 1245 } |
| 1152 } | 1246 } |
| 1153 | 1247 |
| 1154 // Host level data - no cutoff, always learn the navigation if enabled. | 1248 // Host level data - no cutoff, always learn the navigation if enabled. |
| 1155 const std::string host = summary.main_frame_url.host(); | 1249 const std::string host = summary.main_frame_url.host(); |
| 1156 LearnNavigation(host, PREFETCH_KEY_TYPE_HOST, summary.subresource_requests, | 1250 LearnNavigation(host, PREFETCH_KEY_TYPE_HOST, summary.subresource_requests, |
| 1157 config_.max_hosts_to_track, host_table_cache_.get(), | 1251 config_.max_hosts_to_track, host_table_cache_.get(), |
| 1158 summary.initial_url.host(), host_redirect_table_cache_.get()); | 1252 summary.initial_url.host(), host_redirect_table_cache_.get()); |
| 1159 | 1253 |
| 1254 if (config_.is_origin_prediction_enabled) { |
| 1255 LearnOrigins(host, summary.origins, config_.max_hosts_to_track, |
| 1256 origin_table_cache_.get()); |
| 1257 } |
| 1258 |
| 1160 if (observer_) | 1259 if (observer_) |
| 1161 observer_->OnNavigationLearned(url_visit_count, summary); | 1260 observer_->OnNavigationLearned(url_visit_count, summary); |
| 1162 } | 1261 } |
| 1163 | 1262 |
| 1164 void ResourcePrefetchPredictor::LearnNavigation( | 1263 void ResourcePrefetchPredictor::LearnNavigation( |
| 1165 const std::string& key, | 1264 const std::string& key, |
| 1166 PrefetchKeyType key_type, | 1265 PrefetchKeyType key_type, |
| 1167 const std::vector<URLRequestSummary>& new_resources, | 1266 const std::vector<URLRequestSummary>& new_resources, |
| 1168 size_t max_data_map_size, | 1267 size_t max_data_map_size, |
| 1169 PrefetchDataMap* data_map, | 1268 PrefetchDataMap* data_map, |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1394 const RedirectData& url_redirect_data = | 1493 const RedirectData& url_redirect_data = |
| 1395 is_host ? empty_redirect_data : data; | 1494 is_host ? empty_redirect_data : data; |
| 1396 BrowserThread::PostTask( | 1495 BrowserThread::PostTask( |
| 1397 BrowserThread::DB, FROM_HERE, | 1496 BrowserThread::DB, FROM_HERE, |
| 1398 base::Bind(&ResourcePrefetchPredictorTables::UpdateData, tables_, | 1497 base::Bind(&ResourcePrefetchPredictorTables::UpdateData, tables_, |
| 1399 empty_data, empty_data, url_redirect_data, | 1498 empty_data, empty_data, url_redirect_data, |
| 1400 host_redirect_data)); | 1499 host_redirect_data)); |
| 1401 } | 1500 } |
| 1402 } | 1501 } |
| 1403 | 1502 |
| 1503 void ResourcePrefetchPredictor::LearnOrigins( |
| 1504 const std::string& host, |
| 1505 const std::map<GURL, OriginRequestSummary>& summaries, |
| 1506 size_t max_data_map_size, |
| 1507 OriginDataMap* data_map) { |
| 1508 if (host.size() > ResourcePrefetchPredictorTables::kMaxStringLength) |
| 1509 return; |
| 1510 |
| 1511 auto cache_entry = data_map->find(host); |
| 1512 bool new_entry = cache_entry == data_map->end(); |
| 1513 if (new_entry) { |
| 1514 if (data_map->size() >= max_data_map_size) |
| 1515 RemoveOldestEntryInOriginDataMap(data_map); |
| 1516 |
| 1517 cache_entry = data_map->insert({host, OriginData()}).first; |
| 1518 OriginData& data = cache_entry->second; |
| 1519 data.set_host(host); |
| 1520 data.set_last_visit_time(base::Time::Now().ToInternalValue()); |
| 1521 size_t origins_size = summaries.size(); |
| 1522 auto ordered_origins = |
| 1523 std::vector<const OriginRequestSummary*>(origins_size); |
| 1524 for (const auto& kv : summaries) { |
| 1525 size_t index = kv.second.first_occurrence; |
| 1526 DCHECK_LT(index, origins_size); |
| 1527 ordered_origins[index] = &kv.second; |
| 1528 } |
| 1529 |
| 1530 for (const OriginRequestSummary* summary : ordered_origins) { |
| 1531 auto* origin_to_add = data.add_origins(); |
| 1532 InitializeOriginStatFromOriginRequestSummary(origin_to_add, *summary); |
| 1533 } |
| 1534 } else { |
| 1535 auto& data = cache_entry->second; |
| 1536 data.set_last_visit_time(base::Time::Now().ToInternalValue()); |
| 1537 |
| 1538 std::map<GURL, int> old_index; |
| 1539 int old_size = static_cast<int>(data.origins_size()); |
| 1540 for (int i = 0; i < old_size; ++i) { |
| 1541 bool is_new = |
| 1542 old_index.insert({GURL(data.origins(i).origin()), i}).second; |
| 1543 DCHECK(is_new); |
| 1544 } |
| 1545 |
| 1546 // Update the old origins. |
| 1547 for (int i = 0; i < old_size; ++i) { |
| 1548 auto* old_origin = data.mutable_origins(i); |
| 1549 GURL origin(old_origin->origin()); |
| 1550 auto it = summaries.find(origin); |
| 1551 if (it == summaries.end()) { |
| 1552 // miss |
| 1553 old_origin->set_number_of_misses(old_origin->number_of_misses() + 1); |
| 1554 old_origin->set_consecutive_misses(old_origin->consecutive_misses() + |
| 1555 1); |
| 1556 } else { |
| 1557 // hit: update. |
| 1558 const auto& new_origin = it->second; |
| 1559 old_origin->set_always_access_network(new_origin.always_access_network); |
| 1560 old_origin->set_accessed_network(new_origin.accessed_network); |
| 1561 |
| 1562 int position = new_origin.first_occurrence + 1; |
| 1563 int total = |
| 1564 old_origin->number_of_hits() + old_origin->number_of_misses(); |
| 1565 old_origin->set_average_position( |
| 1566 ((old_origin->average_position() * total) + position) / |
| 1567 (total + 1)); |
| 1568 old_origin->set_number_of_hits(old_origin->number_of_hits() + 1); |
| 1569 old_origin->set_consecutive_misses(0); |
| 1570 } |
| 1571 } |
| 1572 |
| 1573 // Add new origins. |
| 1574 for (const auto& kv : summaries) { |
| 1575 if (old_index.find(kv.first) != old_index.end()) |
| 1576 continue; |
| 1577 |
| 1578 auto* origin_to_add = data.add_origins(); |
| 1579 InitializeOriginStatFromOriginRequestSummary(origin_to_add, kv.second); |
| 1580 } |
| 1581 } |
| 1582 |
| 1583 // Trim and Sort. |
| 1584 auto& data = cache_entry->second; |
| 1585 ResourcePrefetchPredictorTables::TrimOrigins(&data, |
| 1586 config_.max_consecutive_misses); |
| 1587 ResourcePrefetchPredictorTables::SortOrigins(&data); |
| 1588 if (data.origins_size() > static_cast<int>(config_.max_resources_per_entry)) { |
| 1589 data.mutable_origins()->DeleteSubrange( |
| 1590 config_.max_origins_per_entry, |
| 1591 data.origins_size() - config_.max_origins_per_entry); |
| 1592 } |
| 1593 |
| 1594 // Update the database. |
| 1595 if (data.origins_size() == 0) { |
| 1596 data_map->erase(cache_entry); |
| 1597 if (!new_entry) { |
| 1598 BrowserThread::PostTask( |
| 1599 BrowserThread::DB, FROM_HERE, |
| 1600 base::Bind(&ResourcePrefetchPredictorTables::DeleteOriginData, |
| 1601 tables_, std::vector<std::string>({host}))); |
| 1602 } |
| 1603 } else { |
| 1604 BrowserThread::PostTask( |
| 1605 BrowserThread::DB, FROM_HERE, |
| 1606 base::Bind(&ResourcePrefetchPredictorTables::UpdateOriginData, tables_, |
| 1607 data)); |
| 1608 } |
| 1609 } |
| 1610 |
| 1404 void ResourcePrefetchPredictor::ReportDatabaseReadiness( | 1611 void ResourcePrefetchPredictor::ReportDatabaseReadiness( |
| 1405 const history::TopHostsList& top_hosts) const { | 1612 const history::TopHostsList& top_hosts) const { |
| 1406 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1613 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1407 if (top_hosts.size() == 0) | 1614 if (top_hosts.size() == 0) |
| 1408 return; | 1615 return; |
| 1409 | 1616 |
| 1410 size_t count_in_cache = 0; | 1617 size_t count_in_cache = 0; |
| 1411 size_t total_visits = 0; | 1618 size_t total_visits = 0; |
| 1412 for (const std::pair<std::string, int>& top_host : top_hosts) { | 1619 for (const std::pair<std::string, int>& top_host : top_hosts) { |
| 1413 const std::string& host = top_host.first; | 1620 const std::string& host = top_host.first; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1512 TestObserver::~TestObserver() { | 1719 TestObserver::~TestObserver() { |
| 1513 predictor_->SetObserverForTesting(nullptr); | 1720 predictor_->SetObserverForTesting(nullptr); |
| 1514 } | 1721 } |
| 1515 | 1722 |
| 1516 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) | 1723 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) |
| 1517 : predictor_(predictor) { | 1724 : predictor_(predictor) { |
| 1518 predictor_->SetObserverForTesting(this); | 1725 predictor_->SetObserverForTesting(this); |
| 1519 } | 1726 } |
| 1520 | 1727 |
| 1521 } // namespace predictors | 1728 } // namespace predictors |
| OLD | NEW |