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

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

Issue 10817004: Adds speculative prefetching of resources. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Addressing Dominich's comments. Created 8 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/stl_util.h" 13 #include "base/stl_util.h"
14 #include "base/string_number_conversions.h" 14 #include "base/string_number_conversions.h"
15 #include "base/stringprintf.h" 15 #include "base/stringprintf.h"
16 #include "base/time.h" 16 #include "base/time.h"
17 #include "chrome/browser/history/history.h" 17 #include "chrome/browser/history/history.h"
18 #include "chrome/browser/history/history_notifications.h" 18 #include "chrome/browser/history/history_notifications.h"
19 #include "chrome/browser/history/history_service_factory.h" 19 #include "chrome/browser/history/history_service_factory.h"
20 #include "chrome/browser/history/in_memory_database.h" 20 #include "chrome/browser/history/in_memory_database.h"
21 #include "chrome/browser/history/url_database.h" 21 #include "chrome/browser/history/url_database.h"
22 #include "chrome/browser/predictors/predictor_database.h" 22 #include "chrome/browser/predictors/predictor_database.h"
23 #include "chrome/browser/predictors/predictor_database_factory.h" 23 #include "chrome/browser/predictors/predictor_database_factory.h"
24 #include "chrome/browser/predictors/resource_prefetcher_manager.h"
24 #include "chrome/browser/prerender/prerender_field_trial.h" 25 #include "chrome/browser/prerender/prerender_field_trial.h"
25 #include "chrome/browser/profiles/profile.h" 26 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/common/chrome_notification_types.h" 27 #include "chrome/common/chrome_notification_types.h"
27 #include "chrome/common/chrome_switches.h" 28 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/url_constants.h" 29 #include "chrome/common/url_constants.h"
29 #include "content/public/browser/browser_thread.h" 30 #include "content/public/browser/browser_thread.h"
30 #include "content/public/browser/load_from_memory_cache_details.h" 31 #include "content/public/browser/load_from_memory_cache_details.h"
31 #include "content/public/browser/navigation_controller.h" 32 #include "content/public/browser/navigation_controller.h"
32 #include "content/public/browser/notification_service.h" 33 #include "content/public/browser/notification_service.h"
33 #include "content/public/browser/notification_source.h" 34 #include "content/public/browser/notification_source.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 void RecordNavigationEvent(NavigationEvent event) { 83 void RecordNavigationEvent(NavigationEvent event) {
83 UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.NavigationEvent", 84 UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.NavigationEvent",
84 event, 85 event,
85 NAVIGATION_EVENT_COUNT); 86 NAVIGATION_EVENT_COUNT);
86 } 87 }
87 88
88 } // namespace 89 } // namespace
89 90
90 namespace predictors { 91 namespace predictors {
91 92
92 ResourcePrefetchPredictor::Config::Config()
93 : max_navigation_lifetime_seconds(60),
94 max_urls_to_track(500),
95 min_url_visit_count(3),
96 max_resources_per_entry(50),
97 max_consecutive_misses(3) {
98 }
99
100 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary() 93 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary()
101 : resource_type(ResourceType::LAST_TYPE), 94 : resource_type(ResourceType::LAST_TYPE),
102 was_cached(false) { 95 was_cached(false) {
103 } 96 }
104 97
105 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary( 98 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary(
106 const URLRequestSummary& other) 99 const URLRequestSummary& other)
107 : navigation_id(other.navigation_id), 100 : navigation_id(other.navigation_id),
108 resource_url(other.resource_url), 101 resource_url(other.resource_url),
109 resource_type(other.resource_type), 102 resource_type(other.resource_type),
110 mime_type(other.mime_type), 103 mime_type(other.mime_type),
111 was_cached(other.was_cached), 104 was_cached(other.was_cached),
112 redirect_url(other.redirect_url) { 105 redirect_url(other.redirect_url) {
113 } 106 }
114 107
115 ResourcePrefetchPredictor::URLRequestSummary::~URLRequestSummary() { 108 ResourcePrefetchPredictor::URLRequestSummary::~URLRequestSummary() {
116 } 109 }
117 110
118 ResourcePrefetchPredictor::UrlTableCacheValue::UrlTableCacheValue() { 111 ResourcePrefetchPredictor::UrlTableCacheValue::UrlTableCacheValue() {
119 } 112 }
120 113
121 ResourcePrefetchPredictor::UrlTableCacheValue::~UrlTableCacheValue() { 114 ResourcePrefetchPredictor::UrlTableCacheValue::~UrlTableCacheValue() {
122 } 115 }
123 116
124 ResourcePrefetchPredictor::ResourcePrefetchPredictor( 117 ResourcePrefetchPredictor::ResourcePrefetchPredictor(
125 const Config& config, 118 const ResourcePrefetchPredictorConfig& config,
126 Profile* profile) 119 Profile* profile)
127 : profile_(profile), 120 : profile_(profile),
128 config_(config), 121 config_(config),
129 initialization_state_(NOT_INITIALIZED), 122 initialization_state_(NOT_INITIALIZED),
130 tables_(PredictorDatabaseFactory::GetForProfile( 123 tables_(PredictorDatabaseFactory::GetForProfile(
131 profile)->resource_prefetch_tables()) { 124 profile)->resource_prefetch_tables()),
125 results_map_deleter_(&results_map_) {
132 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 126 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
133 127
134 notification_registrar_.Add(this, 128 notification_registrar_.Add(this,
135 content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, 129 content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
136 content::NotificationService::AllSources()); 130 content::NotificationService::AllSources());
137 } 131 }
138 132
139 ResourcePrefetchPredictor::~ResourcePrefetchPredictor() { 133 ResourcePrefetchPredictor::~ResourcePrefetchPredictor() {
140 } 134 }
141 135
142 // static 136 void ResourcePrefetchPredictor::Shutdown() {
143 bool ResourcePrefetchPredictor::IsEnabled(Profile* profile) { 137 if (prefetch_manager_) {
144 return prerender::IsSpeculativeResourcePrefetchingLearningEnabled(profile); 138 prefetch_manager_->ShutdownOnUIThread();
139 prefetch_manager_ = NULL;
140 }
145 } 141 }
146 142
147 void ResourcePrefetchPredictor::LazilyInitialize() { 143 void ResourcePrefetchPredictor::LazilyInitialize() {
148 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 144 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
149 145
150 DCHECK_EQ(initialization_state_, NOT_INITIALIZED); 146 DCHECK_EQ(initialization_state_, NOT_INITIALIZED);
151 initialization_state_ = INITIALIZING; 147 initialization_state_ = INITIALIZING;
152 148
153 // Request the in-memory database from the history to force it to load so it's 149 // Request the in-memory database from the history to force it to load so it's
154 // available as soon as possible. 150 // available as soon as possible.
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 DCHECK_EQ(INITIALIZED, initialization_state_); 347 DCHECK_EQ(INITIALIZED, initialization_state_);
352 348
353 RecordNavigationEvent(NAVIGATION_EVENT_REQUEST_STARTED); 349 RecordNavigationEvent(NAVIGATION_EVENT_REQUEST_STARTED);
354 350
355 // Cleanup older navigations. 351 // Cleanup older navigations.
356 CleanupAbandonedNavigations(request.navigation_id); 352 CleanupAbandonedNavigations(request.navigation_id);
357 353
358 // New empty navigation entry. 354 // New empty navigation entry.
359 inflight_navigations_.insert(std::make_pair( 355 inflight_navigations_.insert(std::make_pair(
360 request.navigation_id, std::vector<URLRequestSummary>())); 356 request.navigation_id, std::vector<URLRequestSummary>()));
357
358 // If prefetching is enabled, and we can prefetch something, start
359 // prefetching.
360 if (!prefetch_manager_.get())
361 return;
362
363 const GURL& main_frame_url = request.navigation_id.main_frame_url;
364 const UrlTableCacheMap::const_iterator value_iter = url_table_cache_.find(
365 main_frame_url);
366 if (value_iter == url_table_cache_.end())
367 return;
368
369 const UrlTableCacheValue& value = value_iter->second;
370
371 scoped_ptr<ResourcePrefetcher::RequestVector> requests(
372 new ResourcePrefetcher::RequestVector);
373 for (UrlTableRowVector::const_iterator it = value.rows.begin();
374 it != value.rows.end(); ++it) {
375 float confidence = static_cast<float>(it->number_of_hits) /
376 (it->number_of_hits + it->number_of_misses);
377 if (confidence < config_.min_resource_confidence_to_trigger_prefetch ||
378 it->number_of_hits < config_.min_resource_hits_to_trigger_prefetch) {
379 continue;
380 }
381
382 ResourcePrefetcher::Request* req = new ResourcePrefetcher::Request(
383 it->resource_url);
384 requests->push_back(req);
385 }
386
387 if (requests->empty())
388 return;
389
390 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
391 base::Bind(&ResourcePrefetcherManager::MaybeAddPrefetch,
392 prefetch_manager_,
393 request.navigation_id,
394 base::Passed(&requests)));
361 } 395 }
362 396
363 void ResourcePrefetchPredictor::OnMainFrameResponse( 397 void ResourcePrefetchPredictor::OnMainFrameResponse(
364 const URLRequestSummary& response) { 398 const URLRequestSummary& response) {
365 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 399 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
400 if (initialization_state_ != INITIALIZED)
401 return;
366 402
367 RecordNavigationEvent(NAVIGATION_EVENT_RESPONSE_STARTED); 403 RecordNavigationEvent(NAVIGATION_EVENT_RESPONSE_STARTED);
368 404
369 // TODO(shishir): The prefreshing will be stopped here. 405 if (prefetch_manager_.get())
406 BrowserThread::PostTask(
407 BrowserThread::IO, FROM_HERE,
408 base::Bind(&ResourcePrefetcherManager::MaybeRemovePrefetch,
409 prefetch_manager_,
410 response.navigation_id));
370 } 411 }
371 412
372 void ResourcePrefetchPredictor::OnMainFrameRedirect( 413 void ResourcePrefetchPredictor::OnMainFrameRedirect(
373 const URLRequestSummary& response) { 414 const URLRequestSummary& response) {
374 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 415 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
375 416
376 RecordNavigationEvent(NAVIGATION_EVENT_REQUEST_REDIRECTED); 417 RecordNavigationEvent(NAVIGATION_EVENT_REQUEST_REDIRECTED);
377 418
378 // Remove the older navigation. 419 // Remove the older navigation.
379 inflight_navigations_.erase(response.navigation_id); 420 inflight_navigations_.erase(response.navigation_id);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 for (NavigationMap::iterator it = inflight_navigations_.begin(); 472 for (NavigationMap::iterator it = inflight_navigations_.begin();
432 it != inflight_navigations_.end();) { 473 it != inflight_navigations_.end();) {
433 if (it->first.IsSameRenderer(navigation_id) || 474 if (it->first.IsSameRenderer(navigation_id) ||
434 (time_now - it->first.creation_time > max_navigation_age)) { 475 (time_now - it->first.creation_time > max_navigation_age)) {
435 inflight_navigations_.erase(it++); 476 inflight_navigations_.erase(it++);
436 RecordNavigationEvent(NAVIGATION_EVENT_REQUEST_EXPIRED); 477 RecordNavigationEvent(NAVIGATION_EVENT_REQUEST_EXPIRED);
437 } else { 478 } else {
438 ++it; 479 ++it;
439 } 480 }
440 } 481 }
482 for (ResultsMap::iterator it = results_map_.begin();
483 it != results_map_.end();) {
484 if (it->first.IsSameRenderer(navigation_id) ||
485 (time_now - it->first.creation_time > max_navigation_age)) {
486 delete it->second;
487 results_map_.erase(it++);
488 } else {
489 ++it;
490 }
491 }
441 } 492 }
442 493
443 void ResourcePrefetchPredictor::Observe( 494 void ResourcePrefetchPredictor::Observe(
444 int type, 495 int type,
445 const content::NotificationSource& source, 496 const content::NotificationSource& source,
446 const content::NotificationDetails& details) { 497 const content::NotificationDetails& details) {
447 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 498 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
448 499
449 switch (type) { 500 switch (type) {
450 case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME: { 501 case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME: {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 DeleteUrls(urls_deleted_details->rows); 560 DeleteUrls(urls_deleted_details->rows);
510 break; 561 break;
511 } 562 }
512 563
513 default: 564 default:
514 NOTREACHED() << "Unexpected notification observed."; 565 NOTREACHED() << "Unexpected notification observed.";
515 break; 566 break;
516 } 567 }
517 } 568 }
518 569
570 void ResourcePrefetchPredictor::FinishedPrefetchForNavigation(
571 const NavigationID& navigation_id,
572 scoped_ptr<ResourcePrefetcher::RequestVector> requests) {
573 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
574
575 // Add the results to the results map.
576 ResourcePrefetcher::RequestVector* req = requests.release();
577 if (!results_map_.insert(std::make_pair(navigation_id, req)).second) {
578 DLOG(FATAL) << "Returning results for existing navigation.";
579 delete req;
580 }
581 }
582
519 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() { 583 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() {
520 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 584 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
521 DCHECK_EQ(initialization_state_, INITIALIZING); 585 DCHECK_EQ(initialization_state_, INITIALIZING);
522 586
523 // Update the data with last visit info from in memory history db. 587 // Update the data with last visit info from in memory history db.
524 HistoryService* history_service = HistoryServiceFactory::GetForProfile( 588 HistoryService* history_service = HistoryServiceFactory::GetForProfile(
525 profile_, Profile::EXPLICIT_ACCESS); 589 profile_, Profile::EXPLICIT_ACCESS);
526 DCHECK(history_service); 590 DCHECK(history_service);
527 history::URLDatabase* url_db = history_service->InMemoryDatabase(); 591 history::URLDatabase* url_db = history_service->InMemoryDatabase();
528 if (url_db) { 592 if (url_db) {
(...skipping 29 matching lines...) Expand all
558 notification_registrar_.Add(this, 622 notification_registrar_.Add(this,
559 content::NOTIFICATION_LOAD_FROM_MEMORY_CACHE, 623 content::NOTIFICATION_LOAD_FROM_MEMORY_CACHE,
560 content::NotificationService::AllSources()); 624 content::NotificationService::AllSources());
561 notification_registrar_.Add(this, 625 notification_registrar_.Add(this,
562 chrome::NOTIFICATION_HISTORY_URLS_DELETED, 626 chrome::NOTIFICATION_HISTORY_URLS_DELETED,
563 content::Source<Profile>(profile_)); 627 content::Source<Profile>(profile_));
564 628
565 // TODO(shishir): Maybe listen for notifications for navigation being 629 // TODO(shishir): Maybe listen for notifications for navigation being
566 // abandoned and cleanup the inflight_navigations_. 630 // abandoned and cleanup the inflight_navigations_.
567 631
632 // Initialize the prefetch manager only if prefetching is enabled.
633 if (prerender::IsSpeculativeResourcePrefetchingEnabled(profile_)) {
634 prefetch_manager_ = new ResourcePrefetcherManager(
635 this, config_, profile_->GetRequestContext());
636 }
637
568 initialization_state_ = INITIALIZED; 638 initialization_state_ = INITIALIZED;
569 } 639 }
570 640
571 bool ResourcePrefetchPredictor::ShouldTrackUrl(const GURL& url) { 641 bool ResourcePrefetchPredictor::ShouldTrackUrl(const GURL& url) {
572 bool already_tracking = url_table_cache_.find(url) != url_table_cache_.end(); 642 bool already_tracking = url_table_cache_.find(url) != url_table_cache_.end();
573 643
574 HistoryService* history_service = HistoryServiceFactory::GetForProfile( 644 HistoryService* history_service = HistoryServiceFactory::GetForProfile(
575 profile_, Profile::EXPLICIT_ACCESS); 645 profile_, Profile::EXPLICIT_ACCESS);
576 DCHECK(history_service); 646 DCHECK(history_service);
577 history::URLDatabase* url_db = history_service->InMemoryDatabase(); 647 history::URLDatabase* url_db = history_service->InMemoryDatabase();
(...skipping 17 matching lines...) Expand all
595 665
596 if (inflight_navigations_.find(navigation_id) == 666 if (inflight_navigations_.find(navigation_id) ==
597 inflight_navigations_.end()) { 667 inflight_navigations_.end()) {
598 RecordNavigationEvent(NAVIGATION_EVENT_ONLOAD_UNTRACKED_URL); 668 RecordNavigationEvent(NAVIGATION_EVENT_ONLOAD_UNTRACKED_URL);
599 return; 669 return;
600 } 670 }
601 671
602 RecordNavigationEvent(NAVIGATION_EVENT_ONLOAD_TRACKED_URL); 672 RecordNavigationEvent(NAVIGATION_EVENT_ONLOAD_TRACKED_URL);
603 673
604 // Report any stats. 674 // Report any stats.
605 MaybeReportAccuracyStats(navigation_id); 675 if (prefetch_manager_.get()) {
676 MaybeReportAccuracyStats(navigation_id);
677 } else {
678 MaybeReportSimulatedAccuracyStats(navigation_id);
679 }
606 680
607 // Update the URL table. 681 // Update the URL table.
608 const GURL& main_frame_url = navigation_id.main_frame_url; 682 const GURL& main_frame_url = navigation_id.main_frame_url;
609 if (ShouldTrackUrl(main_frame_url)) { 683 if (ShouldTrackUrl(main_frame_url)) {
610 RecordNavigationEvent(NAVIGATION_EVENT_SHOULD_TRACK_URL); 684 RecordNavigationEvent(NAVIGATION_EVENT_SHOULD_TRACK_URL);
611 LearnUrlNavigation(main_frame_url, inflight_navigations_[navigation_id]); 685 LearnUrlNavigation(main_frame_url, inflight_navigations_[navigation_id]);
612 } else { 686 } else {
613 RecordNavigationEvent(NAVIGATION_EVENT_SHOULD_NOT_TRACK_URL); 687 RecordNavigationEvent(NAVIGATION_EVENT_SHOULD_NOT_TRACK_URL);
614 } 688 }
615 689
616 // Remove the navigation. 690 // Remove the navigation.
617 inflight_navigations_.erase(navigation_id); 691 inflight_navigations_.erase(navigation_id);
692 delete results_map_[navigation_id];
693 results_map_.erase(navigation_id);
618 } 694 }
619 695
620 void ResourcePrefetchPredictor::LearnUrlNavigation( 696 void ResourcePrefetchPredictor::LearnUrlNavigation(
621 const GURL& main_frame_url, 697 const GURL& main_frame_url,
622 const std::vector<URLRequestSummary>& new_resources) { 698 const std::vector<URLRequestSummary>& new_resources) {
623 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 699 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
624 700
625 if (url_table_cache_.find(main_frame_url) == url_table_cache_.end()) { 701 if (url_table_cache_.find(main_frame_url) == url_table_cache_.end()) {
626 if (url_table_cache_.size() >= config_.max_urls_to_track) 702 if (static_cast<int>(url_table_cache_.size()) >= config_.max_urls_to_track)
627 RemoveAnEntryFromUrlDB(); 703 RemoveAnEntryFromUrlDB();
628 704
629 url_table_cache_[main_frame_url].last_visit = base::Time::Now(); 705 url_table_cache_[main_frame_url].last_visit = base::Time::Now();
630 int new_resources_size = static_cast<int>(new_resources.size()); 706 int new_resources_size = static_cast<int>(new_resources.size());
631 std::set<GURL> resources_seen; 707 std::set<GURL> resources_seen;
632 for (int i = 0; i < new_resources_size; ++i) { 708 for (int i = 0; i < new_resources_size; ++i) {
633 if (resources_seen.find(new_resources[i].resource_url) != 709 if (resources_seen.find(new_resources[i].resource_url) !=
634 resources_seen.end()) { 710 resources_seen.end()) {
635 continue; 711 continue;
636 } 712 }
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 } 822 }
747 url_table_cache_.erase(url_to_erase); 823 url_table_cache_.erase(url_to_erase);
748 824
749 std::vector<GURL> urls_to_delete(1, url_to_erase); 825 std::vector<GURL> urls_to_delete(1, url_to_erase);
750 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 826 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
751 base::Bind(&ResourcePrefetchPredictorTables::DeleteRowsForUrls, 827 base::Bind(&ResourcePrefetchPredictorTables::DeleteRowsForUrls,
752 tables_, 828 tables_,
753 urls_to_delete)); 829 urls_to_delete));
754 } 830 }
755 831
756 void ResourcePrefetchPredictor::MaybeReportAccuracyStats( 832 void ResourcePrefetchPredictor::MaybeReportSimulatedAccuracyStats(
757 const NavigationID& navigation_id) const { 833 const NavigationID& navigation_id) const {
758 const GURL& main_frame_url = navigation_id.main_frame_url; 834 const GURL& main_frame_url = navigation_id.main_frame_url;
759 DCHECK(inflight_navigations_.find(navigation_id) != 835 DCHECK(inflight_navigations_.find(navigation_id) !=
760 inflight_navigations_.end()); 836 inflight_navigations_.end());
761 837
762 bool have_predictions_for_url = 838 bool have_predictions_for_url =
763 url_table_cache_.find(main_frame_url) != url_table_cache_.end(); 839 url_table_cache_.find(main_frame_url) != url_table_cache_.end();
764 if (have_predictions_for_url) { 840 if (have_predictions_for_url) {
765 RecordNavigationEvent(NAVIGATION_EVENT_HAVE_PREDICTIONS_FOR_URL); 841 RecordNavigationEvent(NAVIGATION_EVENT_HAVE_PREDICTIONS_FOR_URL);
766 } else { 842 } else {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 // Measure the ratio of total number of resources prefetched from network vs 924 // Measure the ratio of total number of resources prefetched from network vs
849 // the total number of resources fetched by the page from the network. 925 // the total number of resources fetched by the page from the network.
850 RPP_PREDICTED_HISTOGRAM_PERCENTAGE( 926 RPP_PREDICTED_HISTOGRAM_PERCENTAGE(
851 "PrefetchFromNetworkPercentOfTotalFromNetwork", 927 "PrefetchFromNetworkPercentOfTotalFromNetwork",
852 prefetch_network * 100.0 / total_resources_fetched_from_network); 928 prefetch_network * 100.0 / total_resources_fetched_from_network);
853 929
854 #undef RPP_PREDICTED_HISTOGRAM_PERCENTAGE 930 #undef RPP_PREDICTED_HISTOGRAM_PERCENTAGE
855 #undef RPP_PREDICTED_HISTOGRAM_COUNTS 931 #undef RPP_PREDICTED_HISTOGRAM_COUNTS
856 } 932 }
857 933
934 void ResourcePrefetchPredictor::MaybeReportAccuracyStats(
935 const NavigationID& navigation_id) {
936 NavigationMap::iterator nav_it = inflight_navigations_.find(navigation_id);
937 DCHECK(nav_it != inflight_navigations_.end());
938
939 ResultsMap::iterator results_it = results_map_.find(navigation_id);
940 bool have_prefetch_results = results_it != results_map_.end();
941 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.HavePrefetchResults",
942 have_prefetch_results);
943 if (!have_prefetch_results)
944 return;
945
946 // Annotate the results.
947 const std::vector<URLRequestSummary>& actual = nav_it->second;
948 ResourcePrefetcher::RequestVector* prefetched = results_it->second;
949
950 std::map<GURL, bool> actual_resources;
951 for (std::vector<URLRequestSummary>::const_iterator it = actual.begin();
952 it != actual.end(); ++it) {
953 actual_resources[it->resource_url] = it->was_cached;
954 }
955
956 int prefetch_cancelled = 0, prefetch_failed = 0, prefetch_not_started = 0;
957 // 'a_' -> actual, 'p_' -> predicted.
958 int p_cache_a_cache = 0, p_cache_a_network = 0, p_cache_a_notused = 0,
959 p_network_a_cache = 0, p_network_a_network = 0, p_network_a_notused = 0;
960
961 for (ResourcePrefetcher::RequestVector::iterator it = prefetched->begin();
962 it != prefetched->end(); ++it) {
963 ResourcePrefetcher::Request* req = *it;
964
965 // Set the usage states if the resource was actually used.
966 std::map<GURL, bool>::iterator actual_it = actual_resources.find(
967 req->resource_url);
968 if (actual_it != actual_resources.end()) {
969 if (actual_it->second) {
970 req->usage_status =
971 ResourcePrefetcher::Request::USAGE_STATUS_FROM_CACHE;
972 } else {
973 req->usage_status =
974 ResourcePrefetcher::Request::USAGE_STATUS_FROM_NETWORK;
975 }
976 }
977
978 switch (req->prefetch_status) {
979
980 // TODO(shishir): Add histogram for each cancellation reason.
981 case ResourcePrefetcher::Request::PREFETCH_STATUS_REDIRECTED:
982 case ResourcePrefetcher::Request::PREFETCH_STATUS_AUTH_REQUIRED:
983 case ResourcePrefetcher::Request::PREFETCH_STATUS_CERT_REQUIRED:
984 case ResourcePrefetcher::Request::PREFETCH_STATUS_CERT_ERROR:
985 case ResourcePrefetcher::Request::PREFETCH_STATUS_CANCELLED:
986 ++prefetch_cancelled;
987 break;
988
989 case ResourcePrefetcher::Request::PREFETCH_STATUS_FAILED:
990 ++prefetch_failed;
991 break;
992
993 case ResourcePrefetcher::Request::PREFETCH_STATUS_FROM_CACHE:
994 if (req->usage_status ==
995 ResourcePrefetcher::Request::USAGE_STATUS_FROM_CACHE)
996 ++p_cache_a_cache;
997 else if (req->usage_status ==
998 ResourcePrefetcher::Request::USAGE_STATUS_FROM_NETWORK)
999 ++p_cache_a_network;
1000 else
1001 ++p_cache_a_notused;
1002 break;
1003
1004 case ResourcePrefetcher::Request::PREFETCH_STATUS_FROM_NETWORK:
1005 if (req->usage_status ==
1006 ResourcePrefetcher::Request::USAGE_STATUS_FROM_CACHE)
1007 ++p_network_a_cache;
1008 else if (req->usage_status ==
1009 ResourcePrefetcher::Request::USAGE_STATUS_FROM_NETWORK)
1010 ++p_network_a_network;
1011 else
1012 ++p_network_a_notused;
1013 break;
1014
1015 case ResourcePrefetcher::Request::PREFETCH_STATUS_NOT_STARTED:
1016 ++prefetch_not_started;
1017 break;
1018
1019 case ResourcePrefetcher::Request::PREFETCH_STATUS_STARTED:
1020 DLOG(FATAL) << "Invalid prefetch status";
1021 break;
1022 }
1023 }
1024
1025 int total_prefetched = p_cache_a_cache + p_cache_a_network + p_cache_a_notused
1026 + p_network_a_cache + p_network_a_network + p_network_a_notused;
1027
1028 UMA_HISTOGRAM_PERCENTAGE(
1029 "ResourcePrefetchPredictor.PrefetchCancelled",
1030 prefetch_cancelled * 100.0 / total_prefetched);
1031 UMA_HISTOGRAM_PERCENTAGE(
1032 "ResourcePrefetchPredictor.PrefetchFailed",
1033 prefetch_failed * 100.0 / total_prefetched);
1034 UMA_HISTOGRAM_PERCENTAGE(
1035 "ResourcePrefetchPredictor.PrefetchFromCacheUsedFromCache",
1036 p_cache_a_cache * 100.0 / total_prefetched);
1037 UMA_HISTOGRAM_PERCENTAGE(
1038 "ResourcePrefetchPredictor.PrefetchFromCacheUsedFromNetwork",
1039 p_cache_a_network * 100.0 / total_prefetched);
1040 UMA_HISTOGRAM_PERCENTAGE(
1041 "ResourcePrefetchPredictor.PrefetchFromCacheNotUsed",
1042 p_cache_a_notused * 100.0 / total_prefetched);
1043 UMA_HISTOGRAM_PERCENTAGE(
1044 "ResourcePrefetchPredictor.PrefetchFromNetworkUsedFromCache",
1045 p_network_a_cache * 100.0 / total_prefetched);
1046 UMA_HISTOGRAM_PERCENTAGE(
1047 "ResourcePrefetchPredictor.PrefetchFromNetworkUsedFromNetwork",
1048 p_network_a_network * 100.0 / total_prefetched);
1049 UMA_HISTOGRAM_PERCENTAGE(
1050 "ResourcePrefetchPredictor.PrefetchFromNetworkNotUsed",
1051 p_network_a_notused * 100.0 / total_prefetched);
1052
1053 UMA_HISTOGRAM_PERCENTAGE(
1054 "ResourcePrefetchPredictor.PrefetchNotStarted",
1055 prefetch_not_started * 100.0 / (prefetch_not_started + total_prefetched));
1056 }
1057
858 void ResourcePrefetchPredictor::DeleteAllUrls() { 1058 void ResourcePrefetchPredictor::DeleteAllUrls() {
859 inflight_navigations_.clear(); 1059 inflight_navigations_.clear();
860 url_table_cache_.clear(); 1060 url_table_cache_.clear();
861 1061
862 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 1062 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
863 base::Bind(&ResourcePrefetchPredictorTables::DeleteAllRows, tables_)); 1063 base::Bind(&ResourcePrefetchPredictorTables::DeleteAllRows, tables_));
864 } 1064 }
865 1065
866 void ResourcePrefetchPredictor::DeleteUrls(const history::URLRows& urls) { 1066 void ResourcePrefetchPredictor::DeleteUrls(const history::URLRows& urls) {
867 std::vector<GURL> urls_to_delete; 1067 std::vector<GURL> urls_to_delete;
(...skipping 14 matching lines...) Expand all
882 tables_, 1082 tables_,
883 urls_to_delete)); 1083 urls_to_delete));
884 } 1084 }
885 1085
886 void ResourcePrefetchPredictor::SetTablesForTesting( 1086 void ResourcePrefetchPredictor::SetTablesForTesting(
887 scoped_refptr<ResourcePrefetchPredictorTables> tables) { 1087 scoped_refptr<ResourcePrefetchPredictorTables> tables) {
888 tables_ = tables; 1088 tables_ = tables;
889 } 1089 }
890 1090
891 } // namespace predictors 1091 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698