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

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

Issue 2321343002: Redirect handling in resource prefetch predictor (Closed)
Patch Set: test Created 4 years, 3 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 //////////////////////////////////////////////////////////////////////////////// 68 ////////////////////////////////////////////////////////////////////////////////
69 // History lookup task. 69 // History lookup task.
70 70
71 // Used to fetch the visit count for a URL from the History database. 71 // Used to fetch the visit count for a URL from the History database.
72 class GetUrlVisitCountTask : public history::HistoryDBTask { 72 class GetUrlVisitCountTask : public history::HistoryDBTask {
73 public: 73 public:
74 typedef ResourcePrefetchPredictor::URLRequestSummary URLRequestSummary; 74 typedef ResourcePrefetchPredictor::URLRequestSummary URLRequestSummary;
75 typedef base::Callback<void( 75 typedef base::Callback<void(
76 size_t, // Visit count. 76 size_t, // Visit count.
77 const NavigationID&, 77 const NavigationID&,
78 const std::vector<URLRequestSummary>&)> VisitInfoCallback; 78 const std::vector<URLRequestSummary>&,
79 std::vector<GURL>*)> VisitInfoCallback;
79 80
80 GetUrlVisitCountTask( 81 GetUrlVisitCountTask(
81 const NavigationID& navigation_id, 82 const NavigationID& navigation_id,
82 std::vector<URLRequestSummary>* requests, 83 std::unique_ptr<std::vector<URLRequestSummary>> requests,
84 std::unique_ptr<std::vector<GURL>> redirects,
83 VisitInfoCallback callback) 85 VisitInfoCallback callback)
84 : visit_count_(0), 86 : visit_count_(0),
85 navigation_id_(navigation_id), 87 navigation_id_(navigation_id),
86 requests_(requests), 88 requests_(std::move(requests)),
89 redirects_(std::move(redirects)),
87 callback_(callback) { 90 callback_(callback) {
88 DCHECK(requests_.get()); 91 DCHECK(requests_.get());
89 } 92 }
90 93
91 bool RunOnDBThread(history::HistoryBackend* backend, 94 bool RunOnDBThread(history::HistoryBackend* backend,
92 history::HistoryDatabase* db) override { 95 history::HistoryDatabase* db) override {
93 history::URLRow url_row; 96 history::URLRow url_row;
94 if (db->GetRowForURL(navigation_id_.main_frame_url, &url_row)) 97 if (db->GetRowForURL(navigation_id_.main_frame_url, &url_row))
95 visit_count_ = url_row.visit_count(); 98 visit_count_ = url_row.visit_count();
96 return true; 99 return true;
97 } 100 }
98 101
99 void DoneRunOnMainThread() override { 102 void DoneRunOnMainThread() override {
100 callback_.Run(visit_count_, navigation_id_, *requests_); 103 callback_.Run(visit_count_, navigation_id_, *requests_, redirects_.get());
101 } 104 }
102 105
103 private: 106 private:
104 ~GetUrlVisitCountTask() override {} 107 ~GetUrlVisitCountTask() override {}
105 108
106 int visit_count_; 109 int visit_count_;
107 NavigationID navigation_id_; 110 NavigationID navigation_id_;
108 std::unique_ptr<std::vector<URLRequestSummary>> requests_; 111 std::unique_ptr<std::vector<URLRequestSummary>> requests_;
112 std::unique_ptr<std::vector<GURL>> redirects_;
109 VisitInfoCallback callback_; 113 VisitInfoCallback callback_;
110 114
111 DISALLOW_COPY_AND_ASSIGN(GetUrlVisitCountTask); 115 DISALLOW_COPY_AND_ASSIGN(GetUrlVisitCountTask);
112 }; 116 };
113 117
114 //////////////////////////////////////////////////////////////////////////////// 118 ////////////////////////////////////////////////////////////////////////////////
115 // ResourcePrefetchPredictor static functions. 119 // ResourcePrefetchPredictor static functions.
116 120
117 // static 121 // static
118 bool ResourcePrefetchPredictor::ShouldRecordRequest( 122 bool ResourcePrefetchPredictor::ShouldRecordRequest(
119 net::URLRequest* request, 123 net::URLRequest* request,
120 content::ResourceType resource_type) { 124 content::ResourceType resource_type) {
121 const content::ResourceRequestInfo* request_info = 125 const content::ResourceRequestInfo* request_info =
122 content::ResourceRequestInfo::ForRequest(request); 126 content::ResourceRequestInfo::ForRequest(request);
123 if (!request_info) 127 if (!request_info)
124 return false; 128 return false;
125 129
126 if (!request_info->IsMainFrame()) 130 if (!request_info->IsMainFrame())
127 return false; 131 return false;
128 132
129 return resource_type == content::RESOURCE_TYPE_MAIN_FRAME && 133 return resource_type == content::RESOURCE_TYPE_MAIN_FRAME &&
130 IsHandledMainPage(request); 134 IsHandledMainPage(request);
131 } 135 }
132 136
137 // comment to delete
138
133 // static 139 // static
134 bool ResourcePrefetchPredictor::ShouldRecordResponse( 140 bool ResourcePrefetchPredictor::ShouldRecordResponse(
135 net::URLRequest* response) { 141 net::URLRequest* response) {
136 const content::ResourceRequestInfo* request_info = 142 const content::ResourceRequestInfo* request_info =
137 content::ResourceRequestInfo::ForRequest(response); 143 content::ResourceRequestInfo::ForRequest(response);
138 if (!request_info) 144 if (!request_info)
139 return false; 145 return false;
140 146
141 if (!request_info->IsMainFrame()) 147 if (!request_info->IsMainFrame())
142 return false; 148 return false;
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 prefetch_manager_ = NULL; 430 prefetch_manager_ = NULL;
425 } 431 }
426 history_service_observer_.RemoveAll(); 432 history_service_observer_.RemoveAll();
427 } 433 }
428 434
429 void ResourcePrefetchPredictor::OnMainFrameRequest( 435 void ResourcePrefetchPredictor::OnMainFrameRequest(
430 const URLRequestSummary& request) { 436 const URLRequestSummary& request) {
431 DCHECK_CURRENTLY_ON(BrowserThread::UI); 437 DCHECK_CURRENTLY_ON(BrowserThread::UI);
432 DCHECK_EQ(INITIALIZED, initialization_state_); 438 DCHECK_EQ(INITIALIZED, initialization_state_);
433 439
440 VLOG(1) << "Requested URL: " << request.navigation_id.main_frame_url;
mattcary 2016/09/09 09:16:11 These logging messages are probably too verbose fo
alexilin 2016/09/09 13:59:19 Sure, I added them just to find out what's what.
441
434 StartPrefetching(request.navigation_id); 442 StartPrefetching(request.navigation_id);
435 443
436 // Cleanup older navigations. 444 // Cleanup older navigations.
437 CleanupAbandonedNavigations(request.navigation_id); 445 CleanupAbandonedNavigations(request.navigation_id);
438 446
439 // New empty navigation entry. 447 // New empty navigation entry.
440 inflight_navigations_.insert(std::make_pair( 448 inflight_navigations_.insert(std::make_pair(
441 request.navigation_id, 449 request.navigation_id,
442 make_linked_ptr(new std::vector<URLRequestSummary>()))); 450 make_linked_ptr(new std::vector<URLRequestSummary>())));
443 } 451 }
444 452
445 void ResourcePrefetchPredictor::OnMainFrameResponse( 453 void ResourcePrefetchPredictor::OnMainFrameResponse(
446 const URLRequestSummary& response) { 454 const URLRequestSummary& response) {
447 DCHECK_CURRENTLY_ON(BrowserThread::UI); 455 DCHECK_CURRENTLY_ON(BrowserThread::UI);
448 if (initialization_state_ != INITIALIZED) 456 if (initialization_state_ != INITIALIZED)
449 return; 457 return;
450 458
459 VLOG(1) << "Main frame got response (" <<
460 response.navigation_id.main_frame_url << ")";
461
451 StopPrefetching(response.navigation_id); 462 StopPrefetching(response.navigation_id);
452 } 463 }
453 464
454 void ResourcePrefetchPredictor::OnMainFrameRedirect( 465 void ResourcePrefetchPredictor::OnMainFrameRedirect(
455 const URLRequestSummary& response) { 466 const URLRequestSummary& response) {
456 DCHECK_CURRENTLY_ON(BrowserThread::UI); 467 DCHECK_CURRENTLY_ON(BrowserThread::UI);
457 468
469 VLOG(1) << "Redirect from " << response.navigation_id.main_frame_url
470 << " to " << response.redirect_url;
471
458 // TODO(shishir): There are significant gains to be had here if we can use the 472 // TODO(shishir): There are significant gains to be had here if we can use the
459 // start URL in a redirect chain as the key to start prefetching. We can save 473 // start URL in a redirect chain as the key to start prefetching. We can save
460 // of redirect times considerably assuming that the redirect chains do not 474 // of redirect times considerably assuming that the redirect chains do not
461 // change. 475 // change.
462 476
463 // Stop any inflight prefetching. Remove the older navigation. 477 // Stop any inflight prefetching. Remove the older navigation.
464 StopPrefetching(response.navigation_id); 478 StopPrefetching(response.navigation_id);
465 inflight_navigations_.erase(response.navigation_id); 479 inflight_navigations_.erase(response.navigation_id);
466 480
481 RedirectsMap::iterator redir_it = redirects_map_.find(response.navigation_id);
482 std::vector<GURL>* redirects_chain = nullptr;
483 if (redir_it != redirects_map_.end())
484 {
485 redirects_chain = (redir_it->second).release();
486 redirects_map_.erase(redir_it);
487 }
488
467 // A redirect will not lead to another OnMainFrameRequest call, so record the 489 // A redirect will not lead to another OnMainFrameRequest call, so record the
468 // redirect url as a new navigation. 490 // redirect url as a new navigation.
469 491
470 // The redirect url may be empty if the URL was invalid. 492 // The redirect url may be empty if the URL was invalid.
471 if (response.redirect_url.is_empty()) 493 if (response.redirect_url.is_empty())
472 return; 494 return;
473 495
496 if (redirects_chain == nullptr)
497 redirects_chain = new std::vector<GURL>();
498 redirects_chain->push_back(response.navigation_id.main_frame_url);
499
474 NavigationID navigation_id(response.navigation_id); 500 NavigationID navigation_id(response.navigation_id);
475 navigation_id.main_frame_url = response.redirect_url; 501 navigation_id.main_frame_url = response.redirect_url;
476 inflight_navigations_.insert(std::make_pair( 502 inflight_navigations_.insert(std::make_pair(
477 navigation_id, 503 navigation_id,
478 make_linked_ptr(new std::vector<URLRequestSummary>()))); 504 make_linked_ptr(new std::vector<URLRequestSummary>())));
505 redirects_map_.insert(std::make_pair(
506 navigation_id,
507 make_linked_ptr(redirects_chain)));
479 } 508 }
480 509
481 void ResourcePrefetchPredictor::OnSubresourceResponse( 510 void ResourcePrefetchPredictor::OnSubresourceResponse(
482 const URLRequestSummary& response) { 511 const URLRequestSummary& response) {
483 DCHECK_CURRENTLY_ON(BrowserThread::UI); 512 DCHECK_CURRENTLY_ON(BrowserThread::UI);
484 513
485 NavigationMap::const_iterator nav_it = 514 NavigationMap::const_iterator nav_it =
486 inflight_navigations_.find(response.navigation_id); 515 inflight_navigations_.find(response.navigation_id);
487 if (nav_it == inflight_navigations_.end()) { 516 if (nav_it == inflight_navigations_.end()) {
488 return; 517 return;
489 } 518 }
490 519
491 nav_it->second->push_back(response); 520 nav_it->second->push_back(response);
492 } 521 }
493 522
494 void ResourcePrefetchPredictor::OnNavigationComplete( 523 void ResourcePrefetchPredictor::OnNavigationComplete(
495 const NavigationID& nav_id_without_timing_info) { 524 const NavigationID& nav_id_without_timing_info) {
496 DCHECK_CURRENTLY_ON(BrowserThread::UI); 525 DCHECK_CURRENTLY_ON(BrowserThread::UI);
497 526
527 VLOG(1) << "Navigation completed (" <<
528 nav_id_without_timing_info.main_frame_url << ")";
529
498 NavigationMap::iterator nav_it = 530 NavigationMap::iterator nav_it =
499 inflight_navigations_.find(nav_id_without_timing_info); 531 inflight_navigations_.find(nav_id_without_timing_info);
500 if (nav_it == inflight_navigations_.end()) 532 if (nav_it == inflight_navigations_.end())
501 return; 533 return;
502 534
503 const NavigationID navigation_id(nav_it->first); 535 const NavigationID navigation_id(nav_it->first);
504 536
505 // Remove the navigation from the inflight navigations. 537 // Remove the navigation from the inflight navigations.
506 std::vector<URLRequestSummary>* requests = (nav_it->second).release(); 538 std::vector<URLRequestSummary>* requests = (nav_it->second).release();
507 inflight_navigations_.erase(nav_it); 539 inflight_navigations_.erase(nav_it);
508 540
541 std::vector<GURL>* redirects = nullptr;
542 RedirectsMap::iterator redir_it = redirects_map_.find(navigation_id);
543 if (redir_it != redirects_map_.end()) {
544 redirects = (redir_it->second).release();
545 redirects_map_.erase(redir_it);
546 }
547
509 // Kick off history lookup to determine if we should record the URL. 548 // Kick off history lookup to determine if we should record the URL.
510 history::HistoryService* history_service = 549 history::HistoryService* history_service =
511 HistoryServiceFactory::GetForProfile(profile_, 550 HistoryServiceFactory::GetForProfile(profile_,
512 ServiceAccessType::EXPLICIT_ACCESS); 551 ServiceAccessType::EXPLICIT_ACCESS);
513 DCHECK(history_service); 552 DCHECK(history_service);
514 history_service->ScheduleDBTask( 553 history_service->ScheduleDBTask(
515 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( 554 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask(
516 navigation_id, requests, 555 navigation_id,
556 std::unique_ptr<std::vector<URLRequestSummary>>(requests),
557 std::unique_ptr<std::vector<GURL>>(redirects),
517 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, 558 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup,
518 AsWeakPtr()))), 559 AsWeakPtr()))),
519 &history_lookup_consumer_); 560 &history_lookup_consumer_);
520 } 561 }
521 562
522 bool ResourcePrefetchPredictor::GetPrefetchData( 563 bool ResourcePrefetchPredictor::GetPrefetchData(
523 const NavigationID& navigation_id, 564 const NavigationID& navigation_id,
524 ResourcePrefetcher::RequestVector* prefetch_requests, 565 ResourcePrefetcher::RequestVector* prefetch_requests,
525 PrefetchKeyType* key_type) { 566 PrefetchKeyType* key_type) {
526 DCHECK(prefetch_requests); 567 DCHECK(prefetch_requests);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 650
610 void ResourcePrefetchPredictor::StartInitialization() { 651 void ResourcePrefetchPredictor::StartInitialization() {
611 DCHECK_CURRENTLY_ON(BrowserThread::UI); 652 DCHECK_CURRENTLY_ON(BrowserThread::UI);
612 653
613 DCHECK_EQ(NOT_INITIALIZED, initialization_state_); 654 DCHECK_EQ(NOT_INITIALIZED, initialization_state_);
614 initialization_state_ = INITIALIZING; 655 initialization_state_ = INITIALIZING;
615 656
616 // Create local caches using the database as loaded. 657 // Create local caches using the database as loaded.
617 std::unique_ptr<PrefetchDataMap> url_data_map(new PrefetchDataMap()); 658 std::unique_ptr<PrefetchDataMap> url_data_map(new PrefetchDataMap());
618 std::unique_ptr<PrefetchDataMap> host_data_map(new PrefetchDataMap()); 659 std::unique_ptr<PrefetchDataMap> host_data_map(new PrefetchDataMap());
660 std::unique_ptr<RedirectDataMap> url_redirect_data_map(
661 new RedirectDataMap());
662 std::unique_ptr<RedirectDataMap> host_redirect_data_map(
663 new RedirectDataMap());
619 PrefetchDataMap* url_data_ptr = url_data_map.get(); 664 PrefetchDataMap* url_data_ptr = url_data_map.get();
620 PrefetchDataMap* host_data_ptr = host_data_map.get(); 665 PrefetchDataMap* host_data_ptr = host_data_map.get();
666 RedirectDataMap* url_redirect_data_ptr = url_redirect_data_map.get();
667 RedirectDataMap* host_redirect_data_ptr = host_redirect_data_map.get();
621 668
622 BrowserThread::PostTaskAndReply( 669 BrowserThread::PostTaskAndReply(
623 BrowserThread::DB, FROM_HERE, 670 BrowserThread::DB, FROM_HERE,
624 base::Bind(&ResourcePrefetchPredictorTables::GetAllData, 671 base::Bind(&ResourcePrefetchPredictorTables::GetAllData, tables_,
625 tables_, url_data_ptr, host_data_ptr), 672 url_data_ptr,
673 host_data_ptr,
674 url_redirect_data_ptr,
675 host_redirect_data_ptr),
626 base::Bind(&ResourcePrefetchPredictor::CreateCaches, AsWeakPtr(), 676 base::Bind(&ResourcePrefetchPredictor::CreateCaches, AsWeakPtr(),
627 base::Passed(&url_data_map), base::Passed(&host_data_map))); 677 base::Passed(&url_data_map),
678 base::Passed(&host_data_map),
679 base::Passed(&url_redirect_data_map),
680 base::Passed(&host_redirect_data_map)));
628 } 681 }
629 682
630 void ResourcePrefetchPredictor::CreateCaches( 683 void ResourcePrefetchPredictor::CreateCaches(
631 std::unique_ptr<PrefetchDataMap> url_data_map, 684 std::unique_ptr<PrefetchDataMap> url_data_map,
632 std::unique_ptr<PrefetchDataMap> host_data_map) { 685 std::unique_ptr<PrefetchDataMap> host_data_map,
686 std::unique_ptr<RedirectDataMap> url_redirect_data_map,
687 std::unique_ptr<RedirectDataMap> host_redirect_data_map) {
633 DCHECK_CURRENTLY_ON(BrowserThread::UI); 688 DCHECK_CURRENTLY_ON(BrowserThread::UI);
634 689
635 DCHECK_EQ(INITIALIZING, initialization_state_); 690 DCHECK_EQ(INITIALIZING, initialization_state_);
636 DCHECK(!url_table_cache_); 691 DCHECK(!url_table_cache_);
637 DCHECK(!host_table_cache_); 692 DCHECK(!host_table_cache_);
693 DCHECK(!url_redirect_table_cache_);
694 DCHECK(!host_redirect_table_cache_);
638 DCHECK(inflight_navigations_.empty()); 695 DCHECK(inflight_navigations_.empty());
639 696
640 url_table_cache_.reset(url_data_map.release()); 697 url_table_cache_.reset(url_data_map.release());
641 host_table_cache_.reset(host_data_map.release()); 698 host_table_cache_.reset(host_data_map.release());
699 url_redirect_table_cache_.reset(url_redirect_data_map.release());
700 host_redirect_table_cache_.reset(host_redirect_data_map.release());
642 701
643 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.UrlTableMainFrameUrlCount", 702 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.UrlTableMainFrameUrlCount",
644 url_table_cache_->size()); 703 url_table_cache_->size());
645 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostTableHostCount", 704 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostTableHostCount",
646 host_table_cache_->size()); 705 host_table_cache_->size());
647 706
648 ConnectToHistoryService(); 707 ConnectToHistoryService();
649 } 708 }
650 709
651 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() { 710 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() {
(...skipping 25 matching lines...) Expand all
677 } 736 }
678 for (ResultsMap::const_iterator it = results_map_.begin(); 737 for (ResultsMap::const_iterator it = results_map_.begin();
679 it != results_map_.end();) { 738 it != results_map_.end();) {
680 if (it->first.IsSameRenderer(navigation_id) || 739 if (it->first.IsSameRenderer(navigation_id) ||
681 (time_now - it->first.creation_time > max_navigation_age)) { 740 (time_now - it->first.creation_time > max_navigation_age)) {
682 results_map_.erase(it++); 741 results_map_.erase(it++);
683 } else { 742 } else {
684 ++it; 743 ++it;
685 } 744 }
686 } 745 }
746 for (RedirectsMap::iterator it = redirects_map_.begin();
747 it != redirects_map_.end();) {
748 if (it->first.IsSameRenderer(navigation_id) ||
749 (time_now - it->first.creation_time > max_navigation_age)) {
750 redirects_map_.erase(it++);
751 } else {
752 ++it;
753 }
754 }
687 } 755 }
688 756
689 void ResourcePrefetchPredictor::DeleteAllUrls() { 757 void ResourcePrefetchPredictor::DeleteAllUrls() {
690 inflight_navigations_.clear(); 758 inflight_navigations_.clear();
691 url_table_cache_->clear(); 759 url_table_cache_->clear();
692 host_table_cache_->clear(); 760 host_table_cache_->clear();
693 761
694 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 762 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
695 base::Bind(&ResourcePrefetchPredictorTables::DeleteAllData, tables_)); 763 base::Bind(&ResourcePrefetchPredictorTables::DeleteAllData, tables_));
696 } 764 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 811 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
744 base::Bind(&ResourcePrefetchPredictorTables::DeleteSingleDataPoint, 812 base::Bind(&ResourcePrefetchPredictorTables::DeleteSingleDataPoint,
745 tables_, 813 tables_,
746 key_to_delete, 814 key_to_delete,
747 key_type)); 815 key_type));
748 } 816 }
749 817
750 void ResourcePrefetchPredictor::OnVisitCountLookup( 818 void ResourcePrefetchPredictor::OnVisitCountLookup(
751 size_t visit_count, 819 size_t visit_count,
752 const NavigationID& navigation_id, 820 const NavigationID& navigation_id,
753 const std::vector<URLRequestSummary>& requests) { 821 const std::vector<URLRequestSummary>& requests,
822 std::vector<GURL>* redirects) {
754 DCHECK_CURRENTLY_ON(BrowserThread::UI); 823 DCHECK_CURRENTLY_ON(BrowserThread::UI);
755 824
756 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HistoryVisitCountForUrl", 825 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HistoryVisitCountForUrl",
757 visit_count); 826 visit_count);
758 827
828 // (@alexilin) FOR DEBUG
829 if (redirects != nullptr) {
830 std::string chain_string;
831 for (GURL& link : *redirects)
832 {
833 chain_string += link.spec();
834 chain_string += "->";
835 }
836 chain_string += navigation_id.main_frame_url.spec();
837 VLOG(1) << "Redirects chain: " << chain_string;
838 } else {
839 VLOG(1) << "No redirects";
840 }
841 // DELETE IT
842
759 // URL level data - merge only if we are already saving the data, or we it 843 // URL level data - merge only if we are already saving the data, or we it
760 // meets the cutoff requirement. 844 // meets the cutoff requirement.
761 const std::string url_spec = navigation_id.main_frame_url.spec(); 845 const std::string url_spec = navigation_id.main_frame_url.spec();
762 bool already_tracking = url_table_cache_->find(url_spec) != 846 bool already_tracking = url_table_cache_->find(url_spec) !=
763 url_table_cache_->end(); 847 url_table_cache_->end();
764 bool should_track_url = already_tracking || 848 bool should_track_url = already_tracking ||
765 (visit_count >= config_.min_url_visit_count); 849 (visit_count >= config_.min_url_visit_count);
766 850
767 if (should_track_url && config_.IsURLLearningEnabled()) { 851 if (should_track_url && config_.IsURLLearningEnabled()) {
852 VLOG(1) << "Learn by URL";
768 LearnNavigation(url_spec, PREFETCH_KEY_TYPE_URL, requests, 853 LearnNavigation(url_spec, PREFETCH_KEY_TYPE_URL, requests,
769 config_.max_urls_to_track, url_table_cache_.get()); 854 config_.max_urls_to_track, url_table_cache_.get());
855
856 if (redirects != nullptr) {
857 std::vector<std::string> redirect_urls;
858 for (GURL& redirect: *redirects) {
859 redirect_urls.push_back(redirect.spec());
860 }
861 LearnRedirects(redirect_urls, PREFETCH_KEY_TYPE_URL, url_spec,
862 config_.max_urls_to_track,
863 url_redirect_table_cache_.get());
864 }
770 } 865 }
771 866
772 // Host level data - no cutoff, always learn the navigation if enabled. 867 // Host level data - no cutoff, always learn the navigation if enabled.
773 if (config_.IsHostLearningEnabled()) { 868 if (config_.IsHostLearningEnabled()) {
774 LearnNavigation(navigation_id.main_frame_url.host(), 869 VLOG(1) << "Learn by host";
775 PREFETCH_KEY_TYPE_HOST, 870 const std::string host = navigation_id.main_frame_url.host();
776 requests, 871 LearnNavigation(host, PREFETCH_KEY_TYPE_HOST, requests,
777 config_.max_hosts_to_track, 872 config_.max_hosts_to_track, host_table_cache_.get());
778 host_table_cache_.get()); 873
874 if (redirects != nullptr) {
875 std::vector<std::string> redirect_hosts;
876 for (GURL& redirect : *redirects) {
877 redirect_hosts.push_back(redirect.host());
878 }
879 LearnRedirects(redirect_hosts, PREFETCH_KEY_TYPE_HOST, host,
880 config_.max_hosts_to_track,
881 host_redirect_table_cache_.get());
882 }
779 } 883 }
780 884
781 // Remove the navigation from the results map. 885 // Remove the navigation from the results map.
782 results_map_.erase(navigation_id); 886 results_map_.erase(navigation_id);
783 } 887 }
784 888
785 void ResourcePrefetchPredictor::LearnNavigation( 889 void ResourcePrefetchPredictor::LearnNavigation(
786 const std::string& key, 890 const std::string& key,
787 PrefetchKeyType key_type, 891 PrefetchKeyType key_type,
788 const std::vector<URLRequestSummary>& new_resources, 892 const std::vector<URLRequestSummary>& new_resources,
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 const PrefetchData& url_data = is_host ? empty_data : cache_entry->second; 1026 const PrefetchData& url_data = is_host ? empty_data : cache_entry->second;
923 BrowserThread::PostTask( 1027 BrowserThread::PostTask(
924 BrowserThread::DB, FROM_HERE, 1028 BrowserThread::DB, FROM_HERE,
925 base::Bind(&ResourcePrefetchPredictorTables::UpdateData, 1029 base::Bind(&ResourcePrefetchPredictorTables::UpdateData,
926 tables_, 1030 tables_,
927 url_data, 1031 url_data,
928 host_data)); 1032 host_data));
929 } 1033 }
930 } 1034 }
931 1035
1036 void ResourcePrefetchPredictor::LearnRedirects(
1037 const std::vector<std::string>& keys,
mattcary 2016/09/09 13:19:21 I wonder if it's necessary to store data on all th
alexilin 2016/09/09 13:59:19 Yes, you understand the code correctly. But in the
mattcary 2016/09/09 14:14:26 Yeah, I can't disagree with anything you said. +1
1038 PrefetchKeyType key_type,
1039 const std::string& final_redirect,
1040 size_t max_redirect_map_size,
1041 RedirectDataMap* redirect_map) {
1042 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1043
1044 std::set<std::string> visited_keys;
1045 for (const std::string& key : keys) {
1046
1047 if (visited_keys.find(key) != visited_keys.end())
1048 continue;
1049
1050 visited_keys.insert(key);
1051
1052 RedirectDataMap::iterator cache_entry = redirect_map->find(key);
1053 if (cache_entry == redirect_map->end()) {
1054 if (redirect_map->size() >= max_redirect_map_size) {
1055 // TODO: remove oldest entry
1056 }
1057
1058 cache_entry = redirect_map->insert(std::make_pair(
1059 key, RedirectData(key_type, key))).first;
1060 cache_entry->second.last_visit = base::Time::Now();
1061 RedirectStatRow row_to_add;
1062 row_to_add.final_redirect = final_redirect;
1063 row_to_add.number_of_hits = 1;
1064 cache_entry->second.redirect_stats.push_back(row_to_add);
1065 } else {
1066 cache_entry->second.last_visit = base::Time::Now();
1067 RedirectStatRows& redirect_stats = cache_entry->second.redirect_stats;
1068 bool need_to_add = true;
1069
1070 for (RedirectStatRow& redirect_stat : redirect_stats) {
1071 if (redirect_stat.final_redirect == final_redirect) {
1072 need_to_add = false;
1073 ++redirect_stat.number_of_hits;
1074 redirect_stat.consecutive_misses = 0;
1075 } else {
1076 ++redirect_stat.number_of_misses;
1077 ++redirect_stat.consecutive_misses;
1078 }
1079 }
1080
1081 if (need_to_add) {
1082 RedirectStatRow row_to_add;
1083 row_to_add.final_redirect = final_redirect;
1084 row_to_add.number_of_hits = 1;
1085 redirect_stats.push_back(row_to_add);
1086 }
1087 }
1088
1089 RedirectStatRows& redirect_stats = cache_entry->second.redirect_stats;
1090 // TODO: sort and trim redirect stats
1091
1092 // TODO: aggregate all changes in one DB access
1093 if (redirect_stats.empty()) {
1094 // TODO: remove database entry
1095 } else {
1096 // TODO: update database entry
1097 }
1098 }
1099 }
1100
932 void ResourcePrefetchPredictor::OnURLsDeleted( 1101 void ResourcePrefetchPredictor::OnURLsDeleted(
933 history::HistoryService* history_service, 1102 history::HistoryService* history_service,
934 bool all_history, 1103 bool all_history,
935 bool expired, 1104 bool expired,
936 const history::URLRows& deleted_rows, 1105 const history::URLRows& deleted_rows,
937 const std::set<GURL>& favicon_urls) { 1106 const std::set<GURL>& favicon_urls) {
938 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1107 DCHECK_CURRENTLY_ON(BrowserThread::UI);
939 if (INITIALIZED != initialization_state_) 1108 if (INITIALIZED != initialization_state_)
940 return; 1109 return;
941 1110
(...skipping 27 matching lines...) Expand all
969 // HistoryService is already loaded. Continue with Initialization. 1138 // HistoryService is already loaded. Continue with Initialization.
970 OnHistoryAndCacheLoaded(); 1139 OnHistoryAndCacheLoaded();
971 return; 1140 return;
972 } 1141 }
973 DCHECK(!history_service_observer_.IsObserving(history_service)); 1142 DCHECK(!history_service_observer_.IsObserving(history_service));
974 history_service_observer_.Add(history_service); 1143 history_service_observer_.Add(history_service);
975 return; 1144 return;
976 } 1145 }
977 1146
978 } // namespace predictors 1147 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698