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->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 |