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

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, 4 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/time.h" 14 #include "base/time.h"
15 #include "chrome/browser/history/history.h" 15 #include "chrome/browser/history/history.h"
16 #include "chrome/browser/history/history_notifications.h" 16 #include "chrome/browser/history/history_notifications.h"
17 #include "chrome/browser/history/in_memory_database.h" 17 #include "chrome/browser/history/in_memory_database.h"
18 #include "chrome/browser/history/url_database.h" 18 #include "chrome/browser/history/url_database.h"
19 #include "chrome/browser/predictors/predictor_database.h" 19 #include "chrome/browser/predictors/predictor_database.h"
20 #include "chrome/browser/predictors/predictor_database_factory.h" 20 #include "chrome/browser/predictors/predictor_database_factory.h"
21 #include "chrome/browser/predictors/resource_prefetcher_manager.h"
21 #include "chrome/browser/prerender/prerender_field_trial.h" 22 #include "chrome/browser/prerender/prerender_field_trial.h"
22 #include "chrome/browser/profiles/profile.h" 23 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/common/chrome_notification_types.h" 24 #include "chrome/common/chrome_notification_types.h"
24 #include "chrome/common/chrome_switches.h" 25 #include "chrome/common/chrome_switches.h"
25 #include "chrome/common/url_constants.h" 26 #include "chrome/common/url_constants.h"
26 #include "content/public/browser/browser_thread.h" 27 #include "content/public/browser/browser_thread.h"
27 #include "content/public/browser/load_from_memory_cache_details.h" 28 #include "content/public/browser/load_from_memory_cache_details.h"
28 #include "content/public/browser/navigation_controller.h" 29 #include "content/public/browser/navigation_controller.h"
29 #include "content/public/browser/notification_service.h" 30 #include "content/public/browser/notification_service.h"
30 #include "content/public/browser/notification_source.h" 31 #include "content/public/browser/notification_source.h"
(...skipping 30 matching lines...) Expand all
61 RESOURCE_STATUS_URL_TOO_LONG = 16, 62 RESOURCE_STATUS_URL_TOO_LONG = 16,
62 RESOURCE_STATUS_NOT_CACHEABLE = 32, 63 RESOURCE_STATUS_NOT_CACHEABLE = 32,
63 RESOURCE_STATUS_HEADERS_MISSING = 64, 64 RESOURCE_STATUS_HEADERS_MISSING = 64,
64 RESOURCE_STATUS_MAX = 128, 65 RESOURCE_STATUS_MAX = 128,
65 }; 66 };
66 67
67 } // namespace 68 } // namespace
68 69
69 namespace predictors { 70 namespace predictors {
70 71
71 ResourcePrefetchPredictor::Config::Config()
72 : max_navigation_lifetime_seconds(60),
73 max_urls_to_track(500),
74 min_url_visit_count(3),
75 max_resources_per_entry(50),
76 max_consecutive_misses(3),
77 num_resources_assumed_prefetched(25) {
78 }
79
80 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary() 72 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary()
81 : resource_type(ResourceType::LAST_TYPE), 73 : resource_type(ResourceType::LAST_TYPE),
82 was_cached(false) { 74 was_cached(false) {
83 } 75 }
84 76
85 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary( 77 ResourcePrefetchPredictor::URLRequestSummary::URLRequestSummary(
86 const URLRequestSummary& other) 78 const URLRequestSummary& other)
87 : navigation_id(other.navigation_id), 79 : navigation_id(other.navigation_id),
88 resource_url(other.resource_url), 80 resource_url(other.resource_url),
89 resource_type(other.resource_type), 81 resource_type(other.resource_type),
90 mime_type(other.mime_type), 82 mime_type(other.mime_type),
91 was_cached(other.was_cached) { 83 was_cached(other.was_cached) {
92 } 84 }
93 85
94 ResourcePrefetchPredictor::URLRequestSummary::~URLRequestSummary() { 86 ResourcePrefetchPredictor::URLRequestSummary::~URLRequestSummary() {
95 } 87 }
96 88
97 ResourcePrefetchPredictor::UrlTableCacheValue::UrlTableCacheValue() { 89 ResourcePrefetchPredictor::UrlTableCacheValue::UrlTableCacheValue() {
98 } 90 }
99 91
100 ResourcePrefetchPredictor::UrlTableCacheValue::~UrlTableCacheValue() { 92 ResourcePrefetchPredictor::UrlTableCacheValue::~UrlTableCacheValue() {
101 } 93 }
102 94
103 ResourcePrefetchPredictor::ResourcePrefetchPredictor( 95 ResourcePrefetchPredictor::ResourcePrefetchPredictor(
104 const Config& config, 96 const ResourcePrefetchPredictorConfig& config,
105 Profile* profile) 97 Profile* profile)
106 : profile_(profile), 98 : profile_(profile),
107 config_(config), 99 config_(config),
108 initialization_state_(NOT_INITIALIZED), 100 initialization_state_(NOT_INITIALIZED),
109 tables_(PredictorDatabaseFactory::GetForProfile( 101 tables_(PredictorDatabaseFactory::GetForProfile(
110 profile)->resource_prefetch_tables()) { 102 profile)->resource_prefetch_tables()),
103 results_map_deleter_(&results_map_) {
111 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 104 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
112 } 105 }
113 106
114 ResourcePrefetchPredictor::~ResourcePrefetchPredictor() { 107 ResourcePrefetchPredictor::~ResourcePrefetchPredictor() {
115 } 108 prefetch_manager_->ShutdownOnUIThread();
116 109 prefetch_manager_ = NULL;
117 // static
118 bool ResourcePrefetchPredictor::IsEnabled(Profile* profile) {
119 return prerender::IsSpeculativeResourcePrefetchingLearningEnabled(profile);
120 } 110 }
121 111
122 void ResourcePrefetchPredictor::LazilyInitialize() { 112 void ResourcePrefetchPredictor::LazilyInitialize() {
123 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 113 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
124 114
125 DCHECK_EQ(initialization_state_, NOT_INITIALIZED); 115 DCHECK_EQ(initialization_state_, NOT_INITIALIZED);
126 initialization_state_ = INITIALIZING; 116 initialization_state_ = INITIALIZING;
127 117
128 // Request the in-memory database from the history to force it to load so it's 118 // Request the in-memory database from the history to force it to load so it's
129 // available as soon as possible. 119 // available as soon as possible.
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 void ResourcePrefetchPredictor::RecordURLRequest( 276 void ResourcePrefetchPredictor::RecordURLRequest(
287 const URLRequestSummary& request) { 277 const URLRequestSummary& request) {
288 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 278 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
289 279
290 if (initialization_state_ == NOT_INITIALIZED) { 280 if (initialization_state_ == NOT_INITIALIZED) {
291 LazilyInitialize(); 281 LazilyInitialize();
292 return; 282 return;
293 } else if (initialization_state_ != INITIALIZED) { 283 } else if (initialization_state_ != INITIALIZED) {
294 return; 284 return;
295 } 285 }
296 DCHECK_EQ(INITIALIZED, initialization_state_);
297 286
298 CHECK_EQ(request.resource_type, ResourceType::MAIN_FRAME); 287 CHECK_EQ(request.resource_type, ResourceType::MAIN_FRAME);
299 OnMainFrameRequest(request); 288 OnMainFrameRequest(request);
300 } 289 }
301 290
302 void ResourcePrefetchPredictor::RecordUrlResponse( 291 void ResourcePrefetchPredictor::RecordUrlResponse(
303 const URLRequestSummary& response) { 292 const URLRequestSummary& response) {
304 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 293 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
305 if (initialization_state_ != INITIALIZED) 294 if (initialization_state_ != INITIALIZED)
306 return; 295 return;
(...skipping 18 matching lines...) Expand all
325 const URLRequestSummary& request) { 314 const URLRequestSummary& request) {
326 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 315 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
327 DCHECK_EQ(INITIALIZED, initialization_state_); 316 DCHECK_EQ(INITIALIZED, initialization_state_);
328 317
329 // Cleanup older navigations. 318 // Cleanup older navigations.
330 CleanupAbandonedNavigations(request.navigation_id); 319 CleanupAbandonedNavigations(request.navigation_id);
331 320
332 // New empty navigation entry. 321 // New empty navigation entry.
333 inflight_navigations_.insert(std::make_pair( 322 inflight_navigations_.insert(std::make_pair(
334 request.navigation_id, std::vector<URLRequestSummary>())); 323 request.navigation_id, std::vector<URLRequestSummary>()));
324
325 // If prefetching is enabled, and we can prefetch something, start
326 // prefetching.
327 if (!prefetch_manager_.get())
328 return;
329
330 const GURL& main_frame_url = request.navigation_id.main_frame_url;
331 const UrlTableCacheMap::const_iterator value_iter = url_table_cache_.find(
332 main_frame_url);
333 if (value_iter == url_table_cache_.end())
334 return;
335
336 const UrlTableCacheValue& value = value_iter->second;
337
338 scoped_ptr<ResourcePrefetcher::RequestVector> requests(
339 new ResourcePrefetcher::RequestVector);
340 for (UrlTableRowVector::const_iterator it = value.rows.begin();
341 it != value.rows.end(); ++it) {
342 float confidence = static_cast<float>(it->number_of_hits) /
343 (it->number_of_hits + it->number_of_misses);
344 if (confidence < config_.min_resource_confidence_to_trigger_prefetch ||
345 it->number_of_hits < config_.min_resource_hits_to_trigger_prefetch) {
346 continue;
347 }
348
349 ResourcePrefetcher::Request* req = new ResourcePrefetcher::Request(
350 it->resource_url);
351 requests->push_back(req);
352 }
353
354 if (requests->empty())
355 return;
356
357 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
358 base::Bind(&ResourcePrefetcherManager::MaybeAddPrefetch,
359 prefetch_manager_,
360 request.navigation_id,
361 base::Passed(requests.Pass())));
dominich 2012/08/02 15:00:50 I believe you can use &requests instead of calling
Shishir 2012/08/02 22:06:54 Done.
335 } 362 }
336 363
337 void ResourcePrefetchPredictor::OnMainFrameResponse( 364 void ResourcePrefetchPredictor::OnMainFrameResponse(
338 const URLRequestSummary& response) { 365 const URLRequestSummary& response) {
339 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 366 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
367 if (initialization_state_ != INITIALIZED)
368 return;
340 369
341 // TODO(shishir): The prefreshing will be stopped here. 370 if (prefetch_manager_.get())
371 BrowserThread::PostTask(
372 BrowserThread::IO, FROM_HERE,
373 base::Bind(&ResourcePrefetcherManager::MaybeRemovePrefetch,
374 prefetch_manager_,
375 response.navigation_id));
342 } 376 }
343 377
344 void ResourcePrefetchPredictor::OnMainFrameRedirect( 378 void ResourcePrefetchPredictor::OnMainFrameRedirect(
345 const URLRequestSummary& response) { 379 const URLRequestSummary& response) {
346 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 380 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
347 381
348 inflight_navigations_.erase(response.navigation_id); 382 inflight_navigations_.erase(response.navigation_id);
349 } 383 }
350 384
351 void ResourcePrefetchPredictor::OnSubresourceResponse( 385 void ResourcePrefetchPredictor::OnSubresourceResponse(
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 if (it->first.IsSameRenderer(navigation_id) || 422 if (it->first.IsSameRenderer(navigation_id) ||
389 (time_now - it->first.creation_time > max_navigation_age)) { 423 (time_now - it->first.creation_time > max_navigation_age)) {
390 inflight_navigations_.erase(it++); 424 inflight_navigations_.erase(it++);
391 UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.NavigationStatus", 425 UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.NavigationStatus",
392 NAVIGATION_STATUS_ABANDONED, 426 NAVIGATION_STATUS_ABANDONED,
393 NAVIGATION_STATUS_COUNT); 427 NAVIGATION_STATUS_COUNT);
394 } else { 428 } else {
395 ++it; 429 ++it;
396 } 430 }
397 } 431 }
432 for (ResultsMap::iterator it = results_map_.begin();
433 it != results_map_.end();) {
434 if (it->first.IsSameRenderer(navigation_id) ||
435 (time_now - it->first.creation_time > max_navigation_age)) {
436 delete it->second;
437 results_map_.erase(it++);
438 } else {
439 ++it;
440 }
441 }
398 } 442 }
399 443
400 void ResourcePrefetchPredictor::Observe( 444 void ResourcePrefetchPredictor::Observe(
401 int type, 445 int type,
402 const content::NotificationSource& source, 446 const content::NotificationSource& source,
403 const content::NotificationDetails& details) { 447 const content::NotificationDetails& details) {
404 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 448 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
405 449
406 switch (type) { 450 switch (type) {
407 case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME: { 451 case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME: {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 DeleteUrls(urls_deleted_details->rows); 494 DeleteUrls(urls_deleted_details->rows);
451 break; 495 break;
452 } 496 }
453 497
454 default: 498 default:
455 NOTREACHED() << "Unexpected notification observed."; 499 NOTREACHED() << "Unexpected notification observed.";
456 break; 500 break;
457 } 501 }
458 } 502 }
459 503
504 void ResourcePrefetchPredictor::FinishedPrefetchForNavigation(
505 const NavigationID& navigation_id,
506 scoped_ptr<ResourcePrefetcher::RequestVector> requests) {
507 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
508
509 // Add the results to the results map.
510 ResourcePrefetcher::RequestVector* req = requests.release();
511 if (!results_map_.insert(std::make_pair(navigation_id, req)).second) {
512 DLOG(FATAL) << "Returning results for existing navigation.";
513 delete req;
514 }
515 }
516
460 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() { 517 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() {
461 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 518 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
462 DCHECK_EQ(initialization_state_, INITIALIZING); 519 DCHECK_EQ(initialization_state_, INITIALIZING);
463 520
464 // Update the data with last visit info from in memory history db. 521 // Update the data with last visit info from in memory history db.
465 HistoryService* history_service = 522 HistoryService* history_service =
466 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); 523 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
467 DCHECK(history_service); 524 DCHECK(history_service);
468 history::URLDatabase* url_db = history_service->InMemoryDatabase(); 525 history::URLDatabase* url_db = history_service->InMemoryDatabase();
469 if (url_db) { 526 if (url_db) {
(...skipping 22 matching lines...) Expand all
492 notification_registrar_.Add(this, 549 notification_registrar_.Add(this,
493 content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, 550 content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
494 content::NotificationService::AllSources()); 551 content::NotificationService::AllSources());
495 notification_registrar_.Add(this, 552 notification_registrar_.Add(this,
496 chrome::NOTIFICATION_HISTORY_URLS_DELETED, 553 chrome::NOTIFICATION_HISTORY_URLS_DELETED,
497 content::Source<Profile>(profile_)); 554 content::Source<Profile>(profile_));
498 555
499 // TODO(shishir): Maybe listen for notifications for navigation being 556 // TODO(shishir): Maybe listen for notifications for navigation being
500 // abandoned and cleanup the inflight_navigations_. 557 // abandoned and cleanup the inflight_navigations_.
501 558
559 // Initialize the prefetch manager only if prefetching is enabled.
560 if (prerender::IsSpeculativeResourcePrefetchingEnabled(profile_)) {
561 prefetch_manager_ = new ResourcePrefetcherManager(
562 this, config_, profile_->GetRequestContext());
563 }
564
502 initialization_state_ = INITIALIZED; 565 initialization_state_ = INITIALIZED;
503 } 566 }
504 567
505 bool ResourcePrefetchPredictor::ShouldTrackUrl(const GURL& url) { 568 bool ResourcePrefetchPredictor::ShouldTrackUrl(const GURL& url) {
506 if (url_table_cache_.find(url) != url_table_cache_.end()) 569 if (url_table_cache_.find(url) != url_table_cache_.end())
507 return true; 570 return true;
508 571
509 HistoryService* history_service = 572 HistoryService* history_service =
510 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); 573 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
511 DCHECK(history_service); 574 DCHECK(history_service);
(...skipping 16 matching lines...) Expand all
528 NAVIGATION_STATUS_COMPLETE_ABANDONED, 591 NAVIGATION_STATUS_COMPLETE_ABANDONED,
529 NAVIGATION_STATUS_COUNT); 592 NAVIGATION_STATUS_COUNT);
530 return; 593 return;
531 } 594 }
532 595
533 UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.NavigationStatus", 596 UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.NavigationStatus",
534 NAVIGATION_STATUS_COMPLETE, 597 NAVIGATION_STATUS_COMPLETE,
535 NAVIGATION_STATUS_COUNT); 598 NAVIGATION_STATUS_COUNT);
536 599
537 // Report any stats. 600 // Report any stats.
538 MaybeReportAccuracyStats(navigation_id); 601 if (prefetch_manager_.get()) {
602 MaybeReportAccuracyStats(navigation_id);
603 } else {
604 MaybeReportSimulatedAccuracyStats(navigation_id);
605 }
539 606
540 // Update the URL table. 607 // Update the URL table.
541 const GURL& main_frame_url = navigation_id.main_frame_url; 608 const GURL& main_frame_url = navigation_id.main_frame_url;
542 if (ShouldTrackUrl(main_frame_url)) 609 if (ShouldTrackUrl(main_frame_url))
543 LearnUrlNavigation(main_frame_url, inflight_navigations_[navigation_id]); 610 LearnUrlNavigation(main_frame_url, inflight_navigations_[navigation_id]);
544 611
545 // Remove the navigation. 612 // Remove the navigation.
546 inflight_navigations_.erase(navigation_id); 613 inflight_navigations_.erase(navigation_id);
614 delete results_map_[navigation_id];
615 results_map_.erase(navigation_id);
547 } 616 }
548 617
549 void ResourcePrefetchPredictor::LearnUrlNavigation( 618 void ResourcePrefetchPredictor::LearnUrlNavigation(
550 const GURL& main_frame_url, 619 const GURL& main_frame_url,
551 const std::vector<URLRequestSummary>& new_resources) { 620 const std::vector<URLRequestSummary>& new_resources) {
552 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 621 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
553 622
554 if (url_table_cache_.find(main_frame_url) == url_table_cache_.end()) { 623 if (url_table_cache_.find(main_frame_url) == url_table_cache_.end()) {
555 if (url_table_cache_.size() >= config_.max_urls_to_track) 624 if (static_cast<int>(url_table_cache_.size()) >= config_.max_urls_to_track)
dominich 2012/08/02 15:00:50 if it makes sense for this to be size_t that's fin
Shishir 2012/08/02 22:06:54 Lets leave it at int to be consistent through out.
556 RemoveAnEntryFromUrlDB(); 625 RemoveAnEntryFromUrlDB();
557 626
558 url_table_cache_[main_frame_url].last_visit = base::Time::Now(); 627 url_table_cache_[main_frame_url].last_visit = base::Time::Now();
559 int new_resources_size = static_cast<int>(new_resources.size()); 628 int new_resources_size = static_cast<int>(new_resources.size());
560 std::set<GURL> resources_seen; 629 std::set<GURL> resources_seen;
561 for (int i = 0; i < new_resources_size; ++i) { 630 for (int i = 0; i < new_resources_size; ++i) {
562 if (resources_seen.find(new_resources[i].resource_url) != 631 if (resources_seen.find(new_resources[i].resource_url) !=
563 resources_seen.end()) { 632 resources_seen.end()) {
564 continue; 633 continue;
565 } 634 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 } 742 }
674 url_table_cache_.erase(url_to_erase); 743 url_table_cache_.erase(url_to_erase);
675 744
676 std::vector<GURL> urls_to_delete(1, url_to_erase); 745 std::vector<GURL> urls_to_delete(1, url_to_erase);
677 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 746 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
678 base::Bind(&ResourcePrefetchPredictorTables::DeleteRowsForUrls, 747 base::Bind(&ResourcePrefetchPredictorTables::DeleteRowsForUrls,
679 tables_, 748 tables_,
680 urls_to_delete)); 749 urls_to_delete));
681 } 750 }
682 751
683 void ResourcePrefetchPredictor::MaybeReportAccuracyStats( 752 void ResourcePrefetchPredictor::MaybeReportSimulatedAccuracyStats(
684 const NavigationID& navigation_id) const { 753 const NavigationID& navigation_id) const {
685 const GURL& main_frame_url = navigation_id.main_frame_url; 754 const GURL& main_frame_url = navigation_id.main_frame_url;
686 DCHECK(inflight_navigations_.find(navigation_id) != 755 DCHECK(inflight_navigations_.find(navigation_id) !=
687 inflight_navigations_.end()); 756 inflight_navigations_.end());
688 757
689 bool have_predictions_for_url = 758 bool have_predictions_for_url =
690 url_table_cache_.find(main_frame_url) != url_table_cache_.end(); 759 url_table_cache_.find(main_frame_url) != url_table_cache_.end();
691 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.HavePredictionsForUrl", 760 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.HavePredictionsForUrl",
692 have_predictions_for_url); 761 have_predictions_for_url);
693 if (!have_predictions_for_url) 762 if (!have_predictions_for_url)
(...skipping 29 matching lines...) Expand all
723 "ResourcePrefetchPredictor.PredictedPrefetchMisses", 792 "ResourcePrefetchPredictor.PredictedPrefetchMisses",
724 prefetch_missed * 100.0 / num_assumed_prefetched); 793 prefetch_missed * 100.0 / num_assumed_prefetched);
725 UMA_HISTOGRAM_PERCENTAGE( 794 UMA_HISTOGRAM_PERCENTAGE(
726 "ResourcePrefetchPredictor.PredictedPrefetchFromCache", 795 "ResourcePrefetchPredictor.PredictedPrefetchFromCache",
727 prefetch_cached * 100.0 / num_assumed_prefetched); 796 prefetch_cached * 100.0 / num_assumed_prefetched);
728 UMA_HISTOGRAM_PERCENTAGE( 797 UMA_HISTOGRAM_PERCENTAGE(
729 "ResourcePrefetchPredictor.PredictedPrefetchFromNetwork", 798 "ResourcePrefetchPredictor.PredictedPrefetchFromNetwork",
730 prefetch_network * 100.0 / num_assumed_prefetched); 799 prefetch_network * 100.0 / num_assumed_prefetched);
731 } 800 }
732 801
802 void ResourcePrefetchPredictor::MaybeReportAccuracyStats(
803 const NavigationID& navigation_id) {
804 NavigationMap::iterator nav_it = inflight_navigations_.find(navigation_id);
dominich 2012/08/02 15:00:50 no need to do this before checking have_prefetch_r
Shishir 2012/08/02 22:06:54 This is a correctness DCHECK, so I would prefer to
805 DCHECK(nav_it != inflight_navigations_.end());
806
807 ResultsMap::iterator results_it = results_map_.find(navigation_id);
808 bool have_prefetch_results = results_it != results_map_.end();
809 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.HavePrefetchResults",
810 have_prefetch_results);
811 if (!have_prefetch_results)
812 return;
813
814 // Annotate the results.
815 const std::vector<URLRequestSummary>& actual = nav_it->second;
816 ResourcePrefetcher::RequestVector* prefetched = results_it->second;
817
818 std::map<GURL, bool> actual_resources;
819 for (std::vector<URLRequestSummary>::const_iterator it = actual.begin();
820 it != actual.end(); ++it) {
821 actual_resources[it->resource_url] = it->was_cached;
822 }
823
824 int prefetch_cancelled = 0, prefetch_failed = 0, prefetch_not_started = 0;
825 // 'a_' -> actual, 'p_' -> predicted.
826 int p_cache_a_cache = 0, p_cache_a_network = 0, p_cache_a_notused = 0,
827 p_network_a_cache = 0, p_network_a_network = 0, p_network_a_notused = 0;
828
829 for (ResourcePrefetcher::RequestVector::iterator it = prefetched->begin();
830 it != prefetched->end(); ++it) {
831 ResourcePrefetcher::Request* req = *it;
832
833 // Set the usage states if the resource was actually used.
834 std::map<GURL, bool>::iterator actual_it = actual_resources.find(
835 req->resource_url);
836 if (actual_it != actual_resources.end()) {
837 if (actual_it->second) {
838 req->usage_status =
839 ResourcePrefetcher::Request::USAGE_STATUS_FROM_CACHE;
840 } else {
841 req->usage_status =
842 ResourcePrefetcher::Request::USAGE_STATUS_FROM_NETWORK;
843 }
844 }
845
846 switch (req->prefetch_status) {
847
848 // TODO(shishir): Add histogram for each cancellation reason.
849 case ResourcePrefetcher::Request::PREFETCH_STATUS_REDIRECTED:
850 case ResourcePrefetcher::Request::PREFETCH_STATUS_AUTH_REQUIRED:
851 case ResourcePrefetcher::Request::PREFETCH_STATUS_CERT_REQUIRED:
852 case ResourcePrefetcher::Request::PREFETCH_STATUS_CERT_ERROR:
853 case ResourcePrefetcher::Request::PREFETCH_STATUS_CANCELLED:
854 ++prefetch_cancelled;
855 break;
856
857 case ResourcePrefetcher::Request::PREFETCH_STATUS_FAILED:
858 ++prefetch_failed;
859 break;
860
861 case ResourcePrefetcher::Request::PREFETCH_STATUS_FROM_CACHE:
862 if (req->usage_status ==
863 ResourcePrefetcher::Request::USAGE_STATUS_FROM_CACHE)
864 ++p_cache_a_cache;
865 else if (req->usage_status ==
866 ResourcePrefetcher::Request::USAGE_STATUS_FROM_NETWORK)
867 ++p_cache_a_network;
868 else
869 ++p_cache_a_notused;
870 break;
871
872 case ResourcePrefetcher::Request::PREFETCH_STATUS_FROM_NETWORK:
873 if (req->usage_status ==
874 ResourcePrefetcher::Request::USAGE_STATUS_FROM_CACHE)
875 ++p_network_a_cache;
876 else if (req->usage_status ==
877 ResourcePrefetcher::Request::USAGE_STATUS_FROM_NETWORK)
878 ++p_network_a_network;
879 else
880 ++p_network_a_notused;
881 break;
882
883 case ResourcePrefetcher::Request::PREFETCH_STATUS_NOT_STARTED:
884 ++prefetch_not_started;
885 break;
886
887 case ResourcePrefetcher::Request::PREFETCH_STATUS_STARTED:
888 DLOG(FATAL) << "Invalid prefetch status";
889 break;
890 }
891 }
892
893 int total_prefetched = p_cache_a_cache + p_cache_a_network + p_cache_a_notused
894 + p_network_a_cache + p_network_a_network + p_network_a_notused;
895
896 UMA_HISTOGRAM_PERCENTAGE(
897 "ResourcePrefetchPredictor.PrefetchCancelled",
898 prefetch_cancelled * 100.0 / total_prefetched);
899 UMA_HISTOGRAM_PERCENTAGE(
900 "ResourcePrefetchPredictor.PrefetchFailed",
901 prefetch_failed * 100.0 / total_prefetched);
902 UMA_HISTOGRAM_PERCENTAGE(
903 "ResourcePrefetchPredictor.PrefetchFromCacheUsedFromCache",
904 p_cache_a_cache * 100.0 / total_prefetched);
905 UMA_HISTOGRAM_PERCENTAGE(
906 "ResourcePrefetchPredictor.PrefetchFromCacheUsedFromNetwork",
907 p_cache_a_network * 100.0 / total_prefetched);
908 UMA_HISTOGRAM_PERCENTAGE(
909 "ResourcePrefetchPredictor.PrefetchFromCacheNotUsed",
910 p_cache_a_notused * 100.0 / total_prefetched);
911 UMA_HISTOGRAM_PERCENTAGE(
912 "ResourcePrefetchPredictor.PrefetchFromNetworkUsedFromCache",
913 p_network_a_cache * 100.0 / total_prefetched);
914 UMA_HISTOGRAM_PERCENTAGE(
915 "ResourcePrefetchPredictor.PrefetchFromNetworkUsedFromNetwork",
916 p_network_a_network * 100.0 / total_prefetched);
917 UMA_HISTOGRAM_PERCENTAGE(
918 "ResourcePrefetchPredictor.PrefetchFromNetworkNotUsed",
919 p_network_a_notused * 100.0 / total_prefetched);
920
921 UMA_HISTOGRAM_PERCENTAGE(
922 "ResourcePrefetchPredictor.PrefetchNotStarted",
923 prefetch_not_started * 100.0 / (prefetch_not_started + total_prefetched));
924 }
925
733 void ResourcePrefetchPredictor::DeleteAllUrls() { 926 void ResourcePrefetchPredictor::DeleteAllUrls() {
734 inflight_navigations_.clear(); 927 inflight_navigations_.clear();
735 url_table_cache_.clear(); 928 url_table_cache_.clear();
736 929
737 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 930 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
738 base::Bind(&ResourcePrefetchPredictorTables::DeleteAllRows, tables_)); 931 base::Bind(&ResourcePrefetchPredictorTables::DeleteAllRows, tables_));
739 } 932 }
740 933
741 void ResourcePrefetchPredictor::DeleteUrls(const history::URLRows& urls) { 934 void ResourcePrefetchPredictor::DeleteUrls(const history::URLRows& urls) {
742 std::vector<GURL> urls_to_delete; 935 std::vector<GURL> urls_to_delete;
(...skipping 14 matching lines...) Expand all
757 tables_, 950 tables_,
758 urls_to_delete)); 951 urls_to_delete));
759 } 952 }
760 953
761 void ResourcePrefetchPredictor::SetTablesForTesting( 954 void ResourcePrefetchPredictor::SetTablesForTesting(
762 scoped_refptr<ResourcePrefetchPredictorTables> tables) { 955 scoped_refptr<ResourcePrefetchPredictorTables> tables) {
763 tables_ = tables; 956 tables_ = tables;
764 } 957 }
765 958
766 } // namespace predictors 959 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698