Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: chrome/browser/predictors/resource_prefetch_predictor.cc

Issue 2937623007: predictors: Move more methods from ResourcePrefetchPredictor into LoadingDataCollector. (Closed)
Patch Set: Make InitializationState type public. Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 const GURL& request_url = request_summary.request_url;
74 DCHECK(request_url.is_valid());
75 if (!request_url.is_valid())
76 return;
77
78 GURL origin = request_url.GetOrigin();
79 auto it = summaries->find(origin);
80 if (it == summaries->end()) {
81 ResourcePrefetchPredictor::OriginRequestSummary summary;
82 summary.origin = origin;
83 summary.first_occurrence = summaries->size();
84 it = summaries->insert({origin, summary}).first;
85 }
86
87 it->second.always_access_network |=
88 request_summary.always_revalidate || request_summary.is_no_store;
89 it->second.accessed_network |= request_summary.network_accessed;
90 }
91
92 void InitializeOriginStatFromOriginRequestSummary( 70 void InitializeOriginStatFromOriginRequestSummary(
93 OriginStat* origin, 71 OriginStat* origin,
94 const ResourcePrefetchPredictor::OriginRequestSummary& summary) { 72 const ResourcePrefetchPredictor::OriginRequestSummary& summary) {
95 origin->set_origin(summary.origin.spec()); 73 origin->set_origin(summary.origin.spec());
96 origin->set_number_of_hits(1); 74 origin->set_number_of_hits(1);
97 origin->set_average_position(summary.first_occurrence + 1); 75 origin->set_average_position(summary.first_occurrence + 1);
98 origin->set_always_access_network(summary.always_access_network); 76 origin->set_always_access_network(summary.always_access_network);
99 origin->set_accessed_network(summary.accessed_network); 77 origin->set_accessed_network(summary.accessed_network);
100 } 78 }
101 79
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 384
407 // Storage objects have to be initialized on a DB thread. 385 // Storage objects have to be initialized on a DB thread.
408 BrowserThread::PostTaskAndReply( 386 BrowserThread::PostTaskAndReply(
409 BrowserThread::DB, FROM_HERE, 387 BrowserThread::DB, FROM_HERE,
410 base::BindOnce(&ResourcePrefetchPredictor::InitializeOnDBThread, 388 base::BindOnce(&ResourcePrefetchPredictor::InitializeOnDBThread,
411 base::Unretained(this)), 389 base::Unretained(this)),
412 base::BindOnce(&ResourcePrefetchPredictor::ConnectToHistoryService, 390 base::BindOnce(&ResourcePrefetchPredictor::ConnectToHistoryService,
413 AsWeakPtr())); 391 AsWeakPtr()));
414 } 392 }
415 393
416 void ResourcePrefetchPredictor::RecordURLRequest(
417 const URLRequestSummary& request) {
418 DCHECK_CURRENTLY_ON(BrowserThread::UI);
419 if (initialization_state_ != INITIALIZED)
420 return;
421
422 CHECK_EQ(request.resource_type, content::RESOURCE_TYPE_MAIN_FRAME);
423 OnMainFrameRequest(request);
424 }
425
426 void ResourcePrefetchPredictor::RecordURLResponse(
427 const URLRequestSummary& response) {
428 DCHECK_CURRENTLY_ON(BrowserThread::UI);
429 if (initialization_state_ != INITIALIZED)
430 return;
431
432 if (response.resource_type != content::RESOURCE_TYPE_MAIN_FRAME)
433 OnSubresourceResponse(response);
434 }
435
436 void ResourcePrefetchPredictor::RecordURLRedirect(
437 const URLRequestSummary& response) {
438 DCHECK_CURRENTLY_ON(BrowserThread::UI);
439 if (initialization_state_ != INITIALIZED)
440 return;
441
442 if (response.resource_type == content::RESOURCE_TYPE_MAIN_FRAME)
443 OnMainFrameRedirect(response);
444 else
445 OnSubresourceRedirect(response);
446 }
447
448 void ResourcePrefetchPredictor::RecordMainFrameLoadComplete(
449 const NavigationID& navigation_id) {
450 switch (initialization_state_) {
451 case NOT_INITIALIZED:
452 StartInitialization();
453 break;
454 case INITIALIZING:
455 break;
456 case INITIALIZED:
457 // WebContents can return an empty URL if the navigation entry
458 // corresponding to the navigation has not been created yet.
459 if (!navigation_id.main_frame_url.is_empty())
460 OnNavigationComplete(navigation_id);
461 break;
462 default:
463 NOTREACHED() << "Unexpected initialization_state_: "
464 << initialization_state_;
465 }
466 }
467
468 void ResourcePrefetchPredictor::RecordFirstContentfulPaint(
469 const NavigationID& navigation_id,
470 const base::TimeTicks& first_contentful_paint) {
471 DCHECK_CURRENTLY_ON(BrowserThread::UI);
472 if (initialization_state_ != INITIALIZED)
473 return;
474
475 NavigationMap::iterator nav_it = inflight_navigations_.find(navigation_id);
476 if (nav_it != inflight_navigations_.end())
477 nav_it->second->first_contentful_paint = first_contentful_paint;
478 }
479
480 void ResourcePrefetchPredictor::OnPrefetchingFinished( 394 void ResourcePrefetchPredictor::OnPrefetchingFinished(
481 const GURL& main_frame_url, 395 const GURL& main_frame_url,
482 std::unique_ptr<ResourcePrefetcher::PrefetcherStats> stats) { 396 std::unique_ptr<ResourcePrefetcher::PrefetcherStats> stats) {
483 if (observer_) 397 if (observer_)
484 observer_->OnPrefetchingFinished(main_frame_url); 398 observer_->OnPrefetchingFinished(main_frame_url);
485 399
486 if (stats_collector_) 400 if (stats_collector_)
487 stats_collector_->RecordPrefetcherStats(std::move(stats)); 401 stats_collector_->RecordPrefetcherStats(std::move(stats));
488 } 402 }
489 403
(...skipping 21 matching lines...) Expand all
511 } 425 }
512 426
513 void ResourcePrefetchPredictor::Shutdown() { 427 void ResourcePrefetchPredictor::Shutdown() {
514 if (prefetch_manager_.get()) { 428 if (prefetch_manager_.get()) {
515 prefetch_manager_->ShutdownOnUIThread(); 429 prefetch_manager_->ShutdownOnUIThread();
516 prefetch_manager_ = NULL; 430 prefetch_manager_ = NULL;
517 } 431 }
518 history_service_observer_.RemoveAll(); 432 history_service_observer_.RemoveAll();
519 } 433 }
520 434
521 void ResourcePrefetchPredictor::OnMainFrameRequest( 435 void ResourcePrefetchPredictor::HandlePageRequestSummary(
522 const URLRequestSummary& request) { 436 std::unique_ptr<PageRequestSummary> summary) {
523 DCHECK_CURRENTLY_ON(BrowserThread::UI);
524 DCHECK_EQ(INITIALIZED, initialization_state_);
525
526 CleanupAbandonedNavigations(request.navigation_id);
527
528 // New empty navigation entry.
529 const GURL& main_frame_url = request.navigation_id.main_frame_url;
530 inflight_navigations_.emplace(
531 request.navigation_id,
532 base::MakeUnique<PageRequestSummary>(main_frame_url));
533 }
534
535 void ResourcePrefetchPredictor::OnMainFrameRedirect(
536 const URLRequestSummary& response) {
537 DCHECK_CURRENTLY_ON(BrowserThread::UI);
538 DCHECK_EQ(INITIALIZED, initialization_state_);
539
540 const GURL& main_frame_url = response.navigation_id.main_frame_url;
541 std::unique_ptr<PageRequestSummary> summary;
542 NavigationMap::iterator nav_it =
543 inflight_navigations_.find(response.navigation_id);
544 if (nav_it != inflight_navigations_.end()) {
545 summary = std::move(nav_it->second);
546 inflight_navigations_.erase(nav_it);
547 }
548
549 // The redirect url may be empty if the URL was invalid.
550 if (response.redirect_url.is_empty())
551 return;
552
553 // If we lost the information about the first hop for some reason.
554 if (!summary) {
555 summary = base::MakeUnique<PageRequestSummary>(main_frame_url);
556 }
557
558 // A redirect will not lead to another OnMainFrameRequest call, so record the
559 // redirect url as a new navigation id and save the initial url.
560 NavigationID navigation_id(response.navigation_id);
561 navigation_id.main_frame_url = response.redirect_url;
562 summary->main_frame_url = response.redirect_url;
563 inflight_navigations_.emplace(navigation_id, std::move(summary));
564 }
565
566 void ResourcePrefetchPredictor::OnSubresourceResponse(
567 const URLRequestSummary& response) {
568 DCHECK_CURRENTLY_ON(BrowserThread::UI);
569 DCHECK_EQ(INITIALIZED, initialization_state_);
570
571 NavigationMap::const_iterator nav_it =
572 inflight_navigations_.find(response.navigation_id);
573 if (nav_it == inflight_navigations_.end())
574 return;
575 auto& page_request_summary = *nav_it->second;
576
577 if (!response.is_no_store)
578 page_request_summary.subresource_requests.push_back(response);
579
580 if (config_.is_origin_learning_enabled)
581 UpdateOrAddToOrigins(&page_request_summary.origins, response);
582 }
583
584 void ResourcePrefetchPredictor::OnSubresourceRedirect(
585 const URLRequestSummary& response) {
586 DCHECK_CURRENTLY_ON(BrowserThread::UI);
587 DCHECK_EQ(INITIALIZED, initialization_state_);
588
589 if (!config_.is_origin_learning_enabled)
590 return;
591
592 NavigationMap::const_iterator nav_it =
593 inflight_navigations_.find(response.navigation_id);
594 if (nav_it == inflight_navigations_.end())
595 return;
596 auto& page_request_summary = *nav_it->second;
597 UpdateOrAddToOrigins(&page_request_summary.origins, response);
598 }
599
600 void ResourcePrefetchPredictor::OnNavigationComplete(
601 const NavigationID& nav_id_without_timing_info) {
602 DCHECK_CURRENTLY_ON(BrowserThread::UI);
603 DCHECK_EQ(INITIALIZED, initialization_state_);
604
605 NavigationMap::iterator nav_it =
606 inflight_navigations_.find(nav_id_without_timing_info);
607 if (nav_it == inflight_navigations_.end())
608 return;
609
610 // Remove the navigation from the inflight navigations.
611 std::unique_ptr<PageRequestSummary> summary = std::move(nav_it->second);
612 inflight_navigations_.erase(nav_it);
613
614 // Set before_first_contentful paint for each resource.
615 for (auto& request_summary : summary->subresource_requests) {
616 request_summary.before_first_contentful_paint =
617 request_summary.response_time < summary->first_contentful_paint;
618 }
619
620 if (stats_collector_)
621 stats_collector_->RecordPageRequestSummary(*summary);
622
623 // Kick off history lookup to determine if we should record the URL. 437 // Kick off history lookup to determine if we should record the URL.
624 history::HistoryService* history_service = 438 history::HistoryService* history_service =
625 HistoryServiceFactory::GetForProfile(profile_, 439 HistoryServiceFactory::GetForProfile(profile_,
626 ServiceAccessType::EXPLICIT_ACCESS); 440 ServiceAccessType::EXPLICIT_ACCESS);
627 DCHECK(history_service); 441 DCHECK(history_service);
628 history_service->ScheduleDBTask( 442 history_service->ScheduleDBTask(
629 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( 443 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask(
630 std::move(summary), 444 std::move(summary),
631 base::BindOnce(&ResourcePrefetchPredictor::OnVisitCountLookup, 445 base::BindOnce(&ResourcePrefetchPredictor::OnVisitCountLookup,
632 AsWeakPtr()))), 446 AsWeakPtr()))),
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 if (config_.IsPrefetchingEnabledForSomeOrigin(profile_)) { 597 if (config_.IsPrefetchingEnabledForSomeOrigin(profile_)) {
784 prefetch_manager_ = new ResourcePrefetcherManager( 598 prefetch_manager_ = new ResourcePrefetcherManager(
785 this, config_, profile_->GetRequestContext()); 599 this, config_, profile_->GetRequestContext());
786 } 600 }
787 initialization_state_ = INITIALIZED; 601 initialization_state_ = INITIALIZED;
788 602
789 if (observer_) 603 if (observer_)
790 observer_->OnPredictorInitialized(); 604 observer_->OnPredictorInitialized();
791 } 605 }
792 606
793 void ResourcePrefetchPredictor::CleanupAbandonedNavigations(
794 const NavigationID& navigation_id) {
795 if (stats_collector_)
796 stats_collector_->CleanupAbandonedStats();
797
798 static const base::TimeDelta max_navigation_age =
799 base::TimeDelta::FromSeconds(config_.max_navigation_lifetime_seconds);
800
801 base::TimeTicks time_now = base::TimeTicks::Now();
802 for (NavigationMap::iterator it = inflight_navigations_.begin();
803 it != inflight_navigations_.end();) {
804 if ((it->first.tab_id == navigation_id.tab_id) ||
805 (time_now - it->first.creation_time > max_navigation_age)) {
806 inflight_navigations_.erase(it++);
807 } else {
808 ++it;
809 }
810 }
811 }
812
813 void ResourcePrefetchPredictor::DeleteAllUrls() { 607 void ResourcePrefetchPredictor::DeleteAllUrls() {
814 inflight_navigations_.clear(); 608 inflight_navigations_.clear();
815 609
816 url_resource_data_->DeleteAllData(); 610 url_resource_data_->DeleteAllData();
817 host_resource_data_->DeleteAllData(); 611 host_resource_data_->DeleteAllData();
818 url_redirect_data_->DeleteAllData(); 612 url_redirect_data_->DeleteAllData();
819 host_redirect_data_->DeleteAllData(); 613 host_redirect_data_->DeleteAllData();
820 manifest_data_->DeleteAllData(); 614 manifest_data_->DeleteAllData();
821 origin_data_->DeleteAllData(); 615 origin_data_->DeleteAllData();
822 } 616 }
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
1340 TestObserver::~TestObserver() { 1134 TestObserver::~TestObserver() {
1341 predictor_->SetObserverForTesting(nullptr); 1135 predictor_->SetObserverForTesting(nullptr);
1342 } 1136 }
1343 1137
1344 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) 1138 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor)
1345 : predictor_(predictor) { 1139 : predictor_(predictor) {
1346 predictor_->SetObserverForTesting(this); 1140 predictor_->SetObserverForTesting(this);
1347 } 1141 }
1348 1142
1349 } // namespace predictors 1143 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698