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

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 comment. 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 ResourcePrefetcher::RequestVector* requests) {
573 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
574
575 // Add the results to the results map.
576 if (!results_map_.insert(std::make_pair(navigation_id, requests)).second) {
577 DLOG(FATAL) << "Returning results for existing navigation.";
578 delete requests;
579 }
580 }
581
519 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() { 582 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() {
520 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 583 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
521 DCHECK_EQ(initialization_state_, INITIALIZING); 584 DCHECK_EQ(initialization_state_, INITIALIZING);
522 585
523 // Update the data with last visit info from in memory history db. 586 // Update the data with last visit info from in memory history db.
524 HistoryService* history_service = HistoryServiceFactory::GetForProfile( 587 HistoryService* history_service = HistoryServiceFactory::GetForProfile(
525 profile_, Profile::EXPLICIT_ACCESS); 588 profile_, Profile::EXPLICIT_ACCESS);
526 DCHECK(history_service); 589 DCHECK(history_service);
527 history::URLDatabase* url_db = history_service->InMemoryDatabase(); 590 history::URLDatabase* url_db = history_service->InMemoryDatabase();
528 if (url_db) { 591 if (url_db) {
(...skipping 29 matching lines...) Expand all
558 notification_registrar_.Add(this, 621 notification_registrar_.Add(this,
559 content::NOTIFICATION_LOAD_FROM_MEMORY_CACHE, 622 content::NOTIFICATION_LOAD_FROM_MEMORY_CACHE,
560 content::NotificationService::AllSources()); 623 content::NotificationService::AllSources());
561 notification_registrar_.Add(this, 624 notification_registrar_.Add(this,
562 chrome::NOTIFICATION_HISTORY_URLS_DELETED, 625 chrome::NOTIFICATION_HISTORY_URLS_DELETED,
563 content::Source<Profile>(profile_)); 626 content::Source<Profile>(profile_));
564 627
565 // TODO(shishir): Maybe listen for notifications for navigation being 628 // TODO(shishir): Maybe listen for notifications for navigation being
566 // abandoned and cleanup the inflight_navigations_. 629 // abandoned and cleanup the inflight_navigations_.
567 630
631 // Initialize the prefetch manager only if prefetching is enabled.
632 if (prerender::IsSpeculativeResourcePrefetchingEnabled(profile_)) {
633 prefetch_manager_ = new ResourcePrefetcherManager(
634 this, config_, profile_->GetRequestContext());
635 }
636
568 initialization_state_ = INITIALIZED; 637 initialization_state_ = INITIALIZED;
569 } 638 }
570 639
571 bool ResourcePrefetchPredictor::ShouldTrackUrl(const GURL& url) { 640 bool ResourcePrefetchPredictor::ShouldTrackUrl(const GURL& url) {
572 bool already_tracking = url_table_cache_.find(url) != url_table_cache_.end(); 641 bool already_tracking = url_table_cache_.find(url) != url_table_cache_.end();
573 642
574 HistoryService* history_service = HistoryServiceFactory::GetForProfile( 643 HistoryService* history_service = HistoryServiceFactory::GetForProfile(
575 profile_, Profile::EXPLICIT_ACCESS); 644 profile_, Profile::EXPLICIT_ACCESS);
576 DCHECK(history_service); 645 DCHECK(history_service);
577 history::URLDatabase* url_db = history_service->InMemoryDatabase(); 646 history::URLDatabase* url_db = history_service->InMemoryDatabase();
(...skipping 17 matching lines...) Expand all
595 664
596 if (inflight_navigations_.find(navigation_id) == 665 if (inflight_navigations_.find(navigation_id) ==
597 inflight_navigations_.end()) { 666 inflight_navigations_.end()) {
598 RecordNavigationEvent(NAVIGATION_EVENT_ONLOAD_UNTRACKED_URL); 667 RecordNavigationEvent(NAVIGATION_EVENT_ONLOAD_UNTRACKED_URL);
599 return; 668 return;
600 } 669 }
601 670
602 RecordNavigationEvent(NAVIGATION_EVENT_ONLOAD_TRACKED_URL); 671 RecordNavigationEvent(NAVIGATION_EVENT_ONLOAD_TRACKED_URL);
603 672
604 // Report any stats. 673 // Report any stats.
605 MaybeReportAccuracyStats(navigation_id); 674 if (prefetch_manager_.get()) {
675 MaybeReportAccuracyStats(navigation_id);
676 } else {
677 MaybeReportSimulatedAccuracyStats(navigation_id);
678 }
606 679
607 // Update the URL table. 680 // Update the URL table.
608 const GURL& main_frame_url = navigation_id.main_frame_url; 681 const GURL& main_frame_url = navigation_id.main_frame_url;
609 if (ShouldTrackUrl(main_frame_url)) { 682 if (ShouldTrackUrl(main_frame_url)) {
610 RecordNavigationEvent(NAVIGATION_EVENT_SHOULD_TRACK_URL); 683 RecordNavigationEvent(NAVIGATION_EVENT_SHOULD_TRACK_URL);
611 LearnUrlNavigation(main_frame_url, inflight_navigations_[navigation_id]); 684 LearnUrlNavigation(main_frame_url, inflight_navigations_[navigation_id]);
612 } else { 685 } else {
613 RecordNavigationEvent(NAVIGATION_EVENT_SHOULD_NOT_TRACK_URL); 686 RecordNavigationEvent(NAVIGATION_EVENT_SHOULD_NOT_TRACK_URL);
614 } 687 }
615 688
616 // Remove the navigation. 689 // Remove the navigation.
617 inflight_navigations_.erase(navigation_id); 690 inflight_navigations_.erase(navigation_id);
691 delete results_map_[navigation_id];
692 results_map_.erase(navigation_id);
618 } 693 }
619 694
620 void ResourcePrefetchPredictor::LearnUrlNavigation( 695 void ResourcePrefetchPredictor::LearnUrlNavigation(
621 const GURL& main_frame_url, 696 const GURL& main_frame_url,
622 const std::vector<URLRequestSummary>& new_resources) { 697 const std::vector<URLRequestSummary>& new_resources) {
623 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 698 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
624 699
625 if (url_table_cache_.find(main_frame_url) == url_table_cache_.end()) { 700 if (url_table_cache_.find(main_frame_url) == url_table_cache_.end()) {
626 if (url_table_cache_.size() >= config_.max_urls_to_track) 701 if (static_cast<int>(url_table_cache_.size()) >= config_.max_urls_to_track)
627 RemoveAnEntryFromUrlDB(); 702 RemoveAnEntryFromUrlDB();
628 703
629 url_table_cache_[main_frame_url].last_visit = base::Time::Now(); 704 url_table_cache_[main_frame_url].last_visit = base::Time::Now();
630 int new_resources_size = static_cast<int>(new_resources.size()); 705 int new_resources_size = static_cast<int>(new_resources.size());
631 std::set<GURL> resources_seen; 706 std::set<GURL> resources_seen;
632 for (int i = 0; i < new_resources_size; ++i) { 707 for (int i = 0; i < new_resources_size; ++i) {
633 if (resources_seen.find(new_resources[i].resource_url) != 708 if (resources_seen.find(new_resources[i].resource_url) !=
634 resources_seen.end()) { 709 resources_seen.end()) {
635 continue; 710 continue;
636 } 711 }
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 } 821 }
747 url_table_cache_.erase(url_to_erase); 822 url_table_cache_.erase(url_to_erase);
748 823
749 std::vector<GURL> urls_to_delete(1, url_to_erase); 824 std::vector<GURL> urls_to_delete(1, url_to_erase);
750 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 825 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
751 base::Bind(&ResourcePrefetchPredictorTables::DeleteRowsForUrls, 826 base::Bind(&ResourcePrefetchPredictorTables::DeleteRowsForUrls,
752 tables_, 827 tables_,
753 urls_to_delete)); 828 urls_to_delete));
754 } 829 }
755 830
756 void ResourcePrefetchPredictor::MaybeReportAccuracyStats( 831 void ResourcePrefetchPredictor::MaybeReportSimulatedAccuracyStats(
757 const NavigationID& navigation_id) const { 832 const NavigationID& navigation_id) const {
758 const GURL& main_frame_url = navigation_id.main_frame_url; 833 const GURL& main_frame_url = navigation_id.main_frame_url;
759 DCHECK(inflight_navigations_.find(navigation_id) != 834 DCHECK(inflight_navigations_.find(navigation_id) !=
760 inflight_navigations_.end()); 835 inflight_navigations_.end());
761 836
762 bool have_predictions_for_url = 837 bool have_predictions_for_url =
763 url_table_cache_.find(main_frame_url) != url_table_cache_.end(); 838 url_table_cache_.find(main_frame_url) != url_table_cache_.end();
764 if (have_predictions_for_url) { 839 if (have_predictions_for_url) {
765 RecordNavigationEvent(NAVIGATION_EVENT_HAVE_PREDICTIONS_FOR_URL); 840 RecordNavigationEvent(NAVIGATION_EVENT_HAVE_PREDICTIONS_FOR_URL);
766 } else { 841 } 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 923 // 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. 924 // the total number of resources fetched by the page from the network.
850 RPP_PREDICTED_HISTOGRAM_PERCENTAGE( 925 RPP_PREDICTED_HISTOGRAM_PERCENTAGE(
851 "PrefetchFromNetworkPercentOfTotalFromNetwork", 926 "PrefetchFromNetworkPercentOfTotalFromNetwork",
852 prefetch_network * 100.0 / total_resources_fetched_from_network); 927 prefetch_network * 100.0 / total_resources_fetched_from_network);
853 928
854 #undef RPP_PREDICTED_HISTOGRAM_PERCENTAGE 929 #undef RPP_PREDICTED_HISTOGRAM_PERCENTAGE
855 #undef RPP_PREDICTED_HISTOGRAM_COUNTS 930 #undef RPP_PREDICTED_HISTOGRAM_COUNTS
856 } 931 }
857 932
933 void ResourcePrefetchPredictor::MaybeReportAccuracyStats(
934 const NavigationID& navigation_id) {
935 NavigationMap::iterator nav_it = inflight_navigations_.find(navigation_id);
936 DCHECK(nav_it != inflight_navigations_.end());
937
938 ResultsMap::iterator results_it = results_map_.find(navigation_id);
939 bool have_prefetch_results = results_it != results_map_.end();
940 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.HavePrefetchResults",
941 have_prefetch_results);
942 if (!have_prefetch_results)
943 return;
944
945 // Annotate the results.
946 const std::vector<URLRequestSummary>& actual = nav_it->second;
947 ResourcePrefetcher::RequestVector* prefetched = results_it->second;
948
949 std::map<GURL, bool> actual_resources;
950 for (std::vector<URLRequestSummary>::const_iterator it = actual.begin();
951 it != actual.end(); ++it) {
952 actual_resources[it->resource_url] = it->was_cached;
953 }
954
955 int prefetch_cancelled = 0, prefetch_failed = 0, prefetch_not_started = 0;
956 // 'a_' -> actual, 'p_' -> predicted.
957 int p_cache_a_cache = 0, p_cache_a_network = 0, p_cache_a_notused = 0,
958 p_network_a_cache = 0, p_network_a_network = 0, p_network_a_notused = 0;
959
960 for (ResourcePrefetcher::RequestVector::iterator it = prefetched->begin();
961 it != prefetched->end(); ++it) {
962 ResourcePrefetcher::Request* req = *it;
963
964 // Set the usage states if the resource was actually used.
965 std::map<GURL, bool>::iterator actual_it = actual_resources.find(
966 req->resource_url);
967 if (actual_it != actual_resources.end()) {
968 if (actual_it->second) {
969 req->usage_status =
970 ResourcePrefetcher::Request::USAGE_STATUS_FROM_CACHE;
971 } else {
972 req->usage_status =
973 ResourcePrefetcher::Request::USAGE_STATUS_FROM_NETWORK;
974 }
975 }
976
977 switch (req->prefetch_status) {
978
979 // TODO(shishir): Add histogram for each cancellation reason.
980 case ResourcePrefetcher::Request::PREFETCH_STATUS_REDIRECTED:
981 case ResourcePrefetcher::Request::PREFETCH_STATUS_AUTH_REQUIRED:
982 case ResourcePrefetcher::Request::PREFETCH_STATUS_CERT_REQUIRED:
983 case ResourcePrefetcher::Request::PREFETCH_STATUS_CERT_ERROR:
984 case ResourcePrefetcher::Request::PREFETCH_STATUS_CANCELLED:
985 ++prefetch_cancelled;
986 break;
987
988 case ResourcePrefetcher::Request::PREFETCH_STATUS_FAILED:
989 ++prefetch_failed;
990 break;
991
992 case ResourcePrefetcher::Request::PREFETCH_STATUS_FROM_CACHE:
993 if (req->usage_status ==
994 ResourcePrefetcher::Request::USAGE_STATUS_FROM_CACHE)
995 ++p_cache_a_cache;
996 else if (req->usage_status ==
997 ResourcePrefetcher::Request::USAGE_STATUS_FROM_NETWORK)
998 ++p_cache_a_network;
999 else
1000 ++p_cache_a_notused;
1001 break;
1002
1003 case ResourcePrefetcher::Request::PREFETCH_STATUS_FROM_NETWORK:
1004 if (req->usage_status ==
1005 ResourcePrefetcher::Request::USAGE_STATUS_FROM_CACHE)
1006 ++p_network_a_cache;
1007 else if (req->usage_status ==
1008 ResourcePrefetcher::Request::USAGE_STATUS_FROM_NETWORK)
1009 ++p_network_a_network;
1010 else
1011 ++p_network_a_notused;
1012 break;
1013
1014 case ResourcePrefetcher::Request::PREFETCH_STATUS_NOT_STARTED:
1015 ++prefetch_not_started;
1016 break;
1017
1018 case ResourcePrefetcher::Request::PREFETCH_STATUS_STARTED:
1019 DLOG(FATAL) << "Invalid prefetch status";
1020 break;
1021 }
1022 }
1023
1024 int total_prefetched = p_cache_a_cache + p_cache_a_network + p_cache_a_notused
1025 + p_network_a_cache + p_network_a_network + p_network_a_notused;
1026
1027 UMA_HISTOGRAM_PERCENTAGE(
1028 "ResourcePrefetchPredictor.PrefetchCancelled",
1029 prefetch_cancelled * 100.0 / total_prefetched);
1030 UMA_HISTOGRAM_PERCENTAGE(
1031 "ResourcePrefetchPredictor.PrefetchFailed",
1032 prefetch_failed * 100.0 / total_prefetched);
1033 UMA_HISTOGRAM_PERCENTAGE(
1034 "ResourcePrefetchPredictor.PrefetchFromCacheUsedFromCache",
1035 p_cache_a_cache * 100.0 / total_prefetched);
1036 UMA_HISTOGRAM_PERCENTAGE(
1037 "ResourcePrefetchPredictor.PrefetchFromCacheUsedFromNetwork",
1038 p_cache_a_network * 100.0 / total_prefetched);
1039 UMA_HISTOGRAM_PERCENTAGE(
1040 "ResourcePrefetchPredictor.PrefetchFromCacheNotUsed",
1041 p_cache_a_notused * 100.0 / total_prefetched);
1042 UMA_HISTOGRAM_PERCENTAGE(
1043 "ResourcePrefetchPredictor.PrefetchFromNetworkUsedFromCache",
1044 p_network_a_cache * 100.0 / total_prefetched);
1045 UMA_HISTOGRAM_PERCENTAGE(
1046 "ResourcePrefetchPredictor.PrefetchFromNetworkUsedFromNetwork",
1047 p_network_a_network * 100.0 / total_prefetched);
1048 UMA_HISTOGRAM_PERCENTAGE(
1049 "ResourcePrefetchPredictor.PrefetchFromNetworkNotUsed",
1050 p_network_a_notused * 100.0 / total_prefetched);
1051
1052 UMA_HISTOGRAM_PERCENTAGE(
1053 "ResourcePrefetchPredictor.PrefetchNotStarted",
1054 prefetch_not_started * 100.0 / (prefetch_not_started + total_prefetched));
1055 }
1056
858 void ResourcePrefetchPredictor::DeleteAllUrls() { 1057 void ResourcePrefetchPredictor::DeleteAllUrls() {
859 inflight_navigations_.clear(); 1058 inflight_navigations_.clear();
860 url_table_cache_.clear(); 1059 url_table_cache_.clear();
861 1060
862 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 1061 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
863 base::Bind(&ResourcePrefetchPredictorTables::DeleteAllRows, tables_)); 1062 base::Bind(&ResourcePrefetchPredictorTables::DeleteAllRows, tables_));
864 } 1063 }
865 1064
866 void ResourcePrefetchPredictor::DeleteUrls(const history::URLRows& urls) { 1065 void ResourcePrefetchPredictor::DeleteUrls(const history::URLRows& urls) {
867 std::vector<GURL> urls_to_delete; 1066 std::vector<GURL> urls_to_delete;
(...skipping 14 matching lines...) Expand all
882 tables_, 1081 tables_,
883 urls_to_delete)); 1082 urls_to_delete));
884 } 1083 }
885 1084
886 void ResourcePrefetchPredictor::SetTablesForTesting( 1085 void ResourcePrefetchPredictor::SetTablesForTesting(
887 scoped_refptr<ResourcePrefetchPredictorTables> tables) { 1086 scoped_refptr<ResourcePrefetchPredictorTables> tables) {
888 tables_ = tables; 1087 tables_ = tables;
889 } 1088 }
890 1089
891 } // namespace predictors 1090 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698