| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/predictors/resource_prefetch_predictor.h" | 5 #include "chrome/browser/predictors/resource_prefetch_predictor.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 "application/font-woff2", | 47 "application/font-woff2", |
| 48 "font/x-woff", | 48 "font/x-woff", |
| 49 "application/x-font-ttf", | 49 "application/x-font-ttf", |
| 50 "font/woff", | 50 "font/woff", |
| 51 "font/ttf", | 51 "font/ttf", |
| 52 "application/x-font-otf", | 52 "application/x-font-otf", |
| 53 "x-font/woff", | 53 "x-font/woff", |
| 54 "application/font-sfnt", | 54 "application/font-sfnt", |
| 55 "application/font-ttf"}; | 55 "application/font-ttf"}; |
| 56 | 56 |
| 57 // For reporting whether a subresource is handled or not, and for what reasons. | |
| 58 enum ResourceStatus { | |
| 59 RESOURCE_STATUS_HANDLED = 0, | |
| 60 RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_PAGE = 1, | |
| 61 RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_RESOURCE = 2, | |
| 62 RESOURCE_STATUS_UNSUPPORTED_RESOURCE_TYPE = 4, | |
| 63 RESOURCE_STATUS_NOT_GET = 8, | |
| 64 RESOURCE_STATUS_URL_TOO_LONG = 16, | |
| 65 RESOURCE_STATUS_NO_STORE = 32, | |
| 66 RESOURCE_STATUS_HEADERS_MISSING = 64, | |
| 67 RESOURCE_STATUS_MAX = 128, | |
| 68 }; | |
| 69 | |
| 70 // For reporting various interesting events that occur during the loading of a | |
| 71 // single main frame. | |
| 72 enum NavigationEvent { | |
| 73 NAVIGATION_EVENT_REQUEST_STARTED = 0, | |
| 74 NAVIGATION_EVENT_REQUEST_REDIRECTED = 1, | |
| 75 NAVIGATION_EVENT_REQUEST_REDIRECTED_EMPTY_URL = 2, | |
| 76 NAVIGATION_EVENT_REQUEST_EXPIRED = 3, | |
| 77 NAVIGATION_EVENT_RESPONSE_STARTED = 4, | |
| 78 NAVIGATION_EVENT_ONLOAD = 5, | |
| 79 NAVIGATION_EVENT_ONLOAD_EMPTY_URL = 6, | |
| 80 NAVIGATION_EVENT_ONLOAD_UNTRACKED_URL = 7, | |
| 81 NAVIGATION_EVENT_ONLOAD_TRACKED_URL = 8, | |
| 82 NAVIGATION_EVENT_SHOULD_TRACK_URL = 9, | |
| 83 NAVIGATION_EVENT_SHOULD_NOT_TRACK_URL = 10, | |
| 84 NAVIGATION_EVENT_URL_TABLE_FULL = 11, | |
| 85 NAVIGATION_EVENT_HAVE_PREDICTIONS_FOR_URL = 12, | |
| 86 NAVIGATION_EVENT_NO_PREDICTIONS_FOR_URL = 13, | |
| 87 NAVIGATION_EVENT_MAIN_FRAME_URL_TOO_LONG = 14, | |
| 88 NAVIGATION_EVENT_HOST_TOO_LONG = 15, | |
| 89 NAVIGATION_EVENT_COUNT = 16, | |
| 90 }; | |
| 91 | |
| 92 // For reporting events of interest that are not tied to any navigation. | 57 // For reporting events of interest that are not tied to any navigation. |
| 93 enum ReportingEvent { | 58 enum ReportingEvent { |
| 94 REPORTING_EVENT_ALL_HISTORY_CLEARED = 0, | 59 REPORTING_EVENT_ALL_HISTORY_CLEARED = 0, |
| 95 REPORTING_EVENT_PARTIAL_HISTORY_CLEARED = 1, | 60 REPORTING_EVENT_PARTIAL_HISTORY_CLEARED = 1, |
| 96 REPORTING_EVENT_COUNT = 2 | 61 REPORTING_EVENT_COUNT = 2 |
| 97 }; | 62 }; |
| 98 | 63 |
| 99 void RecordNavigationEvent(NavigationEvent event) { | |
| 100 UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.NavigationEvent", | |
| 101 event, | |
| 102 NAVIGATION_EVENT_COUNT); | |
| 103 } | |
| 104 | |
| 105 // These are additional connection types for | |
| 106 // net::NetworkChangeNotifier::ConnectionType. They have negative values in case | |
| 107 // the original network connection types expand. | |
| 108 enum AdditionalConnectionType { | |
| 109 CONNECTION_ALL = -2, | |
| 110 CONNECTION_CELLULAR = -1 | |
| 111 }; | |
| 112 | |
| 113 std::string GetNetTypeStr() { | |
| 114 switch (net::NetworkChangeNotifier::GetConnectionType()) { | |
| 115 case net::NetworkChangeNotifier::CONNECTION_ETHERNET: | |
| 116 return "Ethernet"; | |
| 117 case net::NetworkChangeNotifier::CONNECTION_WIFI: | |
| 118 return "WiFi"; | |
| 119 case net::NetworkChangeNotifier::CONNECTION_2G: | |
| 120 return "2G"; | |
| 121 case net::NetworkChangeNotifier::CONNECTION_3G: | |
| 122 return "3G"; | |
| 123 case net::NetworkChangeNotifier::CONNECTION_4G: | |
| 124 return "4G"; | |
| 125 case net::NetworkChangeNotifier::CONNECTION_NONE: | |
| 126 return "None"; | |
| 127 case net::NetworkChangeNotifier::CONNECTION_BLUETOOTH: | |
| 128 return "Bluetooth"; | |
| 129 case net::NetworkChangeNotifier::CONNECTION_UNKNOWN: | |
| 130 default: | |
| 131 break; | |
| 132 } | |
| 133 return "Unknown"; | |
| 134 } | |
| 135 | |
| 136 void ReportPrefetchedNetworkType(int type) { | |
| 137 UMA_HISTOGRAM_SPARSE_SLOWLY( | |
| 138 "ResourcePrefetchPredictor.NetworkType.Prefetched", | |
| 139 type); | |
| 140 } | |
| 141 | |
| 142 void ReportNotPrefetchedNetworkType(int type) { | |
| 143 UMA_HISTOGRAM_SPARSE_SLOWLY( | |
| 144 "ResourcePrefetchPredictor.NetworkType.NotPrefetched", | |
| 145 type); | |
| 146 } | |
| 147 | |
| 148 } // namespace | 64 } // namespace |
| 149 | 65 |
| 150 namespace predictors { | 66 namespace predictors { |
| 151 | 67 |
| 152 //////////////////////////////////////////////////////////////////////////////// | 68 //////////////////////////////////////////////////////////////////////////////// |
| 153 // History lookup task. | 69 // History lookup task. |
| 154 | 70 |
| 155 // Used to fetch the visit count for a URL from the History database. | 71 // Used to fetch the visit count for a URL from the History database. |
| 156 class GetUrlVisitCountTask : public history::HistoryDBTask { | 72 class GetUrlVisitCountTask : public history::HistoryDBTask { |
| 157 public: | 73 public: |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 | 164 |
| 249 // static | 165 // static |
| 250 bool ResourcePrefetchPredictor::IsHandledMainPage(net::URLRequest* request) { | 166 bool ResourcePrefetchPredictor::IsHandledMainPage(net::URLRequest* request) { |
| 251 return request->url().SchemeIsHTTPOrHTTPS(); | 167 return request->url().SchemeIsHTTPOrHTTPS(); |
| 252 } | 168 } |
| 253 | 169 |
| 254 // static | 170 // static |
| 255 bool ResourcePrefetchPredictor::IsHandledSubresource( | 171 bool ResourcePrefetchPredictor::IsHandledSubresource( |
| 256 net::URLRequest* response, | 172 net::URLRequest* response, |
| 257 content::ResourceType resource_type) { | 173 content::ResourceType resource_type) { |
| 258 int resource_status = 0; | 174 if (!response->first_party_for_cookies().SchemeIsHTTPOrHTTPS() || |
| 259 | 175 !response->url().SchemeIsHTTPOrHTTPS()) |
| 260 if (!response->first_party_for_cookies().SchemeIsHTTPOrHTTPS()) | 176 return false; |
| 261 resource_status |= RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_PAGE; | |
| 262 | |
| 263 if (!response->url().SchemeIsHTTPOrHTTPS()) | |
| 264 resource_status |= RESOURCE_STATUS_NOT_HTTP_OR_HTTPS_RESOURCE; | |
| 265 | 177 |
| 266 std::string mime_type; | 178 std::string mime_type; |
| 267 response->GetMimeType(&mime_type); | 179 response->GetMimeType(&mime_type); |
| 268 if (!IsHandledResourceType(resource_type, mime_type)) | 180 if (!IsHandledResourceType(resource_type, mime_type)) |
| 269 resource_status |= RESOURCE_STATUS_UNSUPPORTED_RESOURCE_TYPE; | 181 return false; |
| 270 | 182 |
| 271 if (response->method() != "GET") | 183 if (response->method() != "GET") |
| 272 resource_status |= RESOURCE_STATUS_NOT_GET; | 184 return false; |
| 273 | 185 |
| 274 if (response->original_url().spec().length() > | 186 if (response->original_url().spec().length() > |
| 275 ResourcePrefetchPredictorTables::kMaxStringLength) { | 187 ResourcePrefetchPredictorTables::kMaxStringLength) { |
| 276 resource_status |= RESOURCE_STATUS_URL_TOO_LONG; | 188 return false; |
| 277 } | 189 } |
| 278 | 190 |
| 279 if (!response->response_info().headers.get()) | 191 if (!response->response_info().headers.get() || IsNoStore(response)) |
| 280 resource_status |= RESOURCE_STATUS_HEADERS_MISSING; | 192 return false; |
| 281 | 193 |
| 282 if (IsNoStore(response)) | 194 return true; |
| 283 resource_status |= RESOURCE_STATUS_NO_STORE; | |
| 284 | |
| 285 return resource_status == 0; | |
| 286 } | 195 } |
| 287 | 196 |
| 288 // static | 197 // static |
| 289 bool ResourcePrefetchPredictor::IsHandledResourceType( | 198 bool ResourcePrefetchPredictor::IsHandledResourceType( |
| 290 content::ResourceType resource_type, | 199 content::ResourceType resource_type, |
| 291 const std::string& mime_type) { | 200 const std::string& mime_type) { |
| 292 content::ResourceType actual_resource_type = | 201 content::ResourceType actual_resource_type = |
| 293 GetResourceType(resource_type, mime_type); | 202 GetResourceType(resource_type, mime_type); |
| 294 return actual_resource_type == content::RESOURCE_TYPE_STYLESHEET || | 203 return actual_resource_type == content::RESOURCE_TYPE_STYLESHEET || |
| 295 actual_resource_type == content::RESOURCE_TYPE_SCRIPT || | 204 actual_resource_type == content::RESOURCE_TYPE_SCRIPT || |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 } | 386 } |
| 478 | 387 |
| 479 void ResourcePrefetchPredictor::RecordMainFrameLoadComplete( | 388 void ResourcePrefetchPredictor::RecordMainFrameLoadComplete( |
| 480 const NavigationID& navigation_id) { | 389 const NavigationID& navigation_id) { |
| 481 switch (initialization_state_) { | 390 switch (initialization_state_) { |
| 482 case NOT_INITIALIZED: | 391 case NOT_INITIALIZED: |
| 483 StartInitialization(); | 392 StartInitialization(); |
| 484 break; | 393 break; |
| 485 case INITIALIZING: | 394 case INITIALIZING: |
| 486 break; | 395 break; |
| 487 case INITIALIZED: { | 396 case INITIALIZED: |
| 488 RecordNavigationEvent(NAVIGATION_EVENT_ONLOAD); | |
| 489 // WebContents can return an empty URL if the navigation entry | 397 // WebContents can return an empty URL if the navigation entry |
| 490 // corresponding to the navigation has not been created yet. | 398 // corresponding to the navigation has not been created yet. |
| 491 if (navigation_id.main_frame_url.is_empty()) | 399 if (!navigation_id.main_frame_url.is_empty()) |
| 492 RecordNavigationEvent(NAVIGATION_EVENT_ONLOAD_EMPTY_URL); | |
| 493 else | |
| 494 OnNavigationComplete(navigation_id); | 400 OnNavigationComplete(navigation_id); |
| 495 break; | 401 break; |
| 496 } | |
| 497 default: | 402 default: |
| 498 NOTREACHED() << "Unexpected initialization_state_: " | 403 NOTREACHED() << "Unexpected initialization_state_: " |
| 499 << initialization_state_; | 404 << initialization_state_; |
| 500 } | 405 } |
| 501 } | 406 } |
| 502 | 407 |
| 503 void ResourcePrefetchPredictor::FinishedPrefetchForNavigation( | 408 void ResourcePrefetchPredictor::FinishedPrefetchForNavigation( |
| 504 const NavigationID& navigation_id, | 409 const NavigationID& navigation_id, |
| 505 PrefetchKeyType key_type, | 410 PrefetchKeyType key_type, |
| 506 ResourcePrefetcher::RequestVector* requests) { | 411 ResourcePrefetcher::RequestVector* requests) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 519 prefetch_manager_ = NULL; | 424 prefetch_manager_ = NULL; |
| 520 } | 425 } |
| 521 history_service_observer_.RemoveAll(); | 426 history_service_observer_.RemoveAll(); |
| 522 } | 427 } |
| 523 | 428 |
| 524 void ResourcePrefetchPredictor::OnMainFrameRequest( | 429 void ResourcePrefetchPredictor::OnMainFrameRequest( |
| 525 const URLRequestSummary& request) { | 430 const URLRequestSummary& request) { |
| 526 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 431 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 527 DCHECK_EQ(INITIALIZED, initialization_state_); | 432 DCHECK_EQ(INITIALIZED, initialization_state_); |
| 528 | 433 |
| 529 RecordNavigationEvent(NAVIGATION_EVENT_REQUEST_STARTED); | |
| 530 | |
| 531 StartPrefetching(request.navigation_id); | 434 StartPrefetching(request.navigation_id); |
| 532 | 435 |
| 533 // Cleanup older navigations. | 436 // Cleanup older navigations. |
| 534 CleanupAbandonedNavigations(request.navigation_id); | 437 CleanupAbandonedNavigations(request.navigation_id); |
| 535 | 438 |
| 536 // New empty navigation entry. | 439 // New empty navigation entry. |
| 537 inflight_navigations_.insert(std::make_pair( | 440 inflight_navigations_.insert(std::make_pair( |
| 538 request.navigation_id, | 441 request.navigation_id, |
| 539 make_linked_ptr(new std::vector<URLRequestSummary>()))); | 442 make_linked_ptr(new std::vector<URLRequestSummary>()))); |
| 540 } | 443 } |
| 541 | 444 |
| 542 void ResourcePrefetchPredictor::OnMainFrameResponse( | 445 void ResourcePrefetchPredictor::OnMainFrameResponse( |
| 543 const URLRequestSummary& response) { | 446 const URLRequestSummary& response) { |
| 544 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 447 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 545 if (initialization_state_ != INITIALIZED) | 448 if (initialization_state_ != INITIALIZED) |
| 546 return; | 449 return; |
| 547 | 450 |
| 548 RecordNavigationEvent(NAVIGATION_EVENT_RESPONSE_STARTED); | |
| 549 | |
| 550 StopPrefetching(response.navigation_id); | 451 StopPrefetching(response.navigation_id); |
| 551 } | 452 } |
| 552 | 453 |
| 553 void ResourcePrefetchPredictor::OnMainFrameRedirect( | 454 void ResourcePrefetchPredictor::OnMainFrameRedirect( |
| 554 const URLRequestSummary& response) { | 455 const URLRequestSummary& response) { |
| 555 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 456 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 556 | 457 |
| 557 RecordNavigationEvent(NAVIGATION_EVENT_REQUEST_REDIRECTED); | |
| 558 | |
| 559 // TODO(shishir): There are significant gains to be had here if we can use the | 458 // TODO(shishir): There are significant gains to be had here if we can use the |
| 560 // start URL in a redirect chain as the key to start prefetching. We can save | 459 // start URL in a redirect chain as the key to start prefetching. We can save |
| 561 // of redirect times considerably assuming that the redirect chains do not | 460 // of redirect times considerably assuming that the redirect chains do not |
| 562 // change. | 461 // change. |
| 563 | 462 |
| 564 // Stop any inflight prefetching. Remove the older navigation. | 463 // Stop any inflight prefetching. Remove the older navigation. |
| 565 StopPrefetching(response.navigation_id); | 464 StopPrefetching(response.navigation_id); |
| 566 inflight_navigations_.erase(response.navigation_id); | 465 inflight_navigations_.erase(response.navigation_id); |
| 567 | 466 |
| 568 // A redirect will not lead to another OnMainFrameRequest call, so record the | 467 // A redirect will not lead to another OnMainFrameRequest call, so record the |
| 569 // redirect url as a new navigation. | 468 // redirect url as a new navigation. |
| 570 | 469 |
| 571 // The redirect url may be empty if the url was invalid. | 470 // The redirect url may be empty if the URL was invalid. |
| 572 if (response.redirect_url.is_empty()) { | 471 if (response.redirect_url.is_empty()) |
| 573 RecordNavigationEvent(NAVIGATION_EVENT_REQUEST_REDIRECTED_EMPTY_URL); | |
| 574 return; | 472 return; |
| 575 } | |
| 576 | 473 |
| 577 NavigationID navigation_id(response.navigation_id); | 474 NavigationID navigation_id(response.navigation_id); |
| 578 navigation_id.main_frame_url = response.redirect_url; | 475 navigation_id.main_frame_url = response.redirect_url; |
| 579 inflight_navigations_.insert(std::make_pair( | 476 inflight_navigations_.insert(std::make_pair( |
| 580 navigation_id, | 477 navigation_id, |
| 581 make_linked_ptr(new std::vector<URLRequestSummary>()))); | 478 make_linked_ptr(new std::vector<URLRequestSummary>()))); |
| 582 } | 479 } |
| 583 | 480 |
| 584 void ResourcePrefetchPredictor::OnSubresourceResponse( | 481 void ResourcePrefetchPredictor::OnSubresourceResponse( |
| 585 const URLRequestSummary& response) { | 482 const URLRequestSummary& response) { |
| 586 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 483 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 587 | 484 |
| 588 NavigationMap::const_iterator nav_it = | 485 NavigationMap::const_iterator nav_it = |
| 589 inflight_navigations_.find(response.navigation_id); | 486 inflight_navigations_.find(response.navigation_id); |
| 590 if (nav_it == inflight_navigations_.end()) { | 487 if (nav_it == inflight_navigations_.end()) { |
| 591 return; | 488 return; |
| 592 } | 489 } |
| 593 | 490 |
| 594 nav_it->second->push_back(response); | 491 nav_it->second->push_back(response); |
| 595 } | 492 } |
| 596 | 493 |
| 597 base::TimeDelta ResourcePrefetchPredictor::OnNavigationComplete( | 494 void ResourcePrefetchPredictor::OnNavigationComplete( |
| 598 const NavigationID& nav_id_without_timing_info) { | 495 const NavigationID& nav_id_without_timing_info) { |
| 599 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 496 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 600 | 497 |
| 601 NavigationMap::iterator nav_it = | 498 NavigationMap::iterator nav_it = |
| 602 inflight_navigations_.find(nav_id_without_timing_info); | 499 inflight_navigations_.find(nav_id_without_timing_info); |
| 603 if (nav_it == inflight_navigations_.end()) { | 500 if (nav_it == inflight_navigations_.end()) |
| 604 RecordNavigationEvent(NAVIGATION_EVENT_ONLOAD_UNTRACKED_URL); | 501 return; |
| 605 return base::TimeDelta(); | |
| 606 } | |
| 607 RecordNavigationEvent(NAVIGATION_EVENT_ONLOAD_TRACKED_URL); | |
| 608 | 502 |
| 609 // Get and use the navigation ID stored in |inflight_navigations_| because it | |
| 610 // has the timing infomation. | |
| 611 const NavigationID navigation_id(nav_it->first); | 503 const NavigationID navigation_id(nav_it->first); |
| 612 | 504 |
| 613 // Report any stats. | |
| 614 base::TimeDelta plt = base::TimeTicks::Now() - navigation_id.creation_time; | |
| 615 ReportPageLoadTimeStats(plt); | |
| 616 if (prefetch_manager_.get()) { | |
| 617 ResultsMap::const_iterator results_it = results_map_.find(navigation_id); | |
| 618 bool have_prefetch_results = results_it != results_map_.end(); | |
| 619 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.HavePrefetchResults", | |
| 620 have_prefetch_results); | |
| 621 if (have_prefetch_results) { | |
| 622 ReportAccuracyStats(results_it->second->key_type, | |
| 623 *(nav_it->second), | |
| 624 results_it->second->requests.get()); | |
| 625 ReportPageLoadTimePrefetchStats( | |
| 626 plt, | |
| 627 true, | |
| 628 base::Bind(&ReportPrefetchedNetworkType), | |
| 629 results_it->second->key_type); | |
| 630 } else { | |
| 631 ReportPageLoadTimePrefetchStats( | |
| 632 plt, | |
| 633 false, | |
| 634 base::Bind(&ReportNotPrefetchedNetworkType), | |
| 635 PREFETCH_KEY_TYPE_URL); | |
| 636 } | |
| 637 } else { | |
| 638 std::unique_ptr<ResourcePrefetcher::RequestVector> requests( | |
| 639 new ResourcePrefetcher::RequestVector); | |
| 640 PrefetchKeyType key_type; | |
| 641 if (GetPrefetchData(navigation_id, requests.get(), &key_type)) { | |
| 642 RecordNavigationEvent(NAVIGATION_EVENT_HAVE_PREDICTIONS_FOR_URL); | |
| 643 ReportPredictedAccuracyStats(key_type, | |
| 644 *(nav_it->second), | |
| 645 *requests); | |
| 646 } else { | |
| 647 RecordNavigationEvent(NAVIGATION_EVENT_NO_PREDICTIONS_FOR_URL); | |
| 648 } | |
| 649 } | |
| 650 | |
| 651 // Remove the navigation from the inflight navigations. | 505 // Remove the navigation from the inflight navigations. |
| 652 std::vector<URLRequestSummary>* requests = (nav_it->second).release(); | 506 std::vector<URLRequestSummary>* requests = (nav_it->second).release(); |
| 653 inflight_navigations_.erase(nav_it); | 507 inflight_navigations_.erase(nav_it); |
| 654 | 508 |
| 655 // Kick off history lookup to determine if we should record the URL. | 509 // Kick off history lookup to determine if we should record the URL. |
| 656 history::HistoryService* history_service = | 510 history::HistoryService* history_service = |
| 657 HistoryServiceFactory::GetForProfile(profile_, | 511 HistoryServiceFactory::GetForProfile(profile_, |
| 658 ServiceAccessType::EXPLICIT_ACCESS); | 512 ServiceAccessType::EXPLICIT_ACCESS); |
| 659 DCHECK(history_service); | 513 DCHECK(history_service); |
| 660 history_service->ScheduleDBTask( | 514 history_service->ScheduleDBTask( |
| 661 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( | 515 std::unique_ptr<history::HistoryDBTask>(new GetUrlVisitCountTask( |
| 662 navigation_id, requests, | 516 navigation_id, requests, |
| 663 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, | 517 base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup, |
| 664 AsWeakPtr()))), | 518 AsWeakPtr()))), |
| 665 &history_lookup_consumer_); | 519 &history_lookup_consumer_); |
| 666 | |
| 667 return plt; | |
| 668 } | 520 } |
| 669 | 521 |
| 670 bool ResourcePrefetchPredictor::GetPrefetchData( | 522 bool ResourcePrefetchPredictor::GetPrefetchData( |
| 671 const NavigationID& navigation_id, | 523 const NavigationID& navigation_id, |
| 672 ResourcePrefetcher::RequestVector* prefetch_requests, | 524 ResourcePrefetcher::RequestVector* prefetch_requests, |
| 673 PrefetchKeyType* key_type) { | 525 PrefetchKeyType* key_type) { |
| 674 DCHECK(prefetch_requests); | 526 DCHECK(prefetch_requests); |
| 675 DCHECK(key_type); | 527 DCHECK(key_type); |
| 676 | 528 |
| 677 *key_type = PREFETCH_KEY_TYPE_URL; | 529 *key_type = PREFETCH_KEY_TYPE_URL; |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 812 const NavigationID& navigation_id) { | 664 const NavigationID& navigation_id) { |
| 813 static const base::TimeDelta max_navigation_age = | 665 static const base::TimeDelta max_navigation_age = |
| 814 base::TimeDelta::FromSeconds(config_.max_navigation_lifetime_seconds); | 666 base::TimeDelta::FromSeconds(config_.max_navigation_lifetime_seconds); |
| 815 | 667 |
| 816 base::TimeTicks time_now = base::TimeTicks::Now(); | 668 base::TimeTicks time_now = base::TimeTicks::Now(); |
| 817 for (NavigationMap::iterator it = inflight_navigations_.begin(); | 669 for (NavigationMap::iterator it = inflight_navigations_.begin(); |
| 818 it != inflight_navigations_.end();) { | 670 it != inflight_navigations_.end();) { |
| 819 if (it->first.IsSameRenderer(navigation_id) || | 671 if (it->first.IsSameRenderer(navigation_id) || |
| 820 (time_now - it->first.creation_time > max_navigation_age)) { | 672 (time_now - it->first.creation_time > max_navigation_age)) { |
| 821 inflight_navigations_.erase(it++); | 673 inflight_navigations_.erase(it++); |
| 822 RecordNavigationEvent(NAVIGATION_EVENT_REQUEST_EXPIRED); | |
| 823 } else { | 674 } else { |
| 824 ++it; | 675 ++it; |
| 825 } | 676 } |
| 826 } | 677 } |
| 827 for (ResultsMap::const_iterator it = results_map_.begin(); | 678 for (ResultsMap::const_iterator it = results_map_.begin(); |
| 828 it != results_map_.end();) { | 679 it != results_map_.end();) { |
| 829 if (it->first.IsSameRenderer(navigation_id) || | 680 if (it->first.IsSameRenderer(navigation_id) || |
| 830 (time_now - it->first.creation_time > max_navigation_age)) { | 681 (time_now - it->first.creation_time > max_navigation_age)) { |
| 831 results_map_.erase(it++); | 682 results_map_.erase(it++); |
| 832 } else { | 683 } else { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 visit_count); | 757 visit_count); |
| 907 | 758 |
| 908 // URL level data - merge only if we are already saving the data, or we it | 759 // URL level data - merge only if we are already saving the data, or we it |
| 909 // meets the cutoff requirement. | 760 // meets the cutoff requirement. |
| 910 const std::string url_spec = navigation_id.main_frame_url.spec(); | 761 const std::string url_spec = navigation_id.main_frame_url.spec(); |
| 911 bool already_tracking = url_table_cache_->find(url_spec) != | 762 bool already_tracking = url_table_cache_->find(url_spec) != |
| 912 url_table_cache_->end(); | 763 url_table_cache_->end(); |
| 913 bool should_track_url = already_tracking || | 764 bool should_track_url = already_tracking || |
| 914 (visit_count >= config_.min_url_visit_count); | 765 (visit_count >= config_.min_url_visit_count); |
| 915 | 766 |
| 916 if (should_track_url) { | 767 if (should_track_url && config_.IsURLLearningEnabled()) { |
| 917 RecordNavigationEvent(NAVIGATION_EVENT_SHOULD_TRACK_URL); | 768 LearnNavigation(url_spec, PREFETCH_KEY_TYPE_URL, requests, |
| 918 | 769 config_.max_urls_to_track, url_table_cache_.get()); |
| 919 if (config_.IsURLLearningEnabled()) { | |
| 920 LearnNavigation(url_spec, PREFETCH_KEY_TYPE_URL, requests, | |
| 921 config_.max_urls_to_track, url_table_cache_.get()); | |
| 922 } | |
| 923 } else { | |
| 924 RecordNavigationEvent(NAVIGATION_EVENT_SHOULD_NOT_TRACK_URL); | |
| 925 } | 770 } |
| 926 | 771 |
| 927 // Host level data - no cutoff, always learn the navigation if enabled. | 772 // Host level data - no cutoff, always learn the navigation if enabled. |
| 928 if (config_.IsHostLearningEnabled()) { | 773 if (config_.IsHostLearningEnabled()) { |
| 929 LearnNavigation(navigation_id.main_frame_url.host(), | 774 LearnNavigation(navigation_id.main_frame_url.host(), |
| 930 PREFETCH_KEY_TYPE_HOST, | 775 PREFETCH_KEY_TYPE_HOST, |
| 931 requests, | 776 requests, |
| 932 config_.max_hosts_to_track, | 777 config_.max_hosts_to_track, |
| 933 host_table_cache_.get()); | 778 host_table_cache_.get()); |
| 934 } | 779 } |
| 935 | 780 |
| 936 // Remove the navigation from the results map. | 781 // Remove the navigation from the results map. |
| 937 results_map_.erase(navigation_id); | 782 results_map_.erase(navigation_id); |
| 938 } | 783 } |
| 939 | 784 |
| 940 void ResourcePrefetchPredictor::LearnNavigation( | 785 void ResourcePrefetchPredictor::LearnNavigation( |
| 941 const std::string& key, | 786 const std::string& key, |
| 942 PrefetchKeyType key_type, | 787 PrefetchKeyType key_type, |
| 943 const std::vector<URLRequestSummary>& new_resources, | 788 const std::vector<URLRequestSummary>& new_resources, |
| 944 size_t max_data_map_size, | 789 size_t max_data_map_size, |
| 945 PrefetchDataMap* data_map) { | 790 PrefetchDataMap* data_map) { |
| 946 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 791 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 947 | 792 |
| 948 // If the primary key is too long reject it. | 793 // If the primary key is too long reject it. |
| 949 if (key.length() > ResourcePrefetchPredictorTables::kMaxStringLength) { | 794 if (key.length() > ResourcePrefetchPredictorTables::kMaxStringLength) |
| 950 if (key_type == PREFETCH_KEY_TYPE_HOST) | |
| 951 RecordNavigationEvent(NAVIGATION_EVENT_HOST_TOO_LONG); | |
| 952 else | |
| 953 RecordNavigationEvent(NAVIGATION_EVENT_MAIN_FRAME_URL_TOO_LONG); | |
| 954 return; | 795 return; |
| 955 } | |
| 956 | 796 |
| 957 PrefetchDataMap::iterator cache_entry = data_map->find(key); | 797 PrefetchDataMap::iterator cache_entry = data_map->find(key); |
| 958 if (cache_entry == data_map->end()) { | 798 if (cache_entry == data_map->end()) { |
| 959 if (data_map->size() >= max_data_map_size) { | 799 if (data_map->size() >= max_data_map_size) { |
| 960 // The table is full, delete an entry. | 800 // The table is full, delete an entry. |
| 961 RemoveOldestEntryInPrefetchDataMap(key_type, data_map); | 801 RemoveOldestEntryInPrefetchDataMap(key_type, data_map); |
| 962 } | 802 } |
| 963 | 803 |
| 964 cache_entry = data_map->insert(std::make_pair( | 804 cache_entry = data_map->insert(std::make_pair( |
| 965 key, PrefetchData(key_type, key))).first; | 805 key, PrefetchData(key_type, key))).first; |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1082 const PrefetchData& url_data = is_host ? empty_data : cache_entry->second; | 922 const PrefetchData& url_data = is_host ? empty_data : cache_entry->second; |
| 1083 BrowserThread::PostTask( | 923 BrowserThread::PostTask( |
| 1084 BrowserThread::DB, FROM_HERE, | 924 BrowserThread::DB, FROM_HERE, |
| 1085 base::Bind(&ResourcePrefetchPredictorTables::UpdateData, | 925 base::Bind(&ResourcePrefetchPredictorTables::UpdateData, |
| 1086 tables_, | 926 tables_, |
| 1087 url_data, | 927 url_data, |
| 1088 host_data)); | 928 host_data)); |
| 1089 } | 929 } |
| 1090 } | 930 } |
| 1091 | 931 |
| 1092 //////////////////////////////////////////////////////////////////////////////// | |
| 1093 // Page load time and accuracy measurement. | |
| 1094 | |
| 1095 // This is essentially UMA_HISTOGRAM_MEDIUM_TIMES, but it avoids using the | |
| 1096 // STATIC_HISTOGRAM_POINTER_BLOCK in UMA_HISTOGRAM definitions. | |
| 1097 #define RPP_HISTOGRAM_MEDIUM_TIMES(name, page_load_time) \ | |
| 1098 do { \ | |
| 1099 base::HistogramBase* histogram = base::Histogram::FactoryTimeGet( \ | |
| 1100 name, \ | |
| 1101 base::TimeDelta::FromMilliseconds(10), \ | |
| 1102 base::TimeDelta::FromMinutes(3), \ | |
| 1103 50, \ | |
| 1104 base::HistogramBase::kUmaTargetedHistogramFlag); \ | |
| 1105 histogram->AddTime(page_load_time); \ | |
| 1106 } while (0) | |
| 1107 | |
| 1108 void ResourcePrefetchPredictor::ReportPageLoadTimeStats( | |
| 1109 base::TimeDelta plt) const { | |
| 1110 net::NetworkChangeNotifier::ConnectionType connection_type = | |
| 1111 net::NetworkChangeNotifier::GetConnectionType(); | |
| 1112 | |
| 1113 RPP_HISTOGRAM_MEDIUM_TIMES("ResourcePrefetchPredictor.PLT", plt); | |
| 1114 RPP_HISTOGRAM_MEDIUM_TIMES( | |
| 1115 "ResourcePrefetchPredictor.PLT_" + GetNetTypeStr(), plt); | |
| 1116 if (net::NetworkChangeNotifier::IsConnectionCellular(connection_type)) | |
| 1117 RPP_HISTOGRAM_MEDIUM_TIMES("ResourcePrefetchPredictor.PLT_Cellular", plt); | |
| 1118 } | |
| 1119 | |
| 1120 void ResourcePrefetchPredictor::ReportPageLoadTimePrefetchStats( | |
| 1121 base::TimeDelta plt, | |
| 1122 bool prefetched, | |
| 1123 base::Callback<void(int)> report_network_type_callback, | |
| 1124 PrefetchKeyType key_type) const { | |
| 1125 net::NetworkChangeNotifier::ConnectionType connection_type = | |
| 1126 net::NetworkChangeNotifier::GetConnectionType(); | |
| 1127 bool on_cellular = | |
| 1128 net::NetworkChangeNotifier::IsConnectionCellular(connection_type); | |
| 1129 | |
| 1130 report_network_type_callback.Run(CONNECTION_ALL); | |
| 1131 report_network_type_callback.Run(connection_type); | |
| 1132 if (on_cellular) | |
| 1133 report_network_type_callback.Run(CONNECTION_CELLULAR); | |
| 1134 | |
| 1135 std::string prefetched_str; | |
| 1136 if (prefetched) | |
| 1137 prefetched_str = "Prefetched"; | |
| 1138 else | |
| 1139 prefetched_str = "NotPrefetched"; | |
| 1140 | |
| 1141 RPP_HISTOGRAM_MEDIUM_TIMES( | |
| 1142 "ResourcePrefetchPredictor.PLT." + prefetched_str, plt); | |
| 1143 RPP_HISTOGRAM_MEDIUM_TIMES( | |
| 1144 "ResourcePrefetchPredictor.PLT." + prefetched_str + "_" + GetNetTypeStr(), | |
| 1145 plt); | |
| 1146 if (on_cellular) { | |
| 1147 RPP_HISTOGRAM_MEDIUM_TIMES( | |
| 1148 "ResourcePrefetchPredictor.PLT." + prefetched_str + "_Cellular", plt); | |
| 1149 } | |
| 1150 | |
| 1151 if (!prefetched) | |
| 1152 return; | |
| 1153 | |
| 1154 std::string type = | |
| 1155 key_type == PREFETCH_KEY_TYPE_HOST ? "Host" : "Url"; | |
| 1156 RPP_HISTOGRAM_MEDIUM_TIMES( | |
| 1157 "ResourcePrefetchPredictor.PLT.Prefetched." + type, plt); | |
| 1158 RPP_HISTOGRAM_MEDIUM_TIMES( | |
| 1159 "ResourcePrefetchPredictor.PLT.Prefetched." + type + "_" | |
| 1160 + GetNetTypeStr(), | |
| 1161 plt); | |
| 1162 if (on_cellular) { | |
| 1163 RPP_HISTOGRAM_MEDIUM_TIMES( | |
| 1164 "ResourcePrefetchPredictor.PLT.Prefetched." + type + "_Cellular", | |
| 1165 plt); | |
| 1166 } | |
| 1167 } | |
| 1168 | |
| 1169 void ResourcePrefetchPredictor::ReportAccuracyStats( | |
| 1170 PrefetchKeyType key_type, | |
| 1171 const std::vector<URLRequestSummary>& actual, | |
| 1172 ResourcePrefetcher::RequestVector* prefetched) const { | |
| 1173 // Annotate the results. | |
| 1174 std::map<GURL, bool> actual_resources; | |
| 1175 for (std::vector<URLRequestSummary>::const_iterator it = actual.begin(); | |
| 1176 it != actual.end(); ++it) { | |
| 1177 actual_resources[it->resource_url] = it->was_cached; | |
| 1178 } | |
| 1179 | |
| 1180 int prefetch_cancelled = 0, prefetch_failed = 0, prefetch_not_started = 0; | |
| 1181 // 'a_' -> actual, 'p_' -> predicted. | |
| 1182 int p_cache_a_cache = 0, p_cache_a_network = 0, p_cache_a_notused = 0, | |
| 1183 p_network_a_cache = 0, p_network_a_network = 0, p_network_a_notused = 0; | |
| 1184 | |
| 1185 for (ResourcePrefetcher::RequestVector::iterator it = prefetched->begin(); | |
| 1186 it != prefetched->end(); ++it) { | |
| 1187 ResourcePrefetcher::Request* req = *it; | |
| 1188 | |
| 1189 // Set the usage states if the resource was actually used. | |
| 1190 std::map<GURL, bool>::const_iterator actual_it = | |
| 1191 actual_resources.find(req->resource_url); | |
| 1192 if (actual_it != actual_resources.end()) { | |
| 1193 if (actual_it->second) { | |
| 1194 req->usage_status = | |
| 1195 ResourcePrefetcher::Request::USAGE_STATUS_FROM_CACHE; | |
| 1196 } else { | |
| 1197 req->usage_status = | |
| 1198 ResourcePrefetcher::Request::USAGE_STATUS_FROM_NETWORK; | |
| 1199 } | |
| 1200 } | |
| 1201 | |
| 1202 switch (req->prefetch_status) { | |
| 1203 // TODO(shishir): Add histogram for each cancellation reason. | |
| 1204 case ResourcePrefetcher::Request::PREFETCH_STATUS_REDIRECTED: | |
| 1205 case ResourcePrefetcher::Request::PREFETCH_STATUS_AUTH_REQUIRED: | |
| 1206 case ResourcePrefetcher::Request::PREFETCH_STATUS_CERT_REQUIRED: | |
| 1207 case ResourcePrefetcher::Request::PREFETCH_STATUS_CERT_ERROR: | |
| 1208 case ResourcePrefetcher::Request::PREFETCH_STATUS_CANCELLED: | |
| 1209 ++prefetch_cancelled; | |
| 1210 break; | |
| 1211 | |
| 1212 case ResourcePrefetcher::Request::PREFETCH_STATUS_FAILED: | |
| 1213 ++prefetch_failed; | |
| 1214 break; | |
| 1215 | |
| 1216 case ResourcePrefetcher::Request::PREFETCH_STATUS_FROM_CACHE: | |
| 1217 if (req->usage_status == | |
| 1218 ResourcePrefetcher::Request::USAGE_STATUS_FROM_CACHE) | |
| 1219 ++p_cache_a_cache; | |
| 1220 else if (req->usage_status == | |
| 1221 ResourcePrefetcher::Request::USAGE_STATUS_FROM_NETWORK) | |
| 1222 ++p_cache_a_network; | |
| 1223 else | |
| 1224 ++p_cache_a_notused; | |
| 1225 break; | |
| 1226 | |
| 1227 case ResourcePrefetcher::Request::PREFETCH_STATUS_FROM_NETWORK: | |
| 1228 if (req->usage_status == | |
| 1229 ResourcePrefetcher::Request::USAGE_STATUS_FROM_CACHE) | |
| 1230 ++p_network_a_cache; | |
| 1231 else if (req->usage_status == | |
| 1232 ResourcePrefetcher::Request::USAGE_STATUS_FROM_NETWORK) | |
| 1233 ++p_network_a_network; | |
| 1234 else | |
| 1235 ++p_network_a_notused; | |
| 1236 break; | |
| 1237 | |
| 1238 case ResourcePrefetcher::Request::PREFETCH_STATUS_NOT_STARTED: | |
| 1239 ++prefetch_not_started; | |
| 1240 break; | |
| 1241 | |
| 1242 case ResourcePrefetcher::Request::PREFETCH_STATUS_STARTED: | |
| 1243 DLOG(FATAL) << "Invalid prefetch status"; | |
| 1244 break; | |
| 1245 } | |
| 1246 } | |
| 1247 | |
| 1248 int total_prefetched = p_cache_a_cache + p_cache_a_network + p_cache_a_notused | |
| 1249 + p_network_a_cache + p_network_a_network + p_network_a_notused; | |
| 1250 | |
| 1251 std::string histogram_type = key_type == PREFETCH_KEY_TYPE_HOST ? "Host." : | |
| 1252 "Url."; | |
| 1253 | |
| 1254 // Macros to avoid using the STATIC_HISTOGRAM_POINTER_BLOCK in UMA_HISTOGRAM | |
| 1255 // definitions. | |
| 1256 #define RPP_HISTOGRAM_PERCENTAGE(suffix, value) \ | |
| 1257 { \ | |
| 1258 std::string name = "ResourcePrefetchPredictor." + histogram_type + suffix; \ | |
| 1259 std::string g_name = "ResourcePrefetchPredictor." + std::string(suffix); \ | |
| 1260 base::HistogramBase* histogram = base::LinearHistogram::FactoryGet( \ | |
| 1261 name, 1, 101, 102, base::Histogram::kUmaTargetedHistogramFlag); \ | |
| 1262 histogram->Add(value); \ | |
| 1263 UMA_HISTOGRAM_PERCENTAGE(g_name, value); \ | |
| 1264 } | |
| 1265 | |
| 1266 RPP_HISTOGRAM_PERCENTAGE("PrefetchCancelled", | |
| 1267 prefetch_cancelled * 100.0 / total_prefetched); | |
| 1268 RPP_HISTOGRAM_PERCENTAGE("PrefetchFailed", | |
| 1269 prefetch_failed * 100.0 / total_prefetched); | |
| 1270 RPP_HISTOGRAM_PERCENTAGE("PrefetchFromCacheUsedFromCache", | |
| 1271 p_cache_a_cache * 100.0 / total_prefetched); | |
| 1272 RPP_HISTOGRAM_PERCENTAGE("PrefetchFromCacheUsedFromNetwork", | |
| 1273 p_cache_a_network * 100.0 / total_prefetched); | |
| 1274 RPP_HISTOGRAM_PERCENTAGE("PrefetchFromCacheNotUsed", | |
| 1275 p_cache_a_notused * 100.0 / total_prefetched); | |
| 1276 RPP_HISTOGRAM_PERCENTAGE("PrefetchFromNetworkUsedFromCache", | |
| 1277 p_network_a_cache * 100.0 / total_prefetched); | |
| 1278 RPP_HISTOGRAM_PERCENTAGE("PrefetchFromNetworkUsedFromNetwork", | |
| 1279 p_network_a_network * 100.0 / total_prefetched); | |
| 1280 RPP_HISTOGRAM_PERCENTAGE("PrefetchFromNetworkNotUsed", | |
| 1281 p_network_a_notused * 100.0 / total_prefetched); | |
| 1282 | |
| 1283 RPP_HISTOGRAM_PERCENTAGE( | |
| 1284 "PrefetchNotStarted", | |
| 1285 prefetch_not_started * 100.0 / (prefetch_not_started + total_prefetched)); | |
| 1286 | |
| 1287 #undef RPP_HISTOGRAM_PERCENTAGE | |
| 1288 } | |
| 1289 | |
| 1290 void ResourcePrefetchPredictor::ReportPredictedAccuracyStats( | |
| 1291 PrefetchKeyType key_type, | |
| 1292 const std::vector<URLRequestSummary>& actual, | |
| 1293 const ResourcePrefetcher::RequestVector& predicted) const { | |
| 1294 std::map<GURL, bool> actual_resources; | |
| 1295 int from_network = 0; | |
| 1296 for (std::vector<URLRequestSummary>::const_iterator it = actual.begin(); | |
| 1297 it != actual.end(); ++it) { | |
| 1298 actual_resources[it->resource_url] = it->was_cached; | |
| 1299 if (!it->was_cached) | |
| 1300 ++from_network; | |
| 1301 } | |
| 1302 | |
| 1303 // Measure the accuracy at 25, 50 predicted resources. | |
| 1304 ReportPredictedAccuracyStatsHelper(key_type, predicted, actual_resources, | |
| 1305 from_network, 25); | |
| 1306 ReportPredictedAccuracyStatsHelper(key_type, predicted, actual_resources, | |
| 1307 from_network, 50); | |
| 1308 } | |
| 1309 | |
| 1310 void ResourcePrefetchPredictor::ReportPredictedAccuracyStatsHelper( | |
| 1311 PrefetchKeyType key_type, | |
| 1312 const ResourcePrefetcher::RequestVector& predicted, | |
| 1313 const std::map<GURL, bool>& actual, | |
| 1314 size_t total_resources_fetched_from_network, | |
| 1315 size_t max_assumed_prefetched) const { | |
| 1316 int prefetch_cached = 0, prefetch_network = 0, prefetch_missed = 0; | |
| 1317 int num_assumed_prefetched = std::min(predicted.size(), | |
| 1318 max_assumed_prefetched); | |
| 1319 if (num_assumed_prefetched == 0) | |
| 1320 return; | |
| 1321 | |
| 1322 for (int i = 0; i < num_assumed_prefetched; ++i) { | |
| 1323 const ResourcePrefetcher::Request& row = *(predicted[i]); | |
| 1324 std::map<GURL, bool>::const_iterator it = actual.find(row.resource_url); | |
| 1325 if (it == actual.end()) { | |
| 1326 ++prefetch_missed; | |
| 1327 } else if (it->second) { | |
| 1328 ++prefetch_cached; | |
| 1329 } else { | |
| 1330 ++prefetch_network; | |
| 1331 } | |
| 1332 } | |
| 1333 | |
| 1334 std::string prefix = key_type == PREFETCH_KEY_TYPE_HOST ? | |
| 1335 "ResourcePrefetchPredictor.Host.Predicted" : | |
| 1336 "ResourcePrefetchPredictor.Url.Predicted"; | |
| 1337 std::string suffix = "_" + base::SizeTToString(max_assumed_prefetched); | |
| 1338 | |
| 1339 // Macros to avoid using the STATIC_HISTOGRAM_POINTER_BLOCK in UMA_HISTOGRAM | |
| 1340 // definitions. | |
| 1341 #define RPP_PREDICTED_HISTOGRAM_COUNTS(name, value) \ | |
| 1342 { \ | |
| 1343 std::string full_name = prefix + name + suffix; \ | |
| 1344 base::HistogramBase* histogram = base::Histogram::FactoryGet( \ | |
| 1345 full_name, 1, 1000000, 50, \ | |
| 1346 base::Histogram::kUmaTargetedHistogramFlag); \ | |
| 1347 histogram->Add(value); \ | |
| 1348 } | |
| 1349 | |
| 1350 #define RPP_PREDICTED_HISTOGRAM_PERCENTAGE(name, value) \ | |
| 1351 { \ | |
| 1352 std::string full_name = prefix + name + suffix; \ | |
| 1353 base::HistogramBase* histogram = base::LinearHistogram::FactoryGet( \ | |
| 1354 full_name, 1, 101, 102, base::Histogram::kUmaTargetedHistogramFlag); \ | |
| 1355 histogram->Add(value); \ | |
| 1356 } | |
| 1357 | |
| 1358 RPP_PREDICTED_HISTOGRAM_COUNTS("PrefetchCount", num_assumed_prefetched); | |
| 1359 RPP_PREDICTED_HISTOGRAM_COUNTS("PrefetchMisses_Count", prefetch_missed); | |
| 1360 RPP_PREDICTED_HISTOGRAM_COUNTS("PrefetchFromCache_Count", prefetch_cached); | |
| 1361 RPP_PREDICTED_HISTOGRAM_COUNTS("PrefetchFromNetwork_Count", prefetch_network); | |
| 1362 | |
| 1363 RPP_PREDICTED_HISTOGRAM_PERCENTAGE( | |
| 1364 "PrefetchMisses_PercentOfTotalPrefetched", | |
| 1365 prefetch_missed * 100.0 / num_assumed_prefetched); | |
| 1366 RPP_PREDICTED_HISTOGRAM_PERCENTAGE( | |
| 1367 "PrefetchFromCache_PercentOfTotalPrefetched", | |
| 1368 prefetch_cached * 100.0 / num_assumed_prefetched); | |
| 1369 RPP_PREDICTED_HISTOGRAM_PERCENTAGE( | |
| 1370 "PrefetchFromNetwork_PercentOfTotalPrefetched", | |
| 1371 prefetch_network * 100.0 / num_assumed_prefetched); | |
| 1372 | |
| 1373 // Measure the ratio of total number of resources prefetched from network vs | |
| 1374 // the total number of resources fetched by the page from the network. | |
| 1375 if (total_resources_fetched_from_network > 0) { | |
| 1376 RPP_PREDICTED_HISTOGRAM_PERCENTAGE( | |
| 1377 "PrefetchFromNetworkPercentOfTotalFromNetwork", | |
| 1378 prefetch_network * 100.0 / total_resources_fetched_from_network); | |
| 1379 } | |
| 1380 | |
| 1381 #undef RPP_HISTOGRAM_MEDIUM_TIMES | |
| 1382 #undef RPP_PREDICTED_HISTOGRAM_PERCENTAGE | |
| 1383 #undef RPP_PREDICTED_HISTOGRAM_COUNTS | |
| 1384 } | |
| 1385 | |
| 1386 void ResourcePrefetchPredictor::OnURLsDeleted( | 932 void ResourcePrefetchPredictor::OnURLsDeleted( |
| 1387 history::HistoryService* history_service, | 933 history::HistoryService* history_service, |
| 1388 bool all_history, | 934 bool all_history, |
| 1389 bool expired, | 935 bool expired, |
| 1390 const history::URLRows& deleted_rows, | 936 const history::URLRows& deleted_rows, |
| 1391 const std::set<GURL>& favicon_urls) { | 937 const std::set<GURL>& favicon_urls) { |
| 1392 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 938 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1393 if (INITIALIZED != initialization_state_) | 939 if (INITIALIZED != initialization_state_) |
| 1394 return; | 940 return; |
| 1395 | 941 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1423 // HistoryService is already loaded. Continue with Initialization. | 969 // HistoryService is already loaded. Continue with Initialization. |
| 1424 OnHistoryAndCacheLoaded(); | 970 OnHistoryAndCacheLoaded(); |
| 1425 return; | 971 return; |
| 1426 } | 972 } |
| 1427 DCHECK(!history_service_observer_.IsObserving(history_service)); | 973 DCHECK(!history_service_observer_.IsObserving(history_service)); |
| 1428 history_service_observer_.Add(history_service); | 974 history_service_observer_.Add(history_service); |
| 1429 return; | 975 return; |
| 1430 } | 976 } |
| 1431 | 977 |
| 1432 } // namespace predictors | 978 } // namespace predictors |
| OLD | NEW |