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 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 bool is_redirect) { | |
| 74 const GURL& resource_url = request_summary.resource_url; | |
| 75 const GURL& redirected_url = request_summary.redirect_url; | |
| 76 bool is_redirected = !redirected_url.is_empty(); | |
| 77 bool valid_urls = | |
| 78 resource_url.is_valid() && (!is_redirected || redirected_url.is_valid()); | |
| 79 | |
| 80 DCHECK(valid_urls); | |
| 81 if (!valid_urls) | |
| 82 return; | |
| 83 | |
| 84 // If the response is a redirect, then add the original origin, otherwise | |
| 85 // the redirected one. Note that this makes the predictor imprecise when | |
| 86 // a request goes through multiple redirects, as this will update the | |
| 87 // summary of the starting point of the redirect chain only. | |
| 88 GURL origin = is_redirect ? resource_url.GetOrigin() | |
| 89 : (is_redirected ? redirected_url.GetOrigin() | |
| 90 : resource_url.GetOrigin()); | |
| 91 auto it = summaries->find(origin); | |
| 92 if (it == summaries->end()) { | |
| 93 ResourcePrefetchPredictor::OriginRequestSummary summary; | |
| 94 summary.origin = origin; | |
| 95 summary.first_occurrence = summaries->size(); | |
| 96 it = summaries->insert({origin, summary}).first; | |
| 97 } | |
| 98 | |
| 99 it->second.always_access_network |= | |
| 100 request_summary.always_revalidate || request_summary.is_no_store; | |
| 101 it->second.accessed_network |= request_summary.network_accessed; | |
| 102 } | |
| 103 | |
| 104 void InitializeOriginStatFromOriginRequestSummary( | |
| 105 OriginStat* origin, | |
| 106 const ResourcePrefetchPredictor::OriginRequestSummary& summary) { | |
| 107 origin->set_origin(summary.origin.spec()); | |
| 108 origin->set_number_of_hits(1); | |
| 109 origin->set_average_position(summary.first_occurrence + 1); | |
| 110 origin->set_always_access_network(summary.always_access_network); | |
| 111 origin->set_accessed_network(summary.accessed_network); | |
| 112 } | |
| 113 | |
| 70 // Used to fetch the visit count for a URL from the History database. | 114 // Used to fetch the visit count for a URL from the History database. |
| 71 class GetUrlVisitCountTask : public history::HistoryDBTask { | 115 class GetUrlVisitCountTask : public history::HistoryDBTask { |
| 72 public: | 116 public: |
| 73 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary; | 117 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary; |
| 74 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; | 118 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; |
| 75 typedef base::Callback<void(size_t, // URL visit count. | 119 typedef base::Callback<void(size_t, // URL visit count. |
| 76 const PageRequestSummary&)> | 120 const PageRequestSummary&)> |
| 77 VisitInfoCallback; | 121 VisitInfoCallback; |
| 78 | 122 |
| 79 GetUrlVisitCountTask(std::unique_ptr<PageRequestSummary> summary, | 123 GetUrlVisitCountTask(std::unique_ptr<PageRequestSummary> summary, |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 271 | 315 |
| 272 content::ResourceType resource_type = request_info->GetResourceType(); | 316 content::ResourceType resource_type = request_info->GetResourceType(); |
| 273 return resource_type == content::RESOURCE_TYPE_MAIN_FRAME | 317 return resource_type == content::RESOURCE_TYPE_MAIN_FRAME |
| 274 ? IsHandledMainPage(response) | 318 ? IsHandledMainPage(response) |
| 275 : IsHandledSubresource(response, resource_type); | 319 : IsHandledSubresource(response, resource_type); |
| 276 } | 320 } |
| 277 | 321 |
| 278 // static | 322 // static |
| 279 bool ResourcePrefetchPredictor::ShouldRecordRedirect( | 323 bool ResourcePrefetchPredictor::ShouldRecordRedirect( |
| 280 net::URLRequest* response) { | 324 net::URLRequest* response) { |
| 281 const content::ResourceRequestInfo* request_info = | 325 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 } | 326 } |
| 292 | 327 |
| 293 // static | 328 // static |
| 294 bool ResourcePrefetchPredictor::IsHandledMainPage(net::URLRequest* request) { | 329 bool ResourcePrefetchPredictor::IsHandledMainPage(net::URLRequest* request) { |
| 295 const GURL& url = request->url(); | 330 const GURL& url = request->url(); |
| 296 bool bad_port = !g_allow_port_in_urls && url.has_port(); | 331 bool bad_port = !g_allow_port_in_urls && url.has_port(); |
| 297 return url.SchemeIsHTTPOrHTTPS() && !bad_port; | 332 return url.SchemeIsHTTPOrHTTPS() && !bad_port; |
| 298 } | 333 } |
| 299 | 334 |
| 300 // static | 335 // static |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 314 return false; | 349 return false; |
| 315 | 350 |
| 316 if (response->method() != "GET") | 351 if (response->method() != "GET") |
| 317 return false; | 352 return false; |
| 318 | 353 |
| 319 if (response->original_url().spec().length() > | 354 if (response->original_url().spec().length() > |
| 320 ResourcePrefetchPredictorTables::kMaxStringLength) { | 355 ResourcePrefetchPredictorTables::kMaxStringLength) { |
| 321 return false; | 356 return false; |
| 322 } | 357 } |
| 323 | 358 |
| 324 if (!response->response_info().headers.get() || IsNoStore(response)) | 359 if (!response->response_info().headers.get()) |
| 325 return false; | 360 return false; |
| 326 | 361 |
| 327 return true; | 362 return true; |
| 328 } | 363 } |
| 329 | 364 |
| 330 // static | 365 // static |
| 331 bool ResourcePrefetchPredictor::IsHandledResourceType( | 366 bool ResourcePrefetchPredictor::IsHandledResourceType( |
| 332 content::ResourceType resource_type, | 367 content::ResourceType resource_type, |
| 333 const std::string& mime_type) { | 368 const std::string& mime_type) { |
| 334 content::ResourceType actual_resource_type = | 369 content::ResourceType actual_resource_type = |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 349 if (resource_type == content::RESOURCE_TYPE_PREFETCH || | 384 if (resource_type == content::RESOURCE_TYPE_PREFETCH || |
| 350 resource_type == content::RESOURCE_TYPE_SUB_RESOURCE || | 385 resource_type == content::RESOURCE_TYPE_SUB_RESOURCE || |
| 351 resource_type == content::RESOURCE_TYPE_XHR) { | 386 resource_type == content::RESOURCE_TYPE_XHR) { |
| 352 return GetResourceTypeFromMimeType(mime_type, | 387 return GetResourceTypeFromMimeType(mime_type, |
| 353 content::RESOURCE_TYPE_LAST_TYPE); | 388 content::RESOURCE_TYPE_LAST_TYPE); |
| 354 } | 389 } |
| 355 return resource_type; | 390 return resource_type; |
| 356 } | 391 } |
| 357 | 392 |
| 358 // static | 393 // static |
| 359 bool ResourcePrefetchPredictor::IsNoStore(const net::URLRequest* response) { | 394 bool ResourcePrefetchPredictor::IsNoStore(const net::URLRequest& response) { |
| 360 if (response->was_cached()) | 395 if (response.was_cached()) |
| 361 return false; | 396 return false; |
| 362 | 397 |
| 363 const net::HttpResponseInfo& response_info = response->response_info(); | 398 const net::HttpResponseInfo& response_info = response.response_info(); |
| 364 if (!response_info.headers.get()) | 399 if (!response_info.headers.get()) |
| 365 return false; | 400 return false; |
| 366 return response_info.headers->HasHeaderValue("cache-control", "no-store"); | 401 return response_info.headers->HasHeaderValue("cache-control", "no-store"); |
| 367 } | 402 } |
| 368 | 403 |
| 369 // static | 404 // static |
| 370 content::ResourceType ResourcePrefetchPredictor::GetResourceTypeFromMimeType( | 405 content::ResourceType ResourcePrefetchPredictor::GetResourceTypeFromMimeType( |
| 371 const std::string& mime_type, | 406 const std::string& mime_type, |
| 372 content::ResourceType fallback) { | 407 content::ResourceType fallback) { |
| 373 if (mime_type.empty()) { | 408 if (mime_type.empty()) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 423 } | 458 } |
| 424 | 459 |
| 425 // static | 460 // static |
| 426 void ResourcePrefetchPredictor::SetAllowPortInUrlsForTesting(bool state) { | 461 void ResourcePrefetchPredictor::SetAllowPortInUrlsForTesting(bool state) { |
| 427 g_allow_port_in_urls = state; | 462 g_allow_port_in_urls = state; |
| 428 } | 463 } |
| 429 | 464 |
| 430 //////////////////////////////////////////////////////////////////////////////// | 465 //////////////////////////////////////////////////////////////////////////////// |
| 431 // ResourcePrefetchPredictor nested types. | 466 // ResourcePrefetchPredictor nested types. |
| 432 | 467 |
| 468 ResourcePrefetchPredictor::OriginRequestSummary::OriginRequestSummary() | |
| 469 : origin(), | |
| 470 always_access_network(false), | |
| 471 accessed_network(false), | |
| 472 first_occurrence(0) {} | |
| 473 | |
| 474 ResourcePrefetchPredictor::OriginRequestSummary::OriginRequestSummary( | |
| 475 const OriginRequestSummary& other) = default; | |
| 476 | |
| 477 ResourcePrefetchPredictor::OriginRequestSummary::~OriginRequestSummary() {} | |
| 478 | |
| 433 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary() | 479 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary() |
| 434 : resource_type(content::RESOURCE_TYPE_LAST_TYPE), | 480 : resource_type(content::RESOURCE_TYPE_LAST_TYPE), |
| 435 priority(net::IDLE), | 481 priority(net::IDLE), |
| 436 was_cached(false), | 482 was_cached(false), |
| 437 has_validators(false), | 483 has_validators(false), |
| 438 always_revalidate(false) {} | 484 always_revalidate(false), |
| 485 is_no_store(false), | |
| 486 network_accessed(false) {} | |
| 439 | 487 |
| 440 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary( | 488 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary( |
| 441 const URLRequestSummary& other) | 489 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 | 490 |
| 452 ResourcePrefetchPredictor::URLRequestSummary::~URLRequestSummary() { | 491 ResourcePrefetchPredictor::URLRequestSummary::~URLRequestSummary() { |
| 453 } | 492 } |
| 454 | 493 |
| 455 // static | 494 // static |
| 456 bool ResourcePrefetchPredictor::URLRequestSummary::SummarizeResponse( | 495 bool ResourcePrefetchPredictor::URLRequestSummary::SummarizeResponse( |
| 457 const net::URLRequest& request, | 496 const net::URLRequest& request, |
| 458 URLRequestSummary* summary) { | 497 URLRequestSummary* summary) { |
| 459 const content::ResourceRequestInfo* request_info = | 498 const content::ResourceRequestInfo* request_info = |
| 460 content::ResourceRequestInfo::ForRequest(&request); | 499 content::ResourceRequestInfo::ForRequest(&request); |
| 461 if (!request_info) | 500 if (!request_info) |
| 462 return false; | 501 return false; |
| 463 | 502 |
| 464 summary->resource_url = request.original_url(); | 503 summary->resource_url = request.original_url(); |
| 504 if (request.url_chain().size() > 1) | |
|
alexilin
2017/04/12 08:21:45
I'd prefer just to add a new `request_url` field t
Benoit L
2017/04/12 12:32:40
Done.
| |
| 505 summary->redirect_url = request.url(); | |
| 465 content::ResourceType resource_type_from_request = | 506 content::ResourceType resource_type_from_request = |
| 466 request_info->GetResourceType(); | 507 request_info->GetResourceType(); |
| 467 summary->priority = request.priority(); | 508 summary->priority = request.priority(); |
| 468 request.GetMimeType(&summary->mime_type); | 509 request.GetMimeType(&summary->mime_type); |
| 469 summary->was_cached = request.was_cached(); | 510 summary->was_cached = request.was_cached(); |
| 470 summary->resource_type = | 511 summary->resource_type = |
| 471 GetResourceType(resource_type_from_request, summary->mime_type); | 512 GetResourceType(resource_type_from_request, summary->mime_type); |
| 472 | 513 |
| 473 scoped_refptr<net::HttpResponseHeaders> headers = | 514 scoped_refptr<net::HttpResponseHeaders> headers = |
| 474 request.response_info().headers; | 515 request.response_info().headers; |
| 475 if (headers.get()) { | 516 if (headers.get()) { |
| 476 summary->has_validators = headers->HasValidators(); | 517 summary->has_validators = headers->HasValidators(); |
| 477 // RFC 2616, section 14.9. | 518 // RFC 2616, section 14.9. |
| 478 summary->always_revalidate = | 519 summary->always_revalidate = |
| 479 headers->HasHeaderValue("cache-control", "no-cache") || | 520 headers->HasHeaderValue("cache-control", "no-cache") || |
| 480 headers->HasHeaderValue("pragma", "no-cache") || | 521 headers->HasHeaderValue("pragma", "no-cache") || |
| 481 headers->HasHeaderValue("vary", "*"); | 522 headers->HasHeaderValue("vary", "*"); |
| 523 summary->is_no_store = IsNoStore(request); | |
| 482 } | 524 } |
| 525 summary->network_accessed = request.response_info().network_accessed; | |
| 483 return true; | 526 return true; |
| 484 } | 527 } |
| 485 | 528 |
| 486 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( | 529 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( |
| 487 const GURL& i_main_frame_url) | 530 const GURL& i_main_frame_url) |
| 488 : main_frame_url(i_main_frame_url), initial_url(i_main_frame_url) {} | 531 : main_frame_url(i_main_frame_url), initial_url(i_main_frame_url) {} |
| 489 | 532 |
| 490 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( | 533 ResourcePrefetchPredictor::PageRequestSummary::PageRequestSummary( |
| 491 const PageRequestSummary& other) = default; | 534 const PageRequestSummary& other) = default; |
| 492 | 535 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 527 if (initialization_state_ != NOT_INITIALIZED) | 570 if (initialization_state_ != NOT_INITIALIZED) |
| 528 return; | 571 return; |
| 529 initialization_state_ = INITIALIZING; | 572 initialization_state_ = INITIALIZING; |
| 530 | 573 |
| 531 // Create local caches using the database as loaded. | 574 // Create local caches using the database as loaded. |
| 532 auto url_data_map = base::MakeUnique<PrefetchDataMap>(); | 575 auto url_data_map = base::MakeUnique<PrefetchDataMap>(); |
| 533 auto host_data_map = base::MakeUnique<PrefetchDataMap>(); | 576 auto host_data_map = base::MakeUnique<PrefetchDataMap>(); |
| 534 auto url_redirect_data_map = base::MakeUnique<RedirectDataMap>(); | 577 auto url_redirect_data_map = base::MakeUnique<RedirectDataMap>(); |
| 535 auto host_redirect_data_map = base::MakeUnique<RedirectDataMap>(); | 578 auto host_redirect_data_map = base::MakeUnique<RedirectDataMap>(); |
| 536 auto manifest_data_map = base::MakeUnique<ManifestDataMap>(); | 579 auto manifest_data_map = base::MakeUnique<ManifestDataMap>(); |
| 580 auto origin_data_map = base::MakeUnique<OriginDataMap>(); | |
| 537 | 581 |
| 538 // Get raw pointers to pass to the first task. Ownership of the unique_ptrs | 582 // Get raw pointers to pass to the first task. Ownership of the unique_ptrs |
| 539 // will be passed to the reply task. | 583 // will be passed to the reply task. |
| 540 auto* url_data_map_ptr = url_data_map.get(); | 584 auto* url_data_map_ptr = url_data_map.get(); |
| 541 auto* host_data_map_ptr = host_data_map.get(); | 585 auto* host_data_map_ptr = host_data_map.get(); |
| 542 auto* url_redirect_data_map_ptr = url_redirect_data_map.get(); | 586 auto* url_redirect_data_map_ptr = url_redirect_data_map.get(); |
| 543 auto* host_redirect_data_map_ptr = host_redirect_data_map.get(); | 587 auto* host_redirect_data_map_ptr = host_redirect_data_map.get(); |
| 544 auto* manifest_data_map_ptr = manifest_data_map.get(); | 588 auto* manifest_data_map_ptr = manifest_data_map.get(); |
| 589 auto* origin_data_map_ptr = origin_data_map.get(); | |
| 545 | 590 |
| 546 BrowserThread::PostTaskAndReply( | 591 BrowserThread::PostTaskAndReply( |
| 547 BrowserThread::DB, FROM_HERE, | 592 BrowserThread::DB, FROM_HERE, |
| 548 base::Bind(&ResourcePrefetchPredictorTables::GetAllData, tables_, | 593 base::Bind(&ResourcePrefetchPredictorTables::GetAllData, tables_, |
| 549 url_data_map_ptr, host_data_map_ptr, url_redirect_data_map_ptr, | 594 url_data_map_ptr, host_data_map_ptr, url_redirect_data_map_ptr, |
| 550 host_redirect_data_map_ptr, manifest_data_map_ptr), | 595 host_redirect_data_map_ptr, manifest_data_map_ptr, |
| 596 origin_data_map_ptr), | |
| 551 base::Bind(&ResourcePrefetchPredictor::CreateCaches, AsWeakPtr(), | 597 base::Bind(&ResourcePrefetchPredictor::CreateCaches, AsWeakPtr(), |
| 552 base::Passed(&url_data_map), base::Passed(&host_data_map), | 598 base::Passed(&url_data_map), base::Passed(&host_data_map), |
| 553 base::Passed(&url_redirect_data_map), | 599 base::Passed(&url_redirect_data_map), |
| 554 base::Passed(&host_redirect_data_map), | 600 base::Passed(&host_redirect_data_map), |
| 555 base::Passed(&manifest_data_map))); | 601 base::Passed(&manifest_data_map), |
| 602 base::Passed(&origin_data_map))); | |
| 556 } | 603 } |
| 557 | 604 |
| 558 void ResourcePrefetchPredictor::RecordURLRequest( | 605 void ResourcePrefetchPredictor::RecordURLRequest( |
| 559 const URLRequestSummary& request) { | 606 const URLRequestSummary& request) { |
| 560 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 607 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 561 if (initialization_state_ != INITIALIZED) | 608 if (initialization_state_ != INITIALIZED) |
| 562 return; | 609 return; |
| 563 | 610 |
| 564 CHECK_EQ(request.resource_type, content::RESOURCE_TYPE_MAIN_FRAME); | 611 CHECK_EQ(request.resource_type, content::RESOURCE_TYPE_MAIN_FRAME); |
| 565 OnMainFrameRequest(request); | 612 OnMainFrameRequest(request); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 576 else | 623 else |
| 577 OnSubresourceResponse(response); | 624 OnSubresourceResponse(response); |
| 578 } | 625 } |
| 579 | 626 |
| 580 void ResourcePrefetchPredictor::RecordURLRedirect( | 627 void ResourcePrefetchPredictor::RecordURLRedirect( |
| 581 const URLRequestSummary& response) { | 628 const URLRequestSummary& response) { |
| 582 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 629 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 583 if (initialization_state_ != INITIALIZED) | 630 if (initialization_state_ != INITIALIZED) |
| 584 return; | 631 return; |
| 585 | 632 |
| 586 CHECK_EQ(response.resource_type, content::RESOURCE_TYPE_MAIN_FRAME); | 633 if (response.resource_type == content::RESOURCE_TYPE_MAIN_FRAME) |
| 587 OnMainFrameRedirect(response); | 634 OnMainFrameRedirect(response); |
| 635 else | |
| 636 OnSubresourceRedirect(response); | |
| 588 } | 637 } |
| 589 | 638 |
| 590 void ResourcePrefetchPredictor::RecordMainFrameLoadComplete( | 639 void ResourcePrefetchPredictor::RecordMainFrameLoadComplete( |
| 591 const NavigationID& navigation_id) { | 640 const NavigationID& navigation_id) { |
| 592 switch (initialization_state_) { | 641 switch (initialization_state_) { |
| 593 case NOT_INITIALIZED: | 642 case NOT_INITIALIZED: |
| 594 StartInitialization(); | 643 StartInitialization(); |
| 595 break; | 644 break; |
| 596 case INITIALIZING: | 645 case INITIALIZING: |
| 597 break; | 646 break; |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 757 inflight_navigations_.insert( | 806 inflight_navigations_.insert( |
| 758 std::make_pair(navigation_id, std::move(summary))); | 807 std::make_pair(navigation_id, std::move(summary))); |
| 759 } | 808 } |
| 760 | 809 |
| 761 void ResourcePrefetchPredictor::OnSubresourceResponse( | 810 void ResourcePrefetchPredictor::OnSubresourceResponse( |
| 762 const URLRequestSummary& response) { | 811 const URLRequestSummary& response) { |
| 763 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 812 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 764 DCHECK_EQ(INITIALIZED, initialization_state_); | 813 DCHECK_EQ(INITIALIZED, initialization_state_); |
| 765 | 814 |
| 766 NavigationMap::const_iterator nav_it = | 815 NavigationMap::const_iterator nav_it = |
| 767 inflight_navigations_.find(response.navigation_id); | 816 inflight_navigations_.find(response.navigation_id); |
| 768 if (nav_it == inflight_navigations_.end()) { | 817 if (nav_it == inflight_navigations_.end()) |
| 769 return; | 818 return; |
| 770 } | 819 auto& page_request_summary = *nav_it->second; |
| 771 | 820 |
| 772 nav_it->second->subresource_requests.push_back(response); | 821 if (!response.is_no_store) |
| 822 page_request_summary.subresource_requests.push_back(response); | |
| 823 | |
| 824 if (config_.is_origin_prediction_enabled) | |
| 825 UpdateOrAddToOrigins(&page_request_summary.origins, response, false); | |
| 826 } | |
| 827 | |
| 828 void ResourcePrefetchPredictor::OnSubresourceRedirect( | |
| 829 const URLRequestSummary& response) { | |
| 830 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 831 DCHECK_EQ(INITIALIZED, initialization_state_); | |
| 832 | |
| 833 if (!config_.is_origin_prediction_enabled) | |
| 834 return; | |
| 835 | |
| 836 NavigationMap::const_iterator nav_it = | |
| 837 inflight_navigations_.find(response.navigation_id); | |
| 838 if (nav_it == inflight_navigations_.end()) | |
| 839 return; | |
| 840 auto& page_request_summary = *nav_it->second; | |
| 841 UpdateOrAddToOrigins(&page_request_summary.origins, response, true); | |
| 773 } | 842 } |
| 774 | 843 |
| 775 void ResourcePrefetchPredictor::OnNavigationComplete( | 844 void ResourcePrefetchPredictor::OnNavigationComplete( |
| 776 const NavigationID& nav_id_without_timing_info) { | 845 const NavigationID& nav_id_without_timing_info) { |
| 777 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 846 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 778 DCHECK_EQ(INITIALIZED, initialization_state_); | 847 DCHECK_EQ(INITIALIZED, initialization_state_); |
| 779 | 848 |
| 780 NavigationMap::iterator nav_it = | 849 NavigationMap::iterator nav_it = |
| 781 inflight_navigations_.find(nav_id_without_timing_info); | 850 inflight_navigations_.find(nav_id_without_timing_info); |
| 782 if (nav_it == inflight_navigations_.end()) | 851 if (nav_it == inflight_navigations_.end()) |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 896 } | 965 } |
| 897 | 966 |
| 898 return has_prefetchable_resource; | 967 return has_prefetchable_resource; |
| 899 } | 968 } |
| 900 | 969 |
| 901 void ResourcePrefetchPredictor::CreateCaches( | 970 void ResourcePrefetchPredictor::CreateCaches( |
| 902 std::unique_ptr<PrefetchDataMap> url_data_map, | 971 std::unique_ptr<PrefetchDataMap> url_data_map, |
| 903 std::unique_ptr<PrefetchDataMap> host_data_map, | 972 std::unique_ptr<PrefetchDataMap> host_data_map, |
| 904 std::unique_ptr<RedirectDataMap> url_redirect_data_map, | 973 std::unique_ptr<RedirectDataMap> url_redirect_data_map, |
| 905 std::unique_ptr<RedirectDataMap> host_redirect_data_map, | 974 std::unique_ptr<RedirectDataMap> host_redirect_data_map, |
| 906 std::unique_ptr<ManifestDataMap> manifest_data_map) { | 975 std::unique_ptr<ManifestDataMap> manifest_data_map, |
| 976 std::unique_ptr<OriginDataMap> origin_data_map) { | |
| 907 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 977 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 908 | 978 |
| 909 DCHECK_EQ(INITIALIZING, initialization_state_); | 979 DCHECK_EQ(INITIALIZING, initialization_state_); |
| 910 DCHECK(!url_table_cache_); | 980 DCHECK(!url_table_cache_); |
| 911 DCHECK(!host_table_cache_); | 981 DCHECK(!host_table_cache_); |
| 912 DCHECK(!url_redirect_table_cache_); | 982 DCHECK(!url_redirect_table_cache_); |
| 913 DCHECK(!host_redirect_table_cache_); | 983 DCHECK(!host_redirect_table_cache_); |
| 914 DCHECK(!manifest_table_cache_); | 984 DCHECK(!manifest_table_cache_); |
| 985 DCHECK(!origin_table_cache_); | |
| 986 | |
| 915 DCHECK(inflight_navigations_.empty()); | 987 DCHECK(inflight_navigations_.empty()); |
| 916 | 988 |
| 917 url_table_cache_ = std::move(url_data_map); | 989 url_table_cache_ = std::move(url_data_map); |
| 918 host_table_cache_ = std::move(host_data_map); | 990 host_table_cache_ = std::move(host_data_map); |
| 919 url_redirect_table_cache_ = std::move(url_redirect_data_map); | 991 url_redirect_table_cache_ = std::move(url_redirect_data_map); |
| 920 host_redirect_table_cache_ = std::move(host_redirect_data_map); | 992 host_redirect_table_cache_ = std::move(host_redirect_data_map); |
| 921 manifest_table_cache_ = std::move(manifest_data_map); | 993 manifest_table_cache_ = std::move(manifest_data_map); |
| 994 origin_table_cache_ = std::move(origin_data_map); | |
| 922 | 995 |
| 923 ConnectToHistoryService(); | 996 ConnectToHistoryService(); |
| 924 } | 997 } |
| 925 | 998 |
| 926 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() { | 999 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() { |
| 927 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1000 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 928 DCHECK_EQ(INITIALIZING, initialization_state_); | 1001 DCHECK_EQ(INITIALIZING, initialization_state_); |
| 929 | 1002 |
| 930 // Initialize the prefetch manager only if prefetching is enabled. | 1003 // Initialize the prefetch manager only if prefetching is enabled. |
| 931 if (config_.IsPrefetchingEnabledForSomeOrigin(profile_)) { | 1004 if (config_.IsPrefetchingEnabledForSomeOrigin(profile_)) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 982 } | 1055 } |
| 983 } | 1056 } |
| 984 | 1057 |
| 985 void ResourcePrefetchPredictor::DeleteAllUrls() { | 1058 void ResourcePrefetchPredictor::DeleteAllUrls() { |
| 986 inflight_navigations_.clear(); | 1059 inflight_navigations_.clear(); |
| 987 url_table_cache_->clear(); | 1060 url_table_cache_->clear(); |
| 988 host_table_cache_->clear(); | 1061 host_table_cache_->clear(); |
| 989 url_redirect_table_cache_->clear(); | 1062 url_redirect_table_cache_->clear(); |
| 990 host_redirect_table_cache_->clear(); | 1063 host_redirect_table_cache_->clear(); |
| 991 manifest_table_cache_->clear(); | 1064 manifest_table_cache_->clear(); |
| 1065 origin_table_cache_->clear(); | |
| 992 | 1066 |
| 993 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, | 1067 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, |
| 994 base::Bind(&ResourcePrefetchPredictorTables::DeleteAllData, tables_)); | 1068 base::Bind(&ResourcePrefetchPredictorTables::DeleteAllData, tables_)); |
| 995 } | 1069 } |
| 996 | 1070 |
| 997 void ResourcePrefetchPredictor::DeleteUrls(const history::URLRows& urls) { | 1071 void ResourcePrefetchPredictor::DeleteUrls(const history::URLRows& urls) { |
| 998 // Check all the urls in the database and pick out the ones that are present | 1072 // Check all the urls in the database and pick out the ones that are present |
| 999 // in the cache. | 1073 // in the cache. |
| 1000 std::vector<std::string> urls_to_delete, hosts_to_delete; | 1074 std::vector<std::string> urls_to_delete, hosts_to_delete; |
| 1001 std::vector<std::string> url_redirects_to_delete, host_redirects_to_delete; | 1075 std::vector<std::string> url_redirects_to_delete, host_redirects_to_delete; |
| 1002 std::vector<std::string> manifest_hosts_to_delete; | 1076 std::vector<std::string> manifest_hosts_to_delete; |
| 1077 std::vector<std::string> origin_hosts_to_delete; | |
| 1003 | 1078 |
| 1004 for (const auto& it : urls) { | 1079 for (const auto& it : urls) { |
| 1005 const std::string& url_spec = it.url().spec(); | 1080 const std::string& url_spec = it.url().spec(); |
| 1006 if (url_table_cache_->find(url_spec) != url_table_cache_->end()) { | 1081 if (url_table_cache_->find(url_spec) != url_table_cache_->end()) { |
| 1007 urls_to_delete.push_back(url_spec); | 1082 urls_to_delete.push_back(url_spec); |
| 1008 url_table_cache_->erase(url_spec); | 1083 url_table_cache_->erase(url_spec); |
| 1009 } | 1084 } |
| 1010 | 1085 |
| 1011 if (url_redirect_table_cache_->find(url_spec) != | 1086 if (url_redirect_table_cache_->find(url_spec) != |
| 1012 url_redirect_table_cache_->end()) { | 1087 url_redirect_table_cache_->end()) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1025 host_redirects_to_delete.push_back(host); | 1100 host_redirects_to_delete.push_back(host); |
| 1026 host_redirect_table_cache_->erase(host); | 1101 host_redirect_table_cache_->erase(host); |
| 1027 } | 1102 } |
| 1028 | 1103 |
| 1029 std::string manifest_host = history::HostForTopHosts(it.url()); | 1104 std::string manifest_host = history::HostForTopHosts(it.url()); |
| 1030 if (manifest_table_cache_->find(manifest_host) != | 1105 if (manifest_table_cache_->find(manifest_host) != |
| 1031 manifest_table_cache_->end()) { | 1106 manifest_table_cache_->end()) { |
| 1032 manifest_hosts_to_delete.push_back(manifest_host); | 1107 manifest_hosts_to_delete.push_back(manifest_host); |
| 1033 manifest_table_cache_->erase(manifest_host); | 1108 manifest_table_cache_->erase(manifest_host); |
| 1034 } | 1109 } |
| 1110 | |
| 1111 if (origin_table_cache_->find(host) != origin_table_cache_->end()) { | |
| 1112 origin_hosts_to_delete.push_back(host); | |
| 1113 origin_table_cache_->erase(host); | |
| 1114 } | |
| 1035 } | 1115 } |
| 1036 | 1116 |
| 1037 if (!urls_to_delete.empty() || !hosts_to_delete.empty()) { | 1117 if (!urls_to_delete.empty() || !hosts_to_delete.empty()) { |
| 1038 BrowserThread::PostTask( | 1118 BrowserThread::PostTask( |
| 1039 BrowserThread::DB, FROM_HERE, | 1119 BrowserThread::DB, FROM_HERE, |
| 1040 base::Bind(&ResourcePrefetchPredictorTables::DeleteResourceData, | 1120 base::Bind(&ResourcePrefetchPredictorTables::DeleteResourceData, |
| 1041 tables_, urls_to_delete, hosts_to_delete)); | 1121 tables_, urls_to_delete, hosts_to_delete)); |
| 1042 } | 1122 } |
| 1043 | 1123 |
| 1044 if (!url_redirects_to_delete.empty() || !host_redirects_to_delete.empty()) { | 1124 if (!url_redirects_to_delete.empty() || !host_redirects_to_delete.empty()) { |
| 1045 BrowserThread::PostTask( | 1125 BrowserThread::PostTask( |
| 1046 BrowserThread::DB, FROM_HERE, | 1126 BrowserThread::DB, FROM_HERE, |
| 1047 base::Bind(&ResourcePrefetchPredictorTables::DeleteRedirectData, | 1127 base::Bind(&ResourcePrefetchPredictorTables::DeleteRedirectData, |
| 1048 tables_, url_redirects_to_delete, host_redirects_to_delete)); | 1128 tables_, url_redirects_to_delete, host_redirects_to_delete)); |
| 1049 } | 1129 } |
| 1050 | 1130 |
| 1051 if (!manifest_hosts_to_delete.empty()) { | 1131 if (!manifest_hosts_to_delete.empty()) { |
| 1052 BrowserThread::PostTask( | 1132 BrowserThread::PostTask( |
| 1053 BrowserThread::DB, FROM_HERE, | 1133 BrowserThread::DB, FROM_HERE, |
| 1054 base::Bind(&ResourcePrefetchPredictorTables::DeleteManifestData, | 1134 base::Bind(&ResourcePrefetchPredictorTables::DeleteManifestData, |
| 1055 tables_, manifest_hosts_to_delete)); | 1135 tables_, manifest_hosts_to_delete)); |
| 1056 } | 1136 } |
| 1137 | |
| 1138 if (!origin_hosts_to_delete.empty()) { | |
| 1139 BrowserThread::PostTask( | |
| 1140 BrowserThread::DB, FROM_HERE, | |
| 1141 base::Bind(&ResourcePrefetchPredictorTables::DeleteOriginData, tables_, | |
| 1142 origin_hosts_to_delete)); | |
| 1143 } | |
| 1057 } | 1144 } |
| 1058 | 1145 |
| 1059 void ResourcePrefetchPredictor::RemoveOldestEntryInPrefetchDataMap( | 1146 void ResourcePrefetchPredictor::RemoveOldestEntryInPrefetchDataMap( |
| 1060 PrefetchKeyType key_type, | 1147 PrefetchKeyType key_type, |
| 1061 PrefetchDataMap* data_map) { | 1148 PrefetchDataMap* data_map) { |
| 1062 if (data_map->empty()) | 1149 if (data_map->empty()) |
| 1063 return; | 1150 return; |
| 1064 | 1151 |
| 1065 uint64_t oldest_time = UINT64_MAX; | 1152 uint64_t oldest_time = UINT64_MAX; |
| 1066 std::string key_to_delete; | 1153 std::string key_to_delete; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1117 }); | 1204 }); |
| 1118 | 1205 |
| 1119 std::string key_to_delete = oldest_entry->first; | 1206 std::string key_to_delete = oldest_entry->first; |
| 1120 data_map->erase(oldest_entry); | 1207 data_map->erase(oldest_entry); |
| 1121 BrowserThread::PostTask( | 1208 BrowserThread::PostTask( |
| 1122 BrowserThread::DB, FROM_HERE, | 1209 BrowserThread::DB, FROM_HERE, |
| 1123 base::Bind(&ResourcePrefetchPredictorTables::DeleteManifestData, tables_, | 1210 base::Bind(&ResourcePrefetchPredictorTables::DeleteManifestData, tables_, |
| 1124 std::vector<std::string>({key_to_delete}))); | 1211 std::vector<std::string>({key_to_delete}))); |
| 1125 } | 1212 } |
| 1126 | 1213 |
| 1214 void ResourcePrefetchPredictor::RemoveOldestEntryInOriginDataMap( | |
| 1215 OriginDataMap* data_map) { | |
| 1216 if (data_map->empty()) | |
| 1217 return; | |
| 1218 | |
| 1219 uint64_t oldest_time = UINT64_MAX; | |
| 1220 std::string key_to_delete; | |
| 1221 for (const auto& kv : *data_map) { | |
| 1222 const OriginData& data = kv.second; | |
| 1223 if (key_to_delete.empty() || data.last_visit_time() < oldest_time) { | |
| 1224 key_to_delete = kv.first; | |
| 1225 oldest_time = data.last_visit_time(); | |
| 1226 } | |
| 1227 } | |
| 1228 | |
| 1229 data_map->erase(key_to_delete); | |
| 1230 BrowserThread::PostTask( | |
| 1231 BrowserThread::DB, FROM_HERE, | |
| 1232 base::Bind(&ResourcePrefetchPredictorTables::DeleteOriginData, tables_, | |
| 1233 std::vector<std::string>({key_to_delete}))); | |
| 1234 } | |
| 1235 | |
| 1127 void ResourcePrefetchPredictor::OnVisitCountLookup( | 1236 void ResourcePrefetchPredictor::OnVisitCountLookup( |
| 1128 size_t url_visit_count, | 1237 size_t url_visit_count, |
| 1129 const PageRequestSummary& summary) { | 1238 const PageRequestSummary& summary) { |
| 1130 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1239 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1131 | 1240 |
| 1132 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HistoryVisitCountForUrl", | 1241 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HistoryVisitCountForUrl", |
| 1133 url_visit_count); | 1242 url_visit_count); |
| 1134 | 1243 |
| 1135 // TODO(alexilin): make only one request to DB thread. | 1244 // TODO(alexilin): make only one request to DB thread. |
| 1136 | 1245 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1150 url_redirect_table_cache_.get()); | 1259 url_redirect_table_cache_.get()); |
| 1151 } | 1260 } |
| 1152 } | 1261 } |
| 1153 | 1262 |
| 1154 // Host level data - no cutoff, always learn the navigation if enabled. | 1263 // Host level data - no cutoff, always learn the navigation if enabled. |
| 1155 const std::string host = summary.main_frame_url.host(); | 1264 const std::string host = summary.main_frame_url.host(); |
| 1156 LearnNavigation(host, PREFETCH_KEY_TYPE_HOST, summary.subresource_requests, | 1265 LearnNavigation(host, PREFETCH_KEY_TYPE_HOST, summary.subresource_requests, |
| 1157 config_.max_hosts_to_track, host_table_cache_.get(), | 1266 config_.max_hosts_to_track, host_table_cache_.get(), |
| 1158 summary.initial_url.host(), host_redirect_table_cache_.get()); | 1267 summary.initial_url.host(), host_redirect_table_cache_.get()); |
| 1159 | 1268 |
| 1269 if (config_.is_origin_prediction_enabled) { | |
| 1270 LearnOrigins(host, summary.origins, config_.max_hosts_to_track, | |
| 1271 origin_table_cache_.get()); | |
| 1272 } | |
| 1273 | |
| 1160 if (observer_) | 1274 if (observer_) |
| 1161 observer_->OnNavigationLearned(url_visit_count, summary); | 1275 observer_->OnNavigationLearned(url_visit_count, summary); |
| 1162 } | 1276 } |
| 1163 | 1277 |
| 1164 void ResourcePrefetchPredictor::LearnNavigation( | 1278 void ResourcePrefetchPredictor::LearnNavigation( |
| 1165 const std::string& key, | 1279 const std::string& key, |
| 1166 PrefetchKeyType key_type, | 1280 PrefetchKeyType key_type, |
| 1167 const std::vector<URLRequestSummary>& new_resources, | 1281 const std::vector<URLRequestSummary>& new_resources, |
| 1168 size_t max_data_map_size, | 1282 size_t max_data_map_size, |
| 1169 PrefetchDataMap* data_map, | 1283 PrefetchDataMap* data_map, |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1394 const RedirectData& url_redirect_data = | 1508 const RedirectData& url_redirect_data = |
| 1395 is_host ? empty_redirect_data : data; | 1509 is_host ? empty_redirect_data : data; |
| 1396 BrowserThread::PostTask( | 1510 BrowserThread::PostTask( |
| 1397 BrowserThread::DB, FROM_HERE, | 1511 BrowserThread::DB, FROM_HERE, |
| 1398 base::Bind(&ResourcePrefetchPredictorTables::UpdateData, tables_, | 1512 base::Bind(&ResourcePrefetchPredictorTables::UpdateData, tables_, |
| 1399 empty_data, empty_data, url_redirect_data, | 1513 empty_data, empty_data, url_redirect_data, |
| 1400 host_redirect_data)); | 1514 host_redirect_data)); |
| 1401 } | 1515 } |
| 1402 } | 1516 } |
| 1403 | 1517 |
| 1518 void ResourcePrefetchPredictor::LearnOrigins( | |
| 1519 const std::string& host, | |
| 1520 const std::map<GURL, OriginRequestSummary>& summaries, | |
| 1521 size_t max_data_map_size, | |
| 1522 OriginDataMap* data_map) { | |
| 1523 if (host.size() > ResourcePrefetchPredictorTables::kMaxStringLength) | |
| 1524 return; | |
| 1525 | |
| 1526 auto cache_entry = data_map->find(host); | |
| 1527 bool new_entry = cache_entry == data_map->end(); | |
| 1528 if (new_entry) { | |
| 1529 if (data_map->size() >= max_data_map_size) | |
| 1530 RemoveOldestEntryInOriginDataMap(data_map); | |
| 1531 | |
| 1532 cache_entry = data_map->insert({host, OriginData()}).first; | |
| 1533 OriginData& data = cache_entry->second; | |
| 1534 data.set_host(host); | |
| 1535 data.set_last_visit_time(base::Time::Now().ToInternalValue()); | |
| 1536 size_t origins_size = summaries.size(); | |
| 1537 auto ordered_origins = | |
| 1538 std::vector<const OriginRequestSummary*>(origins_size); | |
| 1539 for (const auto& kv : summaries) { | |
| 1540 size_t index = kv.second.first_occurrence; | |
| 1541 DCHECK_LT(index, origins_size); | |
| 1542 ordered_origins[index] = &kv.second; | |
| 1543 } | |
| 1544 | |
| 1545 for (const OriginRequestSummary* summary : ordered_origins) { | |
| 1546 auto* origin_to_add = data.add_origins(); | |
| 1547 InitializeOriginStatFromOriginRequestSummary(origin_to_add, *summary); | |
| 1548 } | |
| 1549 } else { | |
| 1550 auto& data = cache_entry->second; | |
| 1551 data.set_last_visit_time(base::Time::Now().ToInternalValue()); | |
| 1552 | |
| 1553 std::map<GURL, int> old_index; | |
| 1554 int old_size = static_cast<int>(data.origins_size()); | |
| 1555 for (int i = 0; i < old_size; ++i) { | |
| 1556 bool is_new = | |
| 1557 old_index.insert({GURL(data.origins(i).origin()), i}).second; | |
| 1558 DCHECK(is_new); | |
| 1559 } | |
| 1560 | |
| 1561 // Update the old origins. | |
| 1562 for (int i = 0; i < old_size; ++i) { | |
| 1563 auto* old_origin = data.mutable_origins(i); | |
| 1564 GURL origin(old_origin->origin()); | |
| 1565 auto it = summaries.find(origin); | |
| 1566 if (it == summaries.end()) { | |
| 1567 // miss | |
| 1568 old_origin->set_number_of_misses(old_origin->number_of_misses() + 1); | |
| 1569 old_origin->set_consecutive_misses(old_origin->consecutive_misses() + | |
| 1570 1); | |
| 1571 } else { | |
| 1572 // hit: update. | |
| 1573 const auto& new_origin = it->second; | |
| 1574 old_origin->set_always_access_network(new_origin.always_access_network); | |
| 1575 old_origin->set_accessed_network(new_origin.accessed_network); | |
| 1576 | |
| 1577 int position = new_origin.first_occurrence + 1; | |
| 1578 int total = | |
| 1579 old_origin->number_of_hits() + old_origin->number_of_misses(); | |
| 1580 old_origin->set_average_position( | |
| 1581 ((old_origin->average_position() * total) + position) / | |
| 1582 (total + 1)); | |
| 1583 old_origin->set_number_of_hits(old_origin->number_of_hits() + 1); | |
| 1584 old_origin->set_consecutive_misses(0); | |
| 1585 } | |
| 1586 } | |
| 1587 | |
| 1588 // Add new origins. | |
| 1589 for (const auto& kv : summaries) { | |
| 1590 if (old_index.find(kv.first) != old_index.end()) | |
| 1591 continue; | |
| 1592 | |
| 1593 auto* origin_to_add = data.add_origins(); | |
| 1594 InitializeOriginStatFromOriginRequestSummary(origin_to_add, kv.second); | |
| 1595 } | |
| 1596 } | |
| 1597 | |
| 1598 // Trim and Sort. | |
| 1599 auto& data = cache_entry->second; | |
| 1600 ResourcePrefetchPredictorTables::TrimOrigins(&data, | |
| 1601 config_.max_consecutive_misses); | |
| 1602 ResourcePrefetchPredictorTables::SortOrigins(&data); | |
| 1603 if (data.origins_size() > static_cast<int>(config_.max_resources_per_entry)) { | |
| 1604 data.mutable_origins()->DeleteSubrange( | |
| 1605 config_.max_origins_per_entry, | |
| 1606 data.origins_size() - config_.max_origins_per_entry); | |
| 1607 } | |
| 1608 | |
| 1609 // Update the database. | |
| 1610 if (data.origins_size() == 0) { | |
| 1611 data_map->erase(cache_entry); | |
| 1612 if (!new_entry) { | |
| 1613 BrowserThread::PostTask( | |
| 1614 BrowserThread::DB, FROM_HERE, | |
| 1615 base::Bind(&ResourcePrefetchPredictorTables::DeleteOriginData, | |
| 1616 tables_, std::vector<std::string>({host}))); | |
| 1617 } | |
| 1618 } else { | |
| 1619 BrowserThread::PostTask( | |
| 1620 BrowserThread::DB, FROM_HERE, | |
| 1621 base::Bind(&ResourcePrefetchPredictorTables::UpdateOriginData, tables_, | |
| 1622 data)); | |
| 1623 } | |
| 1624 } | |
| 1625 | |
| 1404 void ResourcePrefetchPredictor::ReportDatabaseReadiness( | 1626 void ResourcePrefetchPredictor::ReportDatabaseReadiness( |
| 1405 const history::TopHostsList& top_hosts) const { | 1627 const history::TopHostsList& top_hosts) const { |
| 1406 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1628 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1407 if (top_hosts.size() == 0) | 1629 if (top_hosts.size() == 0) |
| 1408 return; | 1630 return; |
| 1409 | 1631 |
| 1410 size_t count_in_cache = 0; | 1632 size_t count_in_cache = 0; |
| 1411 size_t total_visits = 0; | 1633 size_t total_visits = 0; |
| 1412 for (const std::pair<std::string, int>& top_host : top_hosts) { | 1634 for (const std::pair<std::string, int>& top_host : top_hosts) { |
| 1413 const std::string& host = top_host.first; | 1635 const std::string& host = top_host.first; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1512 TestObserver::~TestObserver() { | 1734 TestObserver::~TestObserver() { |
| 1513 predictor_->SetObserverForTesting(nullptr); | 1735 predictor_->SetObserverForTesting(nullptr); |
| 1514 } | 1736 } |
| 1515 | 1737 |
| 1516 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) | 1738 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) |
| 1517 : predictor_(predictor) { | 1739 : predictor_(predictor) { |
| 1518 predictor_->SetObserverForTesting(this); | 1740 predictor_->SetObserverForTesting(this); |
| 1519 } | 1741 } |
| 1520 | 1742 |
| 1521 } // namespace predictors | 1743 } // namespace predictors |
| OLD | NEW |