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

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

Issue 2321343002: Redirect handling in resource prefetch predictor (Closed)
Patch Set: Update some comments 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 65
66 namespace predictors { 66 namespace predictors {
67 67
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 ResourcePrefetchPredictor::Navigation Navigation;
75 typedef base::Callback<void( 76 typedef base::Callback<void(
76 size_t, // Visit count. 77 size_t, // Visit count.
77 const NavigationID&, 78 const NavigationID&,
78 const std::vector<URLRequestSummary>&)> VisitInfoCallback; 79 const Navigation&)> 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<Navigation> navigation,
83 VisitInfoCallback callback) 84 VisitInfoCallback callback)
84 : visit_count_(0), 85 : visit_count_(0),
85 navigation_id_(navigation_id), 86 navigation_id_(navigation_id),
86 requests_(requests), 87 navigation_(std::move(navigation)),
87 callback_(callback) { 88 callback_(callback) {
88 DCHECK(requests_.get()); 89 DCHECK(navigation_.get());
89 } 90 }
90 91
91 bool RunOnDBThread(history::HistoryBackend* backend, 92 bool RunOnDBThread(history::HistoryBackend* backend,
92 history::HistoryDatabase* db) override { 93 history::HistoryDatabase* db) override {
93 history::URLRow url_row; 94 history::URLRow url_row;
94 if (db->GetRowForURL(navigation_id_.main_frame_url, &url_row)) 95 if (db->GetRowForURL(navigation_id_.main_frame_url, &url_row))
95 visit_count_ = url_row.visit_count(); 96 visit_count_ = url_row.visit_count();
96 return true; 97 return true;
97 } 98 }
98 99
99 void DoneRunOnMainThread() override { 100 void DoneRunOnMainThread() override {
100 callback_.Run(visit_count_, navigation_id_, *requests_); 101 callback_.Run(visit_count_, navigation_id_, *navigation_);
101 } 102 }
102 103
103 private: 104 private:
104 ~GetUrlVisitCountTask() override {} 105 ~GetUrlVisitCountTask() override {}
105 106
106 int visit_count_; 107 int visit_count_;
107 NavigationID navigation_id_; 108 NavigationID navigation_id_;
108 std::unique_ptr<std::vector<URLRequestSummary>> requests_; 109 std::unique_ptr<Navigation> navigation_;
109 VisitInfoCallback callback_; 110 VisitInfoCallback callback_;
110 111
111 DISALLOW_COPY_AND_ASSIGN(GetUrlVisitCountTask); 112 DISALLOW_COPY_AND_ASSIGN(GetUrlVisitCountTask);
112 }; 113 };
113 114
114 //////////////////////////////////////////////////////////////////////////////// 115 ////////////////////////////////////////////////////////////////////////////////
115 // ResourcePrefetchPredictor static functions. 116 // ResourcePrefetchPredictor static functions.
116 117
117 // static 118 // static
118 bool ResourcePrefetchPredictor::ShouldRecordRequest( 119 bool ResourcePrefetchPredictor::ShouldRecordRequest(
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 priority(other.priority), 275 priority(other.priority),
275 mime_type(other.mime_type), 276 mime_type(other.mime_type),
276 was_cached(other.was_cached), 277 was_cached(other.was_cached),
277 redirect_url(other.redirect_url), 278 redirect_url(other.redirect_url),
278 has_validators(other.has_validators), 279 has_validators(other.has_validators),
279 always_revalidate(other.always_revalidate) {} 280 always_revalidate(other.always_revalidate) {}
280 281
281 ResourcePrefetchPredictor::URLRequestSummary::~URLRequestSummary() { 282 ResourcePrefetchPredictor::URLRequestSummary::~URLRequestSummary() {
282 } 283 }
283 284
285 ResourcePrefetchPredictor::Navigation::Navigation(
286 const GURL& i_initial_url)
287 : initial_url(i_initial_url),
288 requests(new std::vector<URLRequestSummary>) {
289 }
290
291 ResourcePrefetchPredictor::Navigation::~Navigation() {
292 }
293
284 // static 294 // static
285 bool ResourcePrefetchPredictor::URLRequestSummary::SummarizeResponse( 295 bool ResourcePrefetchPredictor::URLRequestSummary::SummarizeResponse(
286 const net::URLRequest& request, 296 const net::URLRequest& request,
287 URLRequestSummary* summary) { 297 URLRequestSummary* summary) {
288 const content::ResourceRequestInfo* info = 298 const content::ResourceRequestInfo* info =
289 content::ResourceRequestInfo::ForRequest(&request); 299 content::ResourceRequestInfo::ForRequest(&request);
290 if (!info) 300 if (!info)
291 return false; 301 return false;
292 302
293 int render_process_id, render_frame_id; 303 int render_process_id, render_frame_id;
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 const URLRequestSummary& request) { 440 const URLRequestSummary& request) {
431 DCHECK_CURRENTLY_ON(BrowserThread::UI); 441 DCHECK_CURRENTLY_ON(BrowserThread::UI);
432 DCHECK_EQ(INITIALIZED, initialization_state_); 442 DCHECK_EQ(INITIALIZED, initialization_state_);
433 443
434 StartPrefetching(request.navigation_id); 444 StartPrefetching(request.navigation_id);
435 445
436 // Cleanup older navigations. 446 // Cleanup older navigations.
437 CleanupAbandonedNavigations(request.navigation_id); 447 CleanupAbandonedNavigations(request.navigation_id);
438 448
439 // New empty navigation entry. 449 // New empty navigation entry.
450 const GURL& initial_url = request.navigation_id.main_frame_url;
440 inflight_navigations_.insert(std::make_pair( 451 inflight_navigations_.insert(std::make_pair(
441 request.navigation_id, 452 request.navigation_id,
442 make_linked_ptr(new std::vector<URLRequestSummary>()))); 453 std::unique_ptr<Navigation>(new Navigation(initial_url))));
443 } 454 }
444 455
445 void ResourcePrefetchPredictor::OnMainFrameResponse( 456 void ResourcePrefetchPredictor::OnMainFrameResponse(
446 const URLRequestSummary& response) { 457 const URLRequestSummary& response) {
447 DCHECK_CURRENTLY_ON(BrowserThread::UI); 458 DCHECK_CURRENTLY_ON(BrowserThread::UI);
448 if (initialization_state_ != INITIALIZED) 459 if (initialization_state_ != INITIALIZED)
449 return; 460 return;
450 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
458 // TODO(shishir): There are significant gains to be had here if we can use the 469 // 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 470 // 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 471 // of redirect times considerably assuming that the redirect chains do not
461 // change. 472 // change.
462 473
463 // Stop any inflight prefetching. Remove the older navigation. 474 // Stop any inflight prefetching. Remove the older navigation.
464 StopPrefetching(response.navigation_id); 475 StopPrefetching(response.navigation_id);
465 inflight_navigations_.erase(response.navigation_id); 476
477 std::unique_ptr<Navigation> navigation;
478 NavigationMap::iterator nav_it =
479 inflight_navigations_.find(response.navigation_id);
480 if (nav_it != inflight_navigations_.end())
mattcary 2016/09/14 15:37:08 Run git cl format; the brace should be on the same
alexilin 2016/09/14 18:59:55 Oops... Done.
481 {
482 navigation.reset(nav_it->second.release());
483 inflight_navigations_.erase(nav_it);
484 }
466 485
467 // A redirect will not lead to another OnMainFrameRequest call, so record the 486 // A redirect will not lead to another OnMainFrameRequest call, so record the
468 // redirect url as a new navigation. 487 // redirect url as a new navigation.
469 488
470 // The redirect url may be empty if the URL was invalid. 489 // The redirect url may be empty if the URL was invalid.
471 if (response.redirect_url.is_empty()) 490 if (response.redirect_url.is_empty())
472 return; 491 return;
473 492
493 if (!navigation) {
494 navigation.reset(new Navigation(response.navigation_id.main_frame_url));
495 }
496
474 NavigationID navigation_id(response.navigation_id); 497 NavigationID navigation_id(response.navigation_id);
475 navigation_id.main_frame_url = response.redirect_url; 498 navigation_id.main_frame_url = response.redirect_url;
476 inflight_navigations_.insert(std::make_pair( 499 inflight_navigations_.insert(std::make_pair(
477 navigation_id, 500 navigation_id,
478 make_linked_ptr(new std::vector<URLRequestSummary>()))); 501 std::move(navigation)));
479 } 502 }
480 503
481 void ResourcePrefetchPredictor::OnSubresourceResponse( 504 void ResourcePrefetchPredictor::OnSubresourceResponse(
482 const URLRequestSummary& response) { 505 const URLRequestSummary& response) {
483 DCHECK_CURRENTLY_ON(BrowserThread::UI); 506 DCHECK_CURRENTLY_ON(BrowserThread::UI);
484 507
485 NavigationMap::const_iterator nav_it = 508 NavigationMap::const_iterator nav_it =
486 inflight_navigations_.find(response.navigation_id); 509 inflight_navigations_.find(response.navigation_id);
487 if (nav_it == inflight_navigations_.end()) { 510 if (nav_it == inflight_navigations_.end()) {
488 return; 511 return;
489 } 512 }
490 513
491 nav_it->second->push_back(response); 514 nav_it->second->requests->push_back(response);
492 } 515 }
493 516
494 void ResourcePrefetchPredictor::OnNavigationComplete( 517 void ResourcePrefetchPredictor::OnNavigationComplete(
495 const NavigationID& nav_id_without_timing_info) { 518 const NavigationID& nav_id_without_timing_info) {
496 DCHECK_CURRENTLY_ON(BrowserThread::UI); 519 DCHECK_CURRENTLY_ON(BrowserThread::UI);
497 520
498 NavigationMap::iterator nav_it = 521 NavigationMap::iterator nav_it =
499 inflight_navigations_.find(nav_id_without_timing_info); 522 inflight_navigations_.find(nav_id_without_timing_info);
500 if (nav_it == inflight_navigations_.end()) 523 if (nav_it == inflight_navigations_.end())
501 return; 524 return;
502 525
503 const NavigationID navigation_id(nav_it->first); 526 const NavigationID navigation_id(nav_it->first);
504 527
505 // Remove the navigation from the inflight navigations. 528 // Remove the navigation from the inflight navigations.
506 std::vector<URLRequestSummary>* requests = (nav_it->second).release(); 529 std::unique_ptr<Navigation> navigation = std::move(nav_it->second);
507 inflight_navigations_.erase(nav_it); 530 inflight_navigations_.erase(nav_it);
508 531
509 // Kick off history lookup to determine if we should record the URL. 532 // Kick off history lookup to determine if we should record the URL.
510 history::HistoryService* history_service = 533 history::HistoryService* history_service =
511 HistoryServiceFactory::GetForProfile(profile_, 534 HistoryServiceFactory::GetForProfile(profile_,
512 ServiceAccessType::EXPLICIT_ACCESS); 535 ServiceAccessType::EXPLICIT_ACCESS);
513 DCHECK(history_service); 536 DCHECK(history_service);
514 history_service->ScheduleDBTask( 537 history_service->ScheduleDBTask(
515 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( 538 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask(
516 navigation_id, requests, 539 navigation_id,
540 std::move(navigation),
517 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, 541 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup,
518 AsWeakPtr()))), 542 AsWeakPtr()))),
519 &history_lookup_consumer_); 543 &history_lookup_consumer_);
520 } 544 }
521 545
522 bool ResourcePrefetchPredictor::GetPrefetchData( 546 bool ResourcePrefetchPredictor::GetPrefetchData(
523 const NavigationID& navigation_id, 547 const NavigationID& navigation_id,
524 ResourcePrefetcher::RequestVector* prefetch_requests, 548 ResourcePrefetcher::RequestVector* prefetch_requests,
525 PrefetchKeyType* key_type) { 549 PrefetchKeyType* key_type) {
526 DCHECK(prefetch_requests); 550 DCHECK(prefetch_requests);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 633
610 void ResourcePrefetchPredictor::StartInitialization() { 634 void ResourcePrefetchPredictor::StartInitialization() {
611 DCHECK_CURRENTLY_ON(BrowserThread::UI); 635 DCHECK_CURRENTLY_ON(BrowserThread::UI);
612 636
613 DCHECK_EQ(NOT_INITIALIZED, initialization_state_); 637 DCHECK_EQ(NOT_INITIALIZED, initialization_state_);
614 initialization_state_ = INITIALIZING; 638 initialization_state_ = INITIALIZING;
615 639
616 // Create local caches using the database as loaded. 640 // Create local caches using the database as loaded.
617 std::unique_ptr<PrefetchDataMap> url_data_map(new PrefetchDataMap()); 641 std::unique_ptr<PrefetchDataMap> url_data_map(new PrefetchDataMap());
618 std::unique_ptr<PrefetchDataMap> host_data_map(new PrefetchDataMap()); 642 std::unique_ptr<PrefetchDataMap> host_data_map(new PrefetchDataMap());
643 std::unique_ptr<RedirectDataMap> url_redirect_data_map(
644 new RedirectDataMap());
645 std::unique_ptr<RedirectDataMap> host_redirect_data_map(
646 new RedirectDataMap());
619 PrefetchDataMap* url_data_ptr = url_data_map.get(); 647 PrefetchDataMap* url_data_ptr = url_data_map.get();
620 PrefetchDataMap* host_data_ptr = host_data_map.get(); 648 PrefetchDataMap* host_data_ptr = host_data_map.get();
649 RedirectDataMap* url_redirect_data_ptr = url_redirect_data_map.get();
650 RedirectDataMap* host_redirect_data_ptr = host_redirect_data_map.get();
621 651
622 BrowserThread::PostTaskAndReply( 652 BrowserThread::PostTaskAndReply(
623 BrowserThread::DB, FROM_HERE, 653 BrowserThread::DB, FROM_HERE,
624 base::Bind(&ResourcePrefetchPredictorTables::GetAllData, 654 base::Bind(&ResourcePrefetchPredictorTables::GetAllData, tables_,
625 tables_, url_data_ptr, host_data_ptr), 655 url_data_ptr,
656 host_data_ptr,
657 url_redirect_data_ptr,
658 host_redirect_data_ptr),
626 base::Bind(&ResourcePrefetchPredictor::CreateCaches, AsWeakPtr(), 659 base::Bind(&ResourcePrefetchPredictor::CreateCaches, AsWeakPtr(),
627 base::Passed(&url_data_map), base::Passed(&host_data_map))); 660 base::Passed(&url_data_map),
661 base::Passed(&host_data_map),
662 base::Passed(&url_redirect_data_map),
663 base::Passed(&host_redirect_data_map)));
628 } 664 }
629 665
630 void ResourcePrefetchPredictor::CreateCaches( 666 void ResourcePrefetchPredictor::CreateCaches(
631 std::unique_ptr<PrefetchDataMap> url_data_map, 667 std::unique_ptr<PrefetchDataMap> url_data_map,
632 std::unique_ptr<PrefetchDataMap> host_data_map) { 668 std::unique_ptr<PrefetchDataMap> host_data_map,
669 std::unique_ptr<RedirectDataMap> url_redirect_data_map,
670 std::unique_ptr<RedirectDataMap> host_redirect_data_map) {
633 DCHECK_CURRENTLY_ON(BrowserThread::UI); 671 DCHECK_CURRENTLY_ON(BrowserThread::UI);
634 672
635 DCHECK_EQ(INITIALIZING, initialization_state_); 673 DCHECK_EQ(INITIALIZING, initialization_state_);
636 DCHECK(!url_table_cache_); 674 DCHECK(!url_table_cache_);
637 DCHECK(!host_table_cache_); 675 DCHECK(!host_table_cache_);
676 DCHECK(!url_redirect_table_cache_);
677 DCHECK(!host_redirect_table_cache_);
638 DCHECK(inflight_navigations_.empty()); 678 DCHECK(inflight_navigations_.empty());
639 679
640 url_table_cache_.reset(url_data_map.release()); 680 url_table_cache_.reset(url_data_map.release());
641 host_table_cache_.reset(host_data_map.release()); 681 host_table_cache_.reset(host_data_map.release());
682 url_redirect_table_cache_.reset(url_redirect_data_map.release());
683 host_redirect_table_cache_.reset(host_redirect_data_map.release());
642 684
643 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.UrlTableMainFrameUrlCount", 685 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.UrlTableMainFrameUrlCount",
644 url_table_cache_->size()); 686 url_table_cache_->size());
645 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostTableHostCount", 687 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostTableHostCount",
646 host_table_cache_->size()); 688 host_table_cache_->size());
647 689
648 ConnectToHistoryService(); 690 ConnectToHistoryService();
649 } 691 }
650 692
651 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() { 693 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 751
710 const std::string& host = it.url().host(); 752 const std::string& host = it.url().host();
711 if (host_table_cache_->find(host) != host_table_cache_->end()) { 753 if (host_table_cache_->find(host) != host_table_cache_->end()) {
712 hosts_to_delete.push_back(host); 754 hosts_to_delete.push_back(host);
713 host_table_cache_->erase(host); 755 host_table_cache_->erase(host);
714 } 756 }
715 } 757 }
716 758
717 if (!urls_to_delete.empty() || !hosts_to_delete.empty()) { 759 if (!urls_to_delete.empty() || !hosts_to_delete.empty()) {
718 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 760 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
719 base::Bind(&ResourcePrefetchPredictorTables::DeleteData, 761 base::Bind(&ResourcePrefetchPredictorTables::DeleteResourceData,
720 tables_, 762 tables_,
721 urls_to_delete, 763 urls_to_delete,
722 hosts_to_delete)); 764 hosts_to_delete));
723 } 765 }
724 } 766 }
725 767
726 void ResourcePrefetchPredictor::RemoveOldestEntryInPrefetchDataMap( 768 void ResourcePrefetchPredictor::RemoveOldestEntryInPrefetchDataMap(
727 PrefetchKeyType key_type, 769 PrefetchKeyType key_type,
728 PrefetchDataMap* data_map) { 770 PrefetchDataMap* data_map) {
729 if (data_map->empty()) 771 if (data_map->empty())
730 return; 772 return;
731 773
732 base::Time oldest_time; 774 base::Time oldest_time;
733 std::string key_to_delete; 775 std::string key_to_delete;
734 for (PrefetchDataMap::iterator it = data_map->begin(); 776 for (PrefetchDataMap::iterator it = data_map->begin();
735 it != data_map->end(); ++it) { 777 it != data_map->end(); ++it) {
736 if (key_to_delete.empty() || it->second.last_visit < oldest_time) { 778 if (key_to_delete.empty() || it->second.last_visit < oldest_time) {
737 key_to_delete = it->first; 779 key_to_delete = it->first;
738 oldest_time = it->second.last_visit; 780 oldest_time = it->second.last_visit;
739 } 781 }
740 } 782 }
741 783
742 data_map->erase(key_to_delete); 784 data_map->erase(key_to_delete);
743 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 785 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, base::Bind(
744 base::Bind(&ResourcePrefetchPredictorTables::DeleteSingleDataPoint, 786 &ResourcePrefetchPredictorTables::DeleteSingleResourceDataPoint,
745 tables_, 787 tables_,
746 key_to_delete, 788 key_to_delete,
747 key_type)); 789 key_type));
790 }
791
792 void ResourcePrefetchPredictor::RemoveOldestEntryInRedirectDataMap(
793 PrefetchKeyType key_type,
794 RedirectDataMap* data_map) {
795 if (data_map->empty())
796 return;
797
798 base::Time oldest_time;
799 std::string key_to_delete;
800 for (RedirectDataMap::iterator it = data_map->begin();
801 it != data_map->end(); ++it) {
802 if (key_to_delete.empty() || it->second.last_visit < oldest_time) {
803 key_to_delete = it->first;
804 oldest_time = it->second.last_visit;
805 }
806 }
807
808 data_map->erase(key_to_delete);
809 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, base::Bind(
810 &ResourcePrefetchPredictorTables::DeleteSingleRedirectDataPoint,
811 tables_,
812 key_to_delete,
813 key_type));
748 } 814 }
749 815
750 void ResourcePrefetchPredictor::OnVisitCountLookup( 816 void ResourcePrefetchPredictor::OnVisitCountLookup(
751 size_t visit_count, 817 size_t visit_count,
752 const NavigationID& navigation_id, 818 const NavigationID& navigation_id,
753 const std::vector<URLRequestSummary>& requests) { 819 const Navigation& navigation) {
754 DCHECK_CURRENTLY_ON(BrowserThread::UI); 820 DCHECK_CURRENTLY_ON(BrowserThread::UI);
755 821
756 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HistoryVisitCountForUrl", 822 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HistoryVisitCountForUrl",
757 visit_count); 823 visit_count);
758 824
825 // TODO(alexilin) make only one request to DB thread
826
759 // URL level data - merge only if we are already saving the data, or we it 827 // URL level data - merge only if we are already saving the data, or we it
760 // meets the cutoff requirement. 828 // meets the cutoff requirement.
761 const std::string url_spec = navigation_id.main_frame_url.spec(); 829 const std::string url_spec = navigation_id.main_frame_url.spec();
762 bool already_tracking = url_table_cache_->find(url_spec) != 830 bool already_tracking = url_table_cache_->find(url_spec) !=
763 url_table_cache_->end(); 831 url_table_cache_->end();
764 bool should_track_url = already_tracking || 832 bool should_track_url = already_tracking ||
765 (visit_count >= config_.min_url_visit_count); 833 (visit_count >= config_.min_url_visit_count);
766 834
767 if (should_track_url && config_.IsURLLearningEnabled()) { 835 if (should_track_url && config_.IsURLLearningEnabled()) {
768 LearnNavigation(url_spec, PREFETCH_KEY_TYPE_URL, requests, 836 LearnNavigation(url_spec, PREFETCH_KEY_TYPE_URL, *navigation.requests,
769 config_.max_urls_to_track, url_table_cache_.get()); 837 config_.max_urls_to_track, url_table_cache_.get());
838
839 const std::string initial_url_spec = navigation.initial_url.spec();
840 if (url_spec != initial_url_spec) {
841 LearnRedirect(initial_url_spec, PREFETCH_KEY_TYPE_URL, url_spec,
842 config_.max_urls_to_track,
843 url_redirect_table_cache_.get());
844 }
770 } 845 }
771 846
772 // Host level data - no cutoff, always learn the navigation if enabled. 847 // Host level data - no cutoff, always learn the navigation if enabled.
773 if (config_.IsHostLearningEnabled()) { 848 if (config_.IsHostLearningEnabled()) {
774 LearnNavigation(navigation_id.main_frame_url.host(), 849 const std::string host = navigation_id.main_frame_url.host();
775 PREFETCH_KEY_TYPE_HOST, 850 LearnNavigation(host, PREFETCH_KEY_TYPE_HOST, *navigation.requests,
776 requests, 851 config_.max_hosts_to_track, host_table_cache_.get());
852
853 const std::string initial_host = navigation.initial_url.host();
854 if (host != initial_host) {
855 LearnRedirect(initial_host, PREFETCH_KEY_TYPE_HOST, host,
777 config_.max_hosts_to_track, 856 config_.max_hosts_to_track,
778 host_table_cache_.get()); 857 host_redirect_table_cache_.get());
858 }
779 } 859 }
780 860
781 // Remove the navigation from the results map. 861 // Remove the navigation from the results map.
782 results_map_.erase(navigation_id); 862 results_map_.erase(navigation_id);
783 } 863 }
784 864
785 void ResourcePrefetchPredictor::LearnNavigation( 865 void ResourcePrefetchPredictor::LearnNavigation(
786 const std::string& key, 866 const std::string& key,
787 PrefetchKeyType key_type, 867 PrefetchKeyType key_type,
788 const std::vector<URLRequestSummary>& new_resources, 868 const std::vector<URLRequestSummary>& new_resources,
(...skipping 27 matching lines...) Expand all
816 row_to_add.resource_type = new_resources[i].resource_type; 896 row_to_add.resource_type = new_resources[i].resource_type;
817 row_to_add.number_of_hits = 1; 897 row_to_add.number_of_hits = 1;
818 row_to_add.average_position = i + 1; 898 row_to_add.average_position = i + 1;
819 row_to_add.priority = new_resources[i].priority; 899 row_to_add.priority = new_resources[i].priority;
820 row_to_add.has_validators = new_resources[i].has_validators; 900 row_to_add.has_validators = new_resources[i].has_validators;
821 row_to_add.always_revalidate = new_resources[i].always_revalidate; 901 row_to_add.always_revalidate = new_resources[i].always_revalidate;
822 cache_entry->second.resources.push_back(row_to_add); 902 cache_entry->second.resources.push_back(row_to_add);
823 resources_seen.insert(new_resources[i].resource_url); 903 resources_seen.insert(new_resources[i].resource_url);
824 } 904 }
825 } else { 905 } else {
826 ResourceRows& old_resources = cache_entry->second.resources; 906 std::vector<ResourceRow>& old_resources = cache_entry->second.resources;
827 cache_entry->second.last_visit = base::Time::Now(); 907 cache_entry->second.last_visit = base::Time::Now();
828 908
829 // Build indices over the data. 909 // Build indices over the data.
830 std::map<GURL, int> new_index, old_index; 910 std::map<GURL, int> new_index, old_index;
831 int new_resources_size = static_cast<int>(new_resources.size()); 911 int new_resources_size = static_cast<int>(new_resources.size());
832 for (int i = 0; i < new_resources_size; ++i) { 912 for (int i = 0; i < new_resources_size; ++i) {
833 const URLRequestSummary& summary = new_resources[i]; 913 const URLRequestSummary& summary = new_resources[i];
834 // Take the first occurence of every url. 914 // Take the first occurence of every url.
835 if (new_index.find(summary.resource_url) == new_index.end()) 915 if (new_index.find(summary.resource_url) == new_index.end())
836 new_index[summary.resource_url] = i; 916 new_index[summary.resource_url] = i;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 row_to_add.has_validators = new_resources[i].has_validators; 963 row_to_add.has_validators = new_resources[i].has_validators;
884 row_to_add.always_revalidate = new_resources[i].always_revalidate; 964 row_to_add.always_revalidate = new_resources[i].always_revalidate;
885 old_resources.push_back(row_to_add); 965 old_resources.push_back(row_to_add);
886 966
887 // To ensure we dont add the same url twice. 967 // To ensure we dont add the same url twice.
888 old_index[summary.resource_url] = 0; 968 old_index[summary.resource_url] = 0;
889 } 969 }
890 } 970 }
891 971
892 // Trim and sort the resources after the update. 972 // Trim and sort the resources after the update.
893 ResourceRows& resources = cache_entry->second.resources; 973 std::vector<ResourceRow>& resources = cache_entry->second.resources;
894 for (ResourceRows::iterator it = resources.begin(); 974 for (std::vector<ResourceRow>::iterator it = resources.begin();
895 it != resources.end();) { 975 it != resources.end();) {
896 it->UpdateScore(); 976 it->UpdateScore();
897 if (it->consecutive_misses >= config_.max_consecutive_misses) 977 if (it->consecutive_misses >= config_.max_consecutive_misses)
898 it = resources.erase(it); 978 it = resources.erase(it);
899 else 979 else
900 ++it; 980 ++it;
901 } 981 }
902 ResourcePrefetchPredictorTables::SortResourceRows(&resources); 982 ResourcePrefetchPredictorTables::SortResourceRows(&resources);
903 if (resources.size() > config_.max_resources_per_entry) 983 if (resources.size() > config_.max_resources_per_entry)
904 resources.resize(config_.max_resources_per_entry); 984 resources.resize(config_.max_resources_per_entry);
905 985
906 // If the row has no resources, remove it from the cache and delete the 986 // If the row has no resources, remove it from the cache and delete the
907 // entry in the database. Else update the database. 987 // entry in the database. Else update the database.
908 if (resources.empty()) { 988 if (resources.empty()) {
909 data_map->erase(key); 989 data_map->erase(key);
910 BrowserThread::PostTask( 990 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, base::Bind(
911 BrowserThread::DB, FROM_HERE, 991 &ResourcePrefetchPredictorTables::DeleteSingleResourceDataPoint,
912 base::Bind(&ResourcePrefetchPredictorTables::DeleteSingleDataPoint, 992 tables_,
913 tables_, 993 key,
914 key, 994 key_type));
915 key_type));
916 } else { 995 } else {
917 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; 996 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST;
918 PrefetchData empty_data( 997 PrefetchData empty_data(
919 !is_host ? PREFETCH_KEY_TYPE_HOST : PREFETCH_KEY_TYPE_URL, 998 !is_host ? PREFETCH_KEY_TYPE_HOST : PREFETCH_KEY_TYPE_URL,
920 std::string()); 999 std::string());
1000 RedirectData empty_url_redirect_data(PREFETCH_KEY_TYPE_URL, std::string());
1001 RedirectData empty_host_redirect_data(
1002 PREFETCH_KEY_TYPE_HOST, std::string());
921 const PrefetchData& host_data = is_host ? cache_entry->second : empty_data; 1003 const PrefetchData& host_data = is_host ? cache_entry->second : empty_data;
922 const PrefetchData& url_data = is_host ? empty_data : cache_entry->second; 1004 const PrefetchData& url_data = is_host ? empty_data : cache_entry->second;
923 BrowserThread::PostTask( 1005 BrowserThread::PostTask(
924 BrowserThread::DB, FROM_HERE, 1006 BrowserThread::DB, FROM_HERE,
925 base::Bind(&ResourcePrefetchPredictorTables::UpdateData, 1007 base::Bind(&ResourcePrefetchPredictorTables::UpdateData,
926 tables_, 1008 tables_,
927 url_data, 1009 url_data,
928 host_data)); 1010 host_data,
1011 empty_url_redirect_data,
1012 empty_host_redirect_data));
929 } 1013 }
930 } 1014 }
931 1015
1016 void ResourcePrefetchPredictor::LearnRedirect(
1017 const std::string& key,
1018 PrefetchKeyType key_type,
1019 const std::string& final_redirect,
1020 size_t max_redirect_map_size,
1021 RedirectDataMap* redirect_map) {
1022 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1023
1024 RedirectDataMap::iterator cache_entry = redirect_map->find(key);
1025 if (cache_entry == redirect_map->end()) {
1026 if (redirect_map->size() >= max_redirect_map_size) {
1027 RemoveOldestEntryInRedirectDataMap(key_type, redirect_map);
1028 }
1029
1030 cache_entry = redirect_map->insert(std::make_pair(
1031 key, RedirectData(key_type, key))).first;
1032 cache_entry->second.last_visit = base::Time::Now();
1033 RedirectRow row_to_add;
1034 row_to_add.final_redirect = final_redirect;
1035 row_to_add.number_of_hits = 1;
1036 cache_entry->second.redirects.push_back(row_to_add);
1037 } else {
1038 std::vector<RedirectRow>& redirects = cache_entry->second.redirects;
1039 bool need_to_add = true;
1040
1041 cache_entry->second.last_visit = base::Time::Now();
1042 for (RedirectRow& redirect : redirects) {
1043 if (redirect.final_redirect == final_redirect) {
1044 need_to_add = false;
1045 ++redirect.number_of_hits;
1046 redirect.consecutive_misses = 0;
1047 } else {
1048 ++redirect.number_of_misses;
1049 ++redirect.consecutive_misses;
1050 }
1051 }
1052
1053 if (need_to_add) {
1054 RedirectRow row_to_add;
1055 row_to_add.final_redirect = final_redirect;
1056 row_to_add.number_of_hits = 1;
1057 redirects.push_back(row_to_add);
1058 }
1059 }
1060
1061 std::vector<RedirectRow>& redirects = cache_entry->second.redirects;
1062 // Trim and sort redirects after update.
1063 for (std::vector<RedirectRow>::iterator it = redirects.begin();
1064 it != redirects.end();) {
1065 it->UpdateScore();
1066 if (it->consecutive_misses >= config_.max_consecutive_misses)
1067 it = redirects.erase(it);
1068 else
1069 ++it;
1070 }
1071 ResourcePrefetchPredictorTables::SortRedirectRows(&redirects);
1072
1073 if (redirects.size() > config_.max_redirects_per_entry)
1074 redirects.resize(config_.max_redirects_per_entry);
1075
1076 if (redirects.empty()) {
1077 redirect_map->erase(cache_entry);
1078 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, base::Bind(
1079 &ResourcePrefetchPredictorTables::DeleteSingleRedirectDataPoint,
1080 tables_,
1081 key,
1082 key_type));
1083 } else {
1084 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST;
1085 RedirectData empty_redirect_data(
1086 !is_host ? PREFETCH_KEY_TYPE_HOST : PREFETCH_KEY_TYPE_URL,
1087 std::string());
1088 PrefetchData empty_url_data(PREFETCH_KEY_TYPE_URL, std::string());
1089 PrefetchData empty_host_data(
1090 PREFETCH_KEY_TYPE_HOST, std::string());
1091 const RedirectData& host_redirect_data =
1092 is_host ? cache_entry->second : empty_redirect_data;
1093 const RedirectData& url_redirect_data =
1094 is_host ? empty_redirect_data : cache_entry->second;
1095 BrowserThread::PostTask(
1096 BrowserThread::DB, FROM_HERE,
1097 base::Bind(&ResourcePrefetchPredictorTables::UpdateData,
1098 tables_,
1099 empty_url_data,
1100 empty_host_data,
1101 url_redirect_data,
1102 host_redirect_data));
1103 }
1104 }
1105
932 void ResourcePrefetchPredictor::OnURLsDeleted( 1106 void ResourcePrefetchPredictor::OnURLsDeleted(
933 history::HistoryService* history_service, 1107 history::HistoryService* history_service,
934 bool all_history, 1108 bool all_history,
935 bool expired, 1109 bool expired,
936 const history::URLRows& deleted_rows, 1110 const history::URLRows& deleted_rows,
937 const std::set<GURL>& favicon_urls) { 1111 const std::set<GURL>& favicon_urls) {
938 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1112 DCHECK_CURRENTLY_ON(BrowserThread::UI);
939 if (INITIALIZED != initialization_state_) 1113 if (INITIALIZED != initialization_state_)
940 return; 1114 return;
941 1115
(...skipping 27 matching lines...) Expand all
969 // HistoryService is already loaded. Continue with Initialization. 1143 // HistoryService is already loaded. Continue with Initialization.
970 OnHistoryAndCacheLoaded(); 1144 OnHistoryAndCacheLoaded();
971 return; 1145 return;
972 } 1146 }
973 DCHECK(!history_service_observer_.IsObserving(history_service)); 1147 DCHECK(!history_service_observer_.IsObserving(history_service));
974 history_service_observer_.Add(history_service); 1148 history_service_observer_.Add(history_service);
975 return; 1149 return;
976 } 1150 }
977 1151
978 } // namespace predictors 1152 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698