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

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

Issue 2301093002: predictors: Remove unused histograms for speculative_prefetch_predictor. (Closed)
Patch Set: . Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698