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/prerender/prerender_local_predictor.h" | 5 #include "chrome/browser/prerender/prerender_local_predictor.h" |
6 | 6 |
7 #include <ctype.h> | 7 #include <ctype.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <map> | 10 #include <map> |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
448 return return_value; | 448 return return_value; |
449 if (type == SEEN_TABCONTENTS_OBSERVER && !it->second->seen_tabcontents_) { | 449 if (type == SEEN_TABCONTENTS_OBSERVER && !it->second->seen_tabcontents_) { |
450 it->second->seen_tabcontents_ = true; | 450 it->second->seen_tabcontents_ = true; |
451 return_value = true; | 451 return_value = true; |
452 } | 452 } |
453 if (type == SEEN_HISTORY && !it->second->seen_history_) { | 453 if (type == SEEN_HISTORY && !it->second->seen_history_) { |
454 it->second->seen_history_ = true; | 454 it->second->seen_history_ = true; |
455 return_value = true; | 455 return_value = true; |
456 } | 456 } |
457 // If the item has been seen in both the history and in tab contents, | 457 // If the item has been seen in both the history and in tab contents, |
458 // erase it from the map to make room for new prefetches. | 458 // and the page load time has been recorded, erase it from the map to |
459 if (it->second->seen_tabcontents_ && it->second->seen_history_) | 459 // make room for new prefetches. |
460 if (it->second->seen_tabcontents_ && it->second->seen_history_ && | |
461 it->second->seen_plt_) { | |
460 entries_.erase(url.spec().c_str()); | 462 entries_.erase(url.spec().c_str()); |
463 } | |
461 return return_value; | 464 return return_value; |
462 } | 465 } |
463 | 466 |
467 // Marks the PLT for the provided UR as seen. Returns true | |
468 // iff the item is currently in the list and the PLT had not been seen | |
469 // before in, i.e. the sighting was successful. | |
jkarlin
2014/08/21 16:22:53
"before in," please fix.
tburkard
2014/08/22 09:49:34
Done.
| |
470 bool MarkPLTSeen(const GURL& url, base::TimeDelta plt) { | |
471 ExpireOldItems(); | |
472 base::hash_map<string, ListEntry*>::iterator it = | |
473 entries_.find(url.spec().c_str()); | |
474 if (it == entries_.end() || it->second->seen_plt_ || | |
475 it->second->add_time_ > GetCurrentTime() - plt) { | |
476 return false; | |
477 } | |
478 it->second->seen_plt_ = true; | |
479 // If the item has been seen in both the history and in tab contents, | |
480 // and the page load time has been recorded, erase it from the map to | |
481 // make room for new prefetches. | |
482 if (it->second->seen_tabcontents_ && it->second->seen_history_ && | |
483 it->second->seen_plt_) { | |
484 entries_.erase(url.spec().c_str()); | |
485 } | |
486 return true; | |
487 } | |
488 | |
464 private: | 489 private: |
465 struct ListEntry { | 490 struct ListEntry { |
466 explicit ListEntry(const string& url) | 491 explicit ListEntry(const string& url) |
467 : url_(url), | 492 : url_(url), |
468 add_time_(GetCurrentTime()), | 493 add_time_(GetCurrentTime()), |
469 seen_tabcontents_(false), | 494 seen_tabcontents_(false), |
470 seen_history_(false) { | 495 seen_history_(false), |
496 seen_plt_(false) { | |
471 } | 497 } |
472 std::string url_; | 498 std::string url_; |
473 base::Time add_time_; | 499 base::Time add_time_; |
474 bool seen_tabcontents_; | 500 bool seen_tabcontents_; |
475 bool seen_history_; | 501 bool seen_history_; |
502 bool seen_plt_; | |
476 }; | 503 }; |
477 | 504 |
478 void ExpireOldItems() { | 505 void ExpireOldItems() { |
479 base::Time expiry_cutoff = GetCurrentTime() - | 506 base::Time expiry_cutoff = GetCurrentTime() - |
480 base::TimeDelta::FromSeconds(GetPrerenderPrefetchListTimeoutSeconds()); | 507 base::TimeDelta::FromSeconds(GetPrerenderPrefetchListTimeoutSeconds()); |
481 while (!entry_list_.empty() && | 508 while (!entry_list_.empty() && |
482 (entry_list_.front()->add_time_ < expiry_cutoff || | 509 (entry_list_.front()->add_time_ < expiry_cutoff || |
483 entries_.size() > kMaxPrefetchItems)) { | 510 entries_.size() > kMaxPrefetchItems)) { |
484 ListEntry* entry = entry_list_.front(); | 511 ListEntry* entry = entry_list_.front(); |
485 entry_list_.pop_front(); | 512 entry_list_.pop_front(); |
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1112 &history_db_tracker_); | 1139 &history_db_tracker_); |
1113 history->AddVisitDatabaseObserver(this); | 1140 history->AddVisitDatabaseObserver(this); |
1114 is_visit_database_observer_ = true; | 1141 is_visit_database_observer_ = true; |
1115 } else { | 1142 } else { |
1116 RecordEvent(EVENT_INIT_FAILED_NO_HISTORY); | 1143 RecordEvent(EVENT_INIT_FAILED_NO_HISTORY); |
1117 } | 1144 } |
1118 } | 1145 } |
1119 | 1146 |
1120 void PrerenderLocalPredictor::OnPLTEventForURL(const GURL& url, | 1147 void PrerenderLocalPredictor::OnPLTEventForURL(const GURL& url, |
1121 base::TimeDelta page_load_time) { | 1148 base::TimeDelta page_load_time) { |
1149 if (prefetch_list_->MarkPLTSeen(url, page_load_time)) { | |
1150 UMA_HISTOGRAM_CUSTOM_TIMES("Prerender.LocalPredictorPrefetchMatchPLT", | |
1151 page_load_time, | |
1152 base::TimeDelta::FromMilliseconds(10), | |
1153 base::TimeDelta::FromSeconds(60), | |
1154 100); | |
1155 } | |
1156 | |
1122 scoped_ptr<PrerenderProperties> prerender; | 1157 scoped_ptr<PrerenderProperties> prerender; |
1123 if (DoesPrerenderMatchPLTRecord(last_swapped_in_prerender_.get(), | 1158 if (DoesPrerenderMatchPLTRecord(last_swapped_in_prerender_.get(), |
1124 url, page_load_time)) { | 1159 url, page_load_time)) { |
1125 prerender.reset(last_swapped_in_prerender_.release()); | 1160 prerender.reset(last_swapped_in_prerender_.release()); |
1126 } | 1161 } |
1127 if (DoesPrerenderMatchPLTRecord(current_prerender_.get(), | 1162 if (DoesPrerenderMatchPLTRecord(current_prerender_.get(), |
1128 url, page_load_time)) { | 1163 url, page_load_time)) { |
1129 prerender.reset(current_prerender_.release()); | 1164 prerender.reset(current_prerender_.release()); |
1130 } | 1165 } |
1131 if (!prerender.get()) | 1166 if (!prerender.get()) |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1331 num_issued++; | 1366 num_issued++; |
1332 continue; | 1367 continue; |
1333 } | 1368 } |
1334 } | 1369 } |
1335 } | 1370 } |
1336 | 1371 |
1337 void PrerenderLocalPredictor::IssuePrerender( | 1372 void PrerenderLocalPredictor::IssuePrerender( |
1338 CandidatePrerenderInfo* info, | 1373 CandidatePrerenderInfo* info, |
1339 LocalPredictorURLInfo* url_info) { | 1374 LocalPredictorURLInfo* url_info) { |
1340 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1375 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1341 if (prefetch_list_->AddURL(url_info->url)) | 1376 if (prefetch_list_->AddURL(url_info->url)) { |
1342 RecordEvent(EVENT_PREFETCH_LIST_ADDED); | 1377 RecordEvent(EVENT_PREFETCH_LIST_ADDED); |
1378 // If we are prefetching rather than prerendering, now is the time to launch | |
1379 // the prefetch. | |
1380 if (IsLocalPredictorPrerenderPrefetchEnabled()) { | |
1381 // Obtain the render frame host that caused this prefetch. | |
1382 RenderFrameHost* rfh = RenderFrameHost::FromID(info->render_process_id_, | |
1383 info->render_frame_id_); | |
1384 // If it is still alive, launch the prefresh. | |
1385 if (rfh) | |
1386 rfh->Send(new PrefetchMsg_Prefetch(rfh->GetRoutingID(), url_info->url)); | |
1387 } | |
1388 } | |
1343 PrerenderProperties* prerender_properties = | 1389 PrerenderProperties* prerender_properties = |
1344 GetIssuedPrerenderSlotForPriority(url_info->url, url_info->priority); | 1390 GetIssuedPrerenderSlotForPriority(url_info->url, url_info->priority); |
1345 if (!prerender_properties) { | 1391 if (!prerender_properties) { |
1346 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_PRIORITY_TOO_LOW); | 1392 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_PRIORITY_TOO_LOW); |
1347 return; | 1393 return; |
1348 } | 1394 } |
1349 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ISSUING_PRERENDER); | 1395 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ISSUING_PRERENDER); |
1350 DCHECK(prerender_properties != NULL); | 1396 DCHECK(prerender_properties != NULL); |
1351 DCHECK(info != NULL); | 1397 DCHECK(info != NULL); |
1352 DCHECK(url_info != NULL); | 1398 DCHECK(url_info != NULL); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1388 prerender_properties->start_time = current_time; | 1434 prerender_properties->start_time = current_time; |
1389 prerender_properties->actual_start_time = current_time; | 1435 prerender_properties->actual_start_time = current_time; |
1390 prerender_properties->would_have_matched = false; | 1436 prerender_properties->would_have_matched = false; |
1391 prerender_properties->prerender_handle.swap(new_prerender_handle); | 1437 prerender_properties->prerender_handle.swap(new_prerender_handle); |
1392 // new_prerender_handle now represents the old previou prerender that we | 1438 // new_prerender_handle now represents the old previou prerender that we |
1393 // are replacing. So we need to cancel it. | 1439 // are replacing. So we need to cancel it. |
1394 if (new_prerender_handle) { | 1440 if (new_prerender_handle) { |
1395 new_prerender_handle->OnCancel(); | 1441 new_prerender_handle->OnCancel(); |
1396 RecordEvent(EVENT_ISSUE_PRERENDER_CANCELLED_OLD_PRERENDER); | 1442 RecordEvent(EVENT_ISSUE_PRERENDER_CANCELLED_OLD_PRERENDER); |
1397 } | 1443 } |
1398 // If we are prefetching rather than prerendering, now is the time to launch | |
1399 // the prefetch. | |
1400 if (IsLocalPredictorPrerenderPrefetchEnabled()) { | |
1401 // Obtain the render frame host that caused this prefetch. | |
1402 RenderFrameHost* rfh = RenderFrameHost::FromID(info->render_process_id_, | |
1403 info->render_frame_id_); | |
1404 // If it is still alive, launch the prefresh. | |
1405 if (rfh) | |
1406 rfh->Send(new PrefetchMsg_Prefetch(rfh->GetRoutingID(), url)); | |
1407 } | |
1408 } | 1444 } |
1409 | 1445 |
1410 RecordEvent(EVENT_ADD_VISIT_PRERENDERING); | 1446 RecordEvent(EVENT_ADD_VISIT_PRERENDERING); |
1411 if (current_prerender_.get() && current_prerender_->url_id == url_id) { | 1447 if (current_prerender_.get() && current_prerender_->url_id == url_id) { |
1412 RecordEvent(EVENT_ADD_VISIT_PRERENDERING_EXTENDED); | 1448 RecordEvent(EVENT_ADD_VISIT_PRERENDERING_EXTENDED); |
1413 if (priority > current_prerender_->priority) | 1449 if (priority > current_prerender_->priority) |
1414 current_prerender_->priority = priority; | 1450 current_prerender_->priority = priority; |
1415 // If the prerender already existed, we want to extend it. However, | 1451 // If the prerender already existed, we want to extend it. However, |
1416 // we do not want to set its start_time to the current time to | 1452 // we do not want to set its start_time to the current time to |
1417 // disadvantage PLT computations when the prerender is swapped in. | 1453 // disadvantage PLT computations when the prerender is swapped in. |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1526 break; | 1562 break; |
1527 case content::SessionStorageNamespace::MERGE_RESULT_MERGEABLE: | 1563 case content::SessionStorageNamespace::MERGE_RESULT_MERGEABLE: |
1528 RecordEvent(EVENT_NAMESPACE_MISMATCH_MERGE_RESULT_MERGEABLE); | 1564 RecordEvent(EVENT_NAMESPACE_MISMATCH_MERGE_RESULT_MERGEABLE); |
1529 break; | 1565 break; |
1530 default: | 1566 default: |
1531 NOTREACHED(); | 1567 NOTREACHED(); |
1532 } | 1568 } |
1533 } | 1569 } |
1534 | 1570 |
1535 } // namespace prerender | 1571 } // namespace prerender |
OLD | NEW |