Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/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->plt_recorded_) { | |
| 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 // To be called when a PLT was seen for a given URL. | |
| 468 // Returns true iff: | |
| 469 // - There is an entry of a prefetch for the URL provided. | |
| 470 // - The prefetch was started before the page load was started (based on the | |
| 471 // plt). | |
| 472 // - The prefetch entry has not been returned "true" for as a result of a call | |
| 473 // to this method previously. | |
| 474 bool SeenPLTForURL(const GURL& url, base::TimeDelta plt) { | |
|
jkarlin
2014/08/21 14:34:14
Rename to MarkPLTSeen? Then reformat the comments
tburkard
2014/08/21 15:28:11
Done.
| |
| 475 ExpireOldItems(); | |
| 476 base::hash_map<string, ListEntry*>::iterator it = | |
| 477 entries_.find(url.spec().c_str()); | |
| 478 if (it == entries_.end() || it->second->plt_recorded_ || | |
| 479 it->second->add_time_ > GetCurrentTime() - plt) { | |
| 480 return false; | |
| 481 } | |
| 482 it->second->plt_recorded_ = true; | |
| 483 // If the item has been seen in both the history and in tab contents, | |
| 484 // and the page load time has been recorded, erase it from the map to | |
| 485 // make room for new prefetches. | |
| 486 if (it->second->seen_tabcontents_ && it->second->seen_history_ && | |
| 487 it->second->plt_recorded_) { | |
| 488 entries_.erase(url.spec().c_str()); | |
| 489 } | |
| 490 return true; | |
| 491 } | |
| 492 | |
| 464 private: | 493 private: |
| 465 struct ListEntry { | 494 struct ListEntry { |
| 466 explicit ListEntry(const string& url) | 495 explicit ListEntry(const string& url) |
| 467 : url_(url), | 496 : url_(url), |
| 468 add_time_(GetCurrentTime()), | 497 add_time_(GetCurrentTime()), |
| 469 seen_tabcontents_(false), | 498 seen_tabcontents_(false), |
| 470 seen_history_(false) { | 499 seen_history_(false), |
| 500 plt_recorded_(false) { | |
| 471 } | 501 } |
| 472 std::string url_; | 502 std::string url_; |
| 473 base::Time add_time_; | 503 base::Time add_time_; |
| 474 bool seen_tabcontents_; | 504 bool seen_tabcontents_; |
| 475 bool seen_history_; | 505 bool seen_history_; |
| 506 bool plt_recorded_; | |
|
jkarlin
2014/08/21 14:34:14
Why not seen_plt_ like the other members? Prefetc
tburkard
2014/08/21 15:28:11
Done.
| |
| 476 }; | 507 }; |
| 477 | 508 |
| 478 void ExpireOldItems() { | 509 void ExpireOldItems() { |
| 479 base::Time expiry_cutoff = GetCurrentTime() - | 510 base::Time expiry_cutoff = GetCurrentTime() - |
| 480 base::TimeDelta::FromSeconds(GetPrerenderPrefetchListTimeoutSeconds()); | 511 base::TimeDelta::FromSeconds(GetPrerenderPrefetchListTimeoutSeconds()); |
| 481 while (!entry_list_.empty() && | 512 while (!entry_list_.empty() && |
| 482 (entry_list_.front()->add_time_ < expiry_cutoff || | 513 (entry_list_.front()->add_time_ < expiry_cutoff || |
| 483 entries_.size() > kMaxPrefetchItems)) { | 514 entries_.size() > kMaxPrefetchItems)) { |
| 484 ListEntry* entry = entry_list_.front(); | 515 ListEntry* entry = entry_list_.front(); |
| 485 entry_list_.pop_front(); | 516 entry_list_.pop_front(); |
| (...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1112 &history_db_tracker_); | 1143 &history_db_tracker_); |
| 1113 history->AddVisitDatabaseObserver(this); | 1144 history->AddVisitDatabaseObserver(this); |
| 1114 is_visit_database_observer_ = true; | 1145 is_visit_database_observer_ = true; |
| 1115 } else { | 1146 } else { |
| 1116 RecordEvent(EVENT_INIT_FAILED_NO_HISTORY); | 1147 RecordEvent(EVENT_INIT_FAILED_NO_HISTORY); |
| 1117 } | 1148 } |
| 1118 } | 1149 } |
| 1119 | 1150 |
| 1120 void PrerenderLocalPredictor::OnPLTEventForURL(const GURL& url, | 1151 void PrerenderLocalPredictor::OnPLTEventForURL(const GURL& url, |
| 1121 base::TimeDelta page_load_time) { | 1152 base::TimeDelta page_load_time) { |
| 1153 if (prefetch_list_->SeenPLTForURL(url, page_load_time)) { | |
| 1154 UMA_HISTOGRAM_CUSTOM_TIMES("Prerender.LocalPredictorPrefetchMatchPLT", | |
| 1155 page_load_time, | |
| 1156 base::TimeDelta::FromMilliseconds(10), | |
| 1157 base::TimeDelta::FromSeconds(60), | |
| 1158 100); | |
| 1159 } | |
| 1160 | |
| 1122 scoped_ptr<PrerenderProperties> prerender; | 1161 scoped_ptr<PrerenderProperties> prerender; |
| 1123 if (DoesPrerenderMatchPLTRecord(last_swapped_in_prerender_.get(), | 1162 if (DoesPrerenderMatchPLTRecord(last_swapped_in_prerender_.get(), |
| 1124 url, page_load_time)) { | 1163 url, page_load_time)) { |
| 1125 prerender.reset(last_swapped_in_prerender_.release()); | 1164 prerender.reset(last_swapped_in_prerender_.release()); |
| 1126 } | 1165 } |
| 1127 if (DoesPrerenderMatchPLTRecord(current_prerender_.get(), | 1166 if (DoesPrerenderMatchPLTRecord(current_prerender_.get(), |
| 1128 url, page_load_time)) { | 1167 url, page_load_time)) { |
| 1129 prerender.reset(current_prerender_.release()); | 1168 prerender.reset(current_prerender_.release()); |
| 1130 } | 1169 } |
| 1131 if (!prerender.get()) | 1170 if (!prerender.get()) |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1331 num_issued++; | 1370 num_issued++; |
| 1332 continue; | 1371 continue; |
| 1333 } | 1372 } |
| 1334 } | 1373 } |
| 1335 } | 1374 } |
| 1336 | 1375 |
| 1337 void PrerenderLocalPredictor::IssuePrerender( | 1376 void PrerenderLocalPredictor::IssuePrerender( |
| 1338 CandidatePrerenderInfo* info, | 1377 CandidatePrerenderInfo* info, |
| 1339 LocalPredictorURLInfo* url_info) { | 1378 LocalPredictorURLInfo* url_info) { |
| 1340 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1379 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1341 if (prefetch_list_->AddURL(url_info->url)) | 1380 if (prefetch_list_->AddURL(url_info->url)) { |
| 1342 RecordEvent(EVENT_PREFETCH_LIST_ADDED); | 1381 RecordEvent(EVENT_PREFETCH_LIST_ADDED); |
| 1382 // If we are prefetching rather than prerendering, now is the time to launch | |
| 1383 // the prefetch. | |
| 1384 if (IsLocalPredictorPrerenderPrefetchEnabled()) { | |
| 1385 // Obtain the render frame host that caused this prefetch. | |
| 1386 RenderFrameHost* rfh = RenderFrameHost::FromID(info->render_process_id_, | |
| 1387 info->render_frame_id_); | |
| 1388 // If it is still alive, launch the prefresh. | |
| 1389 if (rfh) | |
| 1390 rfh->Send(new PrefetchMsg_Prefetch(rfh->GetRoutingID(), url_info->url)); | |
| 1391 } | |
| 1392 } | |
| 1343 PrerenderProperties* prerender_properties = | 1393 PrerenderProperties* prerender_properties = |
| 1344 GetIssuedPrerenderSlotForPriority(url_info->url, url_info->priority); | 1394 GetIssuedPrerenderSlotForPriority(url_info->url, url_info->priority); |
| 1345 if (!prerender_properties) { | 1395 if (!prerender_properties) { |
| 1346 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_PRIORITY_TOO_LOW); | 1396 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_PRIORITY_TOO_LOW); |
| 1347 return; | 1397 return; |
| 1348 } | 1398 } |
| 1349 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ISSUING_PRERENDER); | 1399 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ISSUING_PRERENDER); |
| 1350 DCHECK(prerender_properties != NULL); | 1400 DCHECK(prerender_properties != NULL); |
| 1351 DCHECK(info != NULL); | 1401 DCHECK(info != NULL); |
| 1352 DCHECK(url_info != NULL); | 1402 DCHECK(url_info != NULL); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1388 prerender_properties->start_time = current_time; | 1438 prerender_properties->start_time = current_time; |
| 1389 prerender_properties->actual_start_time = current_time; | 1439 prerender_properties->actual_start_time = current_time; |
| 1390 prerender_properties->would_have_matched = false; | 1440 prerender_properties->would_have_matched = false; |
| 1391 prerender_properties->prerender_handle.swap(new_prerender_handle); | 1441 prerender_properties->prerender_handle.swap(new_prerender_handle); |
| 1392 // new_prerender_handle now represents the old previou prerender that we | 1442 // new_prerender_handle now represents the old previou prerender that we |
| 1393 // are replacing. So we need to cancel it. | 1443 // are replacing. So we need to cancel it. |
| 1394 if (new_prerender_handle) { | 1444 if (new_prerender_handle) { |
| 1395 new_prerender_handle->OnCancel(); | 1445 new_prerender_handle->OnCancel(); |
| 1396 RecordEvent(EVENT_ISSUE_PRERENDER_CANCELLED_OLD_PRERENDER); | 1446 RecordEvent(EVENT_ISSUE_PRERENDER_CANCELLED_OLD_PRERENDER); |
| 1397 } | 1447 } |
| 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 } | 1448 } |
| 1409 | 1449 |
| 1410 RecordEvent(EVENT_ADD_VISIT_PRERENDERING); | 1450 RecordEvent(EVENT_ADD_VISIT_PRERENDERING); |
| 1411 if (current_prerender_.get() && current_prerender_->url_id == url_id) { | 1451 if (current_prerender_.get() && current_prerender_->url_id == url_id) { |
| 1412 RecordEvent(EVENT_ADD_VISIT_PRERENDERING_EXTENDED); | 1452 RecordEvent(EVENT_ADD_VISIT_PRERENDERING_EXTENDED); |
| 1413 if (priority > current_prerender_->priority) | 1453 if (priority > current_prerender_->priority) |
| 1414 current_prerender_->priority = priority; | 1454 current_prerender_->priority = priority; |
| 1415 // If the prerender already existed, we want to extend it. However, | 1455 // 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 | 1456 // we do not want to set its start_time to the current time to |
| 1417 // disadvantage PLT computations when the prerender is swapped in. | 1457 // disadvantage PLT computations when the prerender is swapped in. |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1526 break; | 1566 break; |
| 1527 case content::SessionStorageNamespace::MERGE_RESULT_MERGEABLE: | 1567 case content::SessionStorageNamespace::MERGE_RESULT_MERGEABLE: |
| 1528 RecordEvent(EVENT_NAMESPACE_MISMATCH_MERGE_RESULT_MERGEABLE); | 1568 RecordEvent(EVENT_NAMESPACE_MISMATCH_MERGE_RESULT_MERGEABLE); |
| 1529 break; | 1569 break; |
| 1530 default: | 1570 default: |
| 1531 NOTREACHED(); | 1571 NOTREACHED(); |
| 1532 } | 1572 } |
| 1533 } | 1573 } |
| 1534 | 1574 |
| 1535 } // namespace prerender | 1575 } // namespace prerender |
| OLD | NEW |