Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |