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