Index: chrome/browser/prerender/prerender_local_predictor.cc |
=================================================================== |
--- chrome/browser/prerender/prerender_local_predictor.cc (revision 198752) |
+++ chrome/browser/prerender/prerender_local_predictor.cc (working copy) |
@@ -19,63 +19,117 @@ |
#include "chrome/browser/history/history_db_task.h" |
#include "chrome/browser/history/history_service.h" |
#include "chrome/browser/history/history_service_factory.h" |
+#include "chrome/browser/prerender/prerender_handle.h" |
#include "chrome/browser/prerender/prerender_histograms.h" |
#include "chrome/browser/prerender/prerender_manager.h" |
#include "chrome/browser/profiles/profile.h" |
+#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" |
#include "content/public/browser/browser_thread.h" |
+#include "content/public/browser/navigation_controller.h" |
+#include "content/public/browser/session_storage_namespace.h" |
+#include "content/public/browser/web_contents.h" |
+#include "content/public/browser/web_contents_view.h" |
#include "content/public/common/page_transition_types.h" |
#include "crypto/secure_hash.h" |
+#include "googleurl/src/url_canon.h" |
#include "grit/browser_resources.h" |
#include "ui/base/resource/resource_bundle.h" |
using content::BrowserThread; |
using content::PageTransition; |
+using content::SessionStorageNamespace; |
+using content::WebContents; |
using history::URLID; |
+using predictors::LoggedInPredictorTable; |
+using std::string; |
+using std::vector; |
namespace prerender { |
namespace { |
static const size_t kURLHashSize = 5; |
+static const int kNumPrerenderCandidates = 5; |
+} // namespace |
+ |
+struct PrerenderLocalPredictor::LocalPredictorURLInfo { |
Shishir
2013/05/07 22:57:30
Add comment about struct.
tburkard
2013/05/07 23:21:59
Done.
|
+ URLID id; |
+ GURL url; |
+ bool url_lookup_success; |
+ bool logged_in; |
+ bool logged_in_lookup_ok; |
+ double priority; |
+}; |
+ |
+struct PrerenderLocalPredictor::LocalPredictorURLLookupInfo { |
Shishir
2013/05/07 22:57:30
Add comments about struct.
tburkard
2013/05/07 23:21:59
Done.
|
+ LocalPredictorURLInfo source_url_; |
+ vector<LocalPredictorURLInfo> candidate_urls_; |
+ explicit LocalPredictorURLLookupInfo(URLID source_id) { |
+ source_url_.id = source_id; |
+ } |
+ void MaybeAddCandidateURL(URLID id, double priority) { |
+ LocalPredictorURLInfo info; |
+ info.id = id; |
+ info.priority = priority; |
+ int insert_pos = candidate_urls_.size(); |
+ if (insert_pos < kNumPrerenderCandidates) |
+ candidate_urls_.push_back(info); |
+ while (insert_pos > 0 && |
Shishir
2013/05/07 22:57:30
Maybe use a list so you can just insert in the rig
tburkard
2013/05/07 23:21:59
I'd prefer to keep it the way it is for now, since
Shishir
2013/05/08 20:19:20
I still think this code is messy. Eg. it has the f
tburkard
2013/05/08 20:35:47
Done.
|
+ candidate_urls_[insert_pos - 1].priority < info.priority) { |
+ if (insert_pos < kNumPrerenderCandidates) |
+ candidate_urls_[insert_pos] = candidate_urls_[insert_pos - 1]; |
+ insert_pos--; |
+ } |
+ if (insert_pos < kNumPrerenderCandidates) |
+ candidate_urls_[insert_pos] = info; |
+ } |
+}; |
+ |
+namespace { |
+ |
// Task to lookup the URL for a given URLID. |
class GetURLForURLIDTask : public history::HistoryDBTask { |
public: |
- GetURLForURLIDTask(URLID url_id, base::Callback<void(const GURL&)> callback) |
- : url_id_(url_id), |
- success_(false), |
+ GetURLForURLIDTask(PrerenderLocalPredictor::LocalPredictorURLLookupInfo* |
+ request, |
Shishir
2013/05/07 22:57:30
indent 4 spaces.
tburkard
2013/05/07 23:21:59
Done.
|
+ const base::Closure& callback) |
+ : request_(request), |
callback_(callback), |
start_time_(base::Time::Now()) { |
} |
virtual bool RunOnDBThread(history::HistoryBackend* backend, |
history::HistoryDatabase* db) OVERRIDE { |
- history::URLRow url_row; |
- success_ = db->GetURLRow(url_id_, &url_row); |
- if (success_) |
- url_ = url_row.url(); |
+ DoURLLookup(db, &request_->source_url_); |
+ for (int i = 0; i < static_cast<int>(request_->candidate_urls_.size()); i++) |
+ DoURLLookup(db, &request_->candidate_urls_[i]); |
return true; |
} |
virtual void DoneRunOnMainThread() OVERRIDE { |
- if (success_) { |
- callback_.Run(url_); |
- UMA_HISTOGRAM_CUSTOM_TIMES("Prerender.LocalPredictorURLLookupTime", |
- base::Time::Now() - start_time_, |
- base::TimeDelta::FromMilliseconds(10), |
- base::TimeDelta::FromSeconds(10), |
- 50); |
- } |
+ callback_.Run(); |
+ UMA_HISTOGRAM_CUSTOM_TIMES("Prerender.LocalPredictorURLLookupTime", |
+ base::Time::Now() - start_time_, |
+ base::TimeDelta::FromMilliseconds(10), |
+ base::TimeDelta::FromSeconds(10), |
+ 50); |
} |
private: |
virtual ~GetURLForURLIDTask() {} |
- URLID url_id_; |
- bool success_; |
- base::Callback<void(const GURL&)> callback_; |
+ void DoURLLookup(history::HistoryDatabase* db, |
+ PrerenderLocalPredictor::LocalPredictorURLInfo* request) { |
+ history::URLRow url_row; |
+ request->url_lookup_success = db->GetURLRow(request->id, &url_row); |
+ if (request->url_lookup_success) |
+ request->url = url_row.url(); |
+ } |
+ |
+ PrerenderLocalPredictor::LocalPredictorURLLookupInfo* request_; |
+ base::Closure callback_; |
base::Time start_time_; |
- GURL url_; |
DISALLOW_COPY_AND_ASSIGN(GetURLForURLIDTask); |
}; |
@@ -86,7 +140,7 @@ |
int max_visits) |
: local_predictor_(local_predictor), |
max_visits_(max_visits), |
- visit_history_(new std::vector<history::BriefVisitInfo>) { |
+ visit_history_(new vector<history::BriefVisitInfo>) { |
} |
virtual bool RunOnDBThread(history::HistoryBackend* backend, |
@@ -104,7 +158,7 @@ |
PrerenderLocalPredictor* local_predictor_; |
int max_visits_; |
- scoped_ptr<std::vector<history::BriefVisitInfo> > visit_history_; |
+ scoped_ptr<vector<history::BriefVisitInfo> > visit_history_; |
DISALLOW_COPY_AND_ASSIGN(GetVisitHistoryTask); |
}; |
@@ -115,7 +169,7 @@ |
const int kVisitHistoryPruneThreshold = 120 * 1000; |
const int kVisitHistoryPruneAmount = 20 * 1000; |
-const int kMaxLocalPredictionTimeMs = 300 * 1000; |
+const int kMaxLocalPredictionTimeMs = 180 * 1000; |
const int kMinLocalPredictionTimeMs = 500; |
bool IsBackForward(PageTransition transition) { |
@@ -139,14 +193,14 @@ |
return base::Time::Now(); |
} |
-bool StrCaseStr(std::string haystack, std::string needle) { |
+bool StrCaseStr(string haystack, string needle) { |
Shishir
2013/05/07 22:57:30
Maybe rename to StringContainsIgnoringCase?
tburkard
2013/05/07 23:21:59
Done.
|
std::transform(haystack.begin(), haystack.end(), haystack.begin(), ::tolower); |
std::transform(needle.begin(), needle.end(), needle.begin(), ::tolower); |
- return haystack.find(needle) != std::string::npos; |
+ return haystack.find(needle) != string::npos; |
} |
bool IsExtendedRootURL(const GURL& url) { |
- const std::string& path = url.path(); |
+ const string& path = url.path(); |
return path == "/index.html" || path == "/home.html" || |
path == "/main.html" || |
path == "/index.htm" || path == "/home.htm" || path == "/main.htm" || |
@@ -161,6 +215,16 @@ |
(!url.has_query()) && (!url.has_ref()); |
} |
+bool IsLogInURL(const GURL& url) { |
+ return StrCaseStr(url.spec().c_str(), "login") || |
+ StrCaseStr(url.spec().c_str(), "signin"); |
+} |
+ |
+bool IsLogOutURL(const GURL& url) { |
+ return StrCaseStr(url.spec().c_str(), "logout") || |
+ StrCaseStr(url.spec().c_str(), "signout"); |
+} |
+ |
int64 URLHashToInt64(const unsigned char* data) { |
COMPILE_ASSERT(kURLHashSize < sizeof(int64), url_hash_must_fit_in_int64); |
int64 value = 0; |
@@ -179,10 +243,34 @@ |
return hash_value; |
} |
+bool URLsIdenticalIgnoringFragments(const GURL& url1, const GURL& url2) { |
+ url_canon::Replacements<char> replacement; |
+ replacement.ClearRef(); |
+ GURL u1 = url1.ReplaceComponents(replacement); |
+ GURL u2 = url2.ReplaceComponents(replacement); |
+ return (u1 == u2); |
+} |
+ |
+void LookupLoggedInStatesOnDBThread( |
+ scoped_refptr<LoggedInPredictorTable> logged_in_predictor_table, |
+ PrerenderLocalPredictor::LocalPredictorURLLookupInfo* request_) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
+ for (int i = 0; i < static_cast<int>(request_->candidate_urls_.size()); i++) { |
+ PrerenderLocalPredictor::LocalPredictorURLInfo* info = |
+ &request_->candidate_urls_[i]; |
+ if (info->url_lookup_success) { |
+ logged_in_predictor_table->HasUserLoggedIn( |
+ info->url, &info->logged_in, &info->logged_in_lookup_ok); |
+ } else { |
+ info->logged_in_lookup_ok = false; |
+ } |
+ } |
+} |
+ |
} // namespace |
-struct PrerenderLocalPredictor::PrerenderData { |
- PrerenderData(URLID url_id, const GURL& url, double priority, |
+struct PrerenderLocalPredictor::PrerenderProperties { |
+ PrerenderProperties(URLID url_id, const GURL& url, double priority, |
base::Time start_time) |
: url_id(url_id), |
url(url), |
@@ -204,13 +292,14 @@ |
base::Time actual_start_time; |
private: |
- DISALLOW_IMPLICIT_CONSTRUCTORS(PrerenderData); |
+ DISALLOW_IMPLICIT_CONSTRUCTORS(PrerenderProperties); |
}; |
PrerenderLocalPredictor::PrerenderLocalPredictor( |
PrerenderManager* prerender_manager) |
: prerender_manager_(prerender_manager), |
- is_visit_database_observer_(false) { |
+ is_visit_database_observer_(false), |
+ weak_factory_(this) { |
RecordEvent(EVENT_CONSTRUCTED); |
if (MessageLoop::current()) { |
timer_.Start(FROM_HERE, |
@@ -250,6 +339,8 @@ |
PrerenderLocalPredictor::~PrerenderLocalPredictor() { |
Shutdown(); |
+ if (prerender_handle_.get()) |
+ prerender_handle_->OnCancel(); |
} |
void PrerenderLocalPredictor::Shutdown() { |
@@ -296,9 +387,9 @@ |
std::map<URLID, int> next_urls_num_found; |
int num_occurrences_of_current_visit = 0; |
base::Time last_visited; |
- URLID best_next_url = 0; |
- int best_next_url_count = 0; |
- const std::vector<history::BriefVisitInfo>& visits = *(visit_history_.get()); |
+ scoped_ptr<LocalPredictorURLLookupInfo> lookup_info( |
+ new LocalPredictorURLLookupInfo(info.url_id)); |
+ const vector<history::BriefVisitInfo>& visits = *(visit_history_.get()); |
for (int i = 0; i < static_cast<int>(visits.size()); i++) { |
if (!ShouldExcludeTransitionForPrediction(visits[i].transition)) { |
if (visits[i].url_id == info.url_id) { |
@@ -322,73 +413,105 @@ |
next_urls_num_found.insert(std::pair<URLID, int>(*it, 0)); |
std::map<URLID, int>::iterator num_found_it = insert_ret.first; |
num_found_it->second++; |
- if (num_found_it->second > best_next_url_count) { |
- best_next_url_count = num_found_it->second; |
- best_next_url = *it; |
- } |
} |
} |
} |
- // Only consider a candidate next page for prerendering if it was viewed |
- // at least twice, and at least 10% of the time. |
- if (num_occurrences_of_current_visit > 0 && |
- best_next_url_count > 1 && |
- best_next_url_count * 10 >= num_occurrences_of_current_visit) { |
- RecordEvent(EVENT_ADD_VISIT_IDENTIFIED_PRERENDER_CANDIDATE); |
- double priority = static_cast<double>(best_next_url_count) / |
- static_cast<double>(num_occurrences_of_current_visit); |
- if (ShouldReplaceCurrentPrerender(priority)) { |
- RecordEvent(EVENT_START_URL_LOOKUP); |
- HistoryService* history = GetHistoryIfExists(); |
- if (history) { |
- history->ScheduleDBTask( |
- new GetURLForURLIDTask( |
- best_next_url, |
- base::Bind(&PrerenderLocalPredictor::OnLookupURL, |
- base::Unretained(this), |
- best_next_url, |
- priority)), |
- &history_db_consumer_); |
- } |
+ for (std::map<URLID, int>::const_iterator it = next_urls_num_found.begin(); |
+ it != next_urls_num_found.end(); |
+ ++it) { |
+ // Only consider a candidate next page for prerendering if it was viewed |
+ // at least twice, and at least 10% of the time. |
+ if (num_occurrences_of_current_visit > 0 && |
+ it->second > 1 && |
+ it->second * 10 >= num_occurrences_of_current_visit) { |
+ RecordEvent(EVENT_ADD_VISIT_IDENTIFIED_PRERENDER_CANDIDATE); |
+ double priority = static_cast<double>(it->second) / |
+ static_cast<double>(num_occurrences_of_current_visit); |
+ lookup_info->MaybeAddCandidateURL(it->first, priority); |
} |
} |
+ |
+ if (lookup_info->candidate_urls_.size() < 1) { |
Shishir
2013/05/07 22:57:30
== 0
tburkard
2013/05/07 23:21:59
Done.
|
+ RecordEvent(EVENT_NO_PRERENDER_CANDIDATES); |
+ return; |
+ } |
+ |
+ RecordEvent(EVENT_START_URL_LOOKUP); |
+ HistoryService* history = GetHistoryIfExists(); |
+ if (history) { |
+ RecordEvent(EVENT_GOT_HISTORY_ISSUING_LOOKUP); |
+ LocalPredictorURLLookupInfo* lookup_info_ptr = lookup_info.get(); |
+ history->ScheduleDBTask( |
+ new GetURLForURLIDTask( |
+ lookup_info_ptr, |
+ base::Bind(&PrerenderLocalPredictor::OnLookupURL, |
+ base::Unretained(this), |
Shishir
2013/05/07 22:57:30
unreatined? What if the predictor is deleted?
tburkard
2013/05/07 23:21:59
The use of the history_db_consumer_ will prevent a
|
+ base::Passed(&lookup_info))), |
+ &history_db_consumer_); |
+ } |
} |
-void PrerenderLocalPredictor::OnLookupURL(history::URLID url_id, |
- double priority, |
- const GURL& url) { |
+void PrerenderLocalPredictor::OnLookupURL( |
+ scoped_ptr<LocalPredictorURLLookupInfo> info) { |
RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT); |
- base::Time current_time = GetCurrentTime(); |
- if (ShouldReplaceCurrentPrerender(priority)) { |
- if (IsRootPageURL(url)) { |
- RecordEvent(EVENT_ADD_VISIT_PRERENDERING); |
- if (current_prerender_.get() && current_prerender_->url_id == url_id) { |
- RecordEvent(EVENT_ADD_VISIT_PRERENDERING_EXTENDED); |
- if (priority > current_prerender_->priority) |
- current_prerender_->priority = priority; |
- // If the prerender already existed, we want to extend it. However, |
- // we do not want to set its start_time to the current time to |
- // disadvantage PLT computations when the prerender is swapped in. |
- // So we set the new start time to current_time - 10s (since the vast |
- // majority of PLTs are < 10s), provided that is not before the actual |
- // time the prerender was started (so as to not artificially advantage |
- // the PLT computation). |
- base::Time simulated_new_start_time = |
- current_time - base::TimeDelta::FromSeconds(10); |
- if (simulated_new_start_time > current_prerender_->start_time) |
- current_prerender_->start_time = simulated_new_start_time; |
- } else { |
- current_prerender_.reset( |
- new PrerenderData(url_id, url, priority, current_time)); |
- } |
- current_prerender_->actual_start_time = current_time; |
- } else { |
- RecordEvent(EVENT_ADD_VISIT_NOT_ROOTPAGE); |
+ if (!info->source_url_.url_lookup_success || |
+ !(info->candidate_urls_.size() >= 1) || |
Shishir
2013/05/07 22:57:30
This condition cannot happen, so you can add a dch
tburkard
2013/05/07 23:21:59
Done.
|
+ !info->candidate_urls_[0].url_lookup_success) { |
Shishir
2013/05/07 22:57:30
Cant you use the second candidate if the first's l
tburkard
2013/05/07 23:21:59
Done.
|
+ RecordEvent(EVENT_PRERENDER_URL_LOOKUP_FAILED); |
+ return; |
+ } |
+ |
+ LogCandidateURLStats(info->candidate_urls_[0].url); |
+ |
+ WebContents* source_web_contents = NULL; |
+ |
+#if !defined(OS_ANDROID) |
+ for (TabContentsIterator it; !it.done(); it.Next()) { |
Shishir
2013/05/07 22:57:30
Need to document this correctly since this is not
tburkard
2013/05/07 23:21:59
Done.
|
+ if (it->GetURL() == info->source_url_.url) { |
+ source_web_contents = *it; |
+ break; |
} |
} |
+#endif |
+ if (!source_web_contents) { |
+ RecordEvent(EVENT_PRERENDER_URL_LOOKUP_NO_SOURCE_WEBCONTENTS_FOUND); |
+ return; |
+ } |
+ |
+ scoped_refptr<SessionStorageNamespace> session_storage_namespace = |
+ source_web_contents->GetController().GetDefaultSessionStorageNamespace(); |
+ |
+ gfx::Rect container_bounds; |
+ source_web_contents->GetView()->GetContainerBounds(&container_bounds); |
+ scoped_ptr<gfx::Size> size(new gfx::Size(container_bounds.size())); |
+ |
+ scoped_refptr<LoggedInPredictorTable> logged_in_table = |
+ prerender_manager_->logged_in_predictor_table(); |
+ |
+ if (!logged_in_table.get()) { |
+ RecordEvent(EVENT_PRERENDER_URL_LOOKUP_NO_LOGGED_IN_TABLE_FOUND); |
+ return; |
+ } |
+ |
+ RecordEvent(EVENT_PRERENDER_URL_LOOKUP_ISSUING_LOGGED_IN_LOOKUP); |
+ |
+ LocalPredictorURLLookupInfo* info_ptr = info.get(); |
+ BrowserThread::PostTaskAndReply( |
+ BrowserThread::DB, FROM_HERE, |
+ base::Bind(&LookupLoggedInStatesOnDBThread, |
+ logged_in_table, |
+ info_ptr), |
+ base::Bind(&PrerenderLocalPredictor::ContinuePrerenderCheck, |
+ weak_factory_.GetWeakPtr(), |
+ session_storage_namespace, |
+ base::Passed(&size), |
+ base::Passed(&info))); |
+} |
+ |
+void PrerenderLocalPredictor::LogCandidateURLStats(const GURL& url) const { |
if (url_whitelist_.count(GetInt64URLHashForURL(url)) > 0) { |
RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_ON_WHITELIST); |
if (IsRootPageURL(url)) |
@@ -404,21 +527,19 @@ |
RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_IS_HTTP); |
if (url.has_query()) |
RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_HAS_QUERY_STRING); |
- if (StrCaseStr(url.spec().c_str(), "logout") || |
- StrCaseStr(url.spec().c_str(), "signout")) |
+ if (IsLogOutURL(url)) |
RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_CONTAINS_LOGOUT); |
- if (StrCaseStr(url.spec().c_str(), "login") || |
- StrCaseStr(url.spec().c_str(), "signin")) |
+ if (IsLogInURL(url)) |
RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_CONTAINS_LOGIN); |
} |
void PrerenderLocalPredictor::OnGetInitialVisitHistory( |
- scoped_ptr<std::vector<history::BriefVisitInfo> > visit_history) { |
+ scoped_ptr<vector<history::BriefVisitInfo> > visit_history) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
DCHECK(!visit_history_.get()); |
RecordEvent(EVENT_INIT_SUCCEEDED); |
// Since the visit history has descending timestamps, we must reverse it. |
- visit_history_.reset(new std::vector<history::BriefVisitInfo>( |
+ visit_history_.reset(new vector<history::BriefVisitInfo>( |
visit_history->rbegin(), visit_history->rend())); |
} |
@@ -447,7 +568,7 @@ |
void PrerenderLocalPredictor::OnPLTEventForURL(const GURL& url, |
base::TimeDelta page_load_time) { |
- scoped_ptr<PrerenderData> prerender; |
+ scoped_ptr<PrerenderProperties> prerender; |
if (DoesPrerenderMatchPLTRecord(last_swapped_in_prerender_.get(), |
url, page_load_time)) { |
prerender.reset(last_swapped_in_prerender_.release()); |
@@ -480,7 +601,7 @@ |
} |
bool PrerenderLocalPredictor::IsPrerenderStillValid( |
- PrerenderLocalPredictor::PrerenderData* prerender) const { |
+ PrerenderLocalPredictor::PrerenderProperties* prerender) const { |
return (prerender && |
(prerender->start_time + |
base::TimeDelta::FromMilliseconds(kMaxLocalPredictionTimeMs)) |
@@ -494,7 +615,9 @@ |
} |
bool PrerenderLocalPredictor::DoesPrerenderMatchPLTRecord( |
- PrerenderData* prerender, const GURL& url, base::TimeDelta plt) const { |
+ PrerenderProperties* prerender, |
+ const GURL& url, |
+ base::TimeDelta plt) const { |
if (prerender && prerender->start_time < GetCurrentTime() - plt) { |
if (prerender->url.is_empty()) |
RecordEvent(EVENT_ERROR_NO_PRERENDER_URL_FOR_PLT); |
@@ -506,11 +629,107 @@ |
bool PrerenderLocalPredictor::ShouldReplaceCurrentPrerender( |
double priority) const { |
- base::TimeDelta max_age = |
- base::TimeDelta::FromMilliseconds(kMaxLocalPredictionTimeMs); |
- return (!current_prerender_.get()) || |
- current_prerender_->priority < priority || |
- current_prerender_->start_time < GetCurrentTime() - max_age; |
+ return (!prerender_handle_.get() || |
+ !prerender_handle_->IsPrerendering() || |
+ current_prerender_priority_ < priority); |
} |
+void PrerenderLocalPredictor::ContinuePrerenderCheck( |
+ scoped_refptr<SessionStorageNamespace> session_storage_namespace, |
+ scoped_ptr<gfx::Size> size, |
+ scoped_ptr<LocalPredictorURLLookupInfo> info) { |
+ RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_STARTED); |
+ scoped_ptr<LocalPredictorURLInfo> url_info; |
+ for (int i = 0; i < static_cast<int>(info->candidate_urls_.size()); i++) { |
+ url_info.reset(new LocalPredictorURLInfo(info->candidate_urls_[i])); |
+ if (!url_info->url_lookup_success) { |
+ RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_NO_URL); |
+ url_info.reset(NULL); |
+ continue; |
+ } |
+ if (!ShouldReplaceCurrentPrerender(url_info->priority)) { |
+ RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_PRIORITY_TOO_LOW); |
+ url_info.reset(NULL); |
+ continue; |
+ } |
+ if (URLsIdenticalIgnoringFragments(info->source_url_.url, |
+ url_info->url)) { |
+ RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_URLS_IDENTICAL_BUT_FRAGMENT); |
+ url_info.reset(NULL); |
+ continue; |
+ } |
+ if (url_info->url.SchemeIs("https")) { |
+ RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_HTTPS); |
+ url_info.reset(NULL); |
+ continue; |
+ } |
+ if (IsRootPageURL(url_info->url)) { |
+ RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ROOT_PAGE); |
+ break; |
Shishir
2013/05/07 22:57:30
Why is this case different? Documentation?
tburkard
2013/05/07 23:21:59
Done.
|
+ } |
+ if (IsLogOutURL(url_info->url)) { |
+ RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_LOGOUT_URL); |
+ url_info.reset(NULL); |
+ continue; |
+ } |
+ if (IsLogInURL(url_info->url)) { |
+ RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_LOGIN_URL); |
+ url_info.reset(NULL); |
+ continue; |
+ } |
+ if (!url_info->logged_in && url_info->logged_in_lookup_ok) { |
+ RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_NOT_LOGGED_IN); |
Shishir
2013/05/07 22:57:30
Shouldn't this be checked early?
tburkard
2013/05/07 23:21:59
Done.
tburkard
2013/05/08 00:25:27
Sorry, didn't properly reply to this. No, the loca
Shishir
2013/05/08 20:19:20
Since the sequence of checks is to a certain logic
tburkard
2013/05/08 20:35:47
Done.
|
+ break; |
+ } |
+ RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_FALLTHROUGH_NOT_PRERENDERING); |
+ url_info.reset(NULL); |
+ } |
+ if (!url_info.get()) |
+ return; |
+ RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ISSUING_PRERENDER); |
+ IssuePrerender(session_storage_namespace, size.Pass(), |
+ url_info.Pass()); |
+} |
+ |
+void PrerenderLocalPredictor::IssuePrerender( |
+ scoped_refptr<SessionStorageNamespace> session_storage_namespace, |
+ scoped_ptr<gfx::Size> size, |
+ scoped_ptr<LocalPredictorURLInfo> info) { |
+ URLID url_id = info->id; |
+ const GURL& url = info->url; |
+ double priority = info->priority; |
+ base::Time current_time = GetCurrentTime(); |
+ RecordEvent(EVENT_ISSUING_PRERENDER); |
+ |
+ current_prerender_priority_ = priority; |
+ scoped_ptr<prerender::PrerenderHandle> old_prerender_handle( |
+ prerender_handle_.release()); |
+ prerender_handle_.reset(prerender_manager_->AddPrerenderFromLocalPredictor( |
+ url, session_storage_namespace.get(), *size)); |
+ if (old_prerender_handle) |
+ old_prerender_handle->OnCancel(); |
+ |
+ RecordEvent(EVENT_ADD_VISIT_PRERENDERING); |
+ if (current_prerender_.get() && current_prerender_->url_id == url_id) { |
+ RecordEvent(EVENT_ADD_VISIT_PRERENDERING_EXTENDED); |
+ if (priority > current_prerender_->priority) |
+ current_prerender_->priority = priority; |
+ // If the prerender already existed, we want to extend it. However, |
+ // we do not want to set its start_time to the current time to |
+ // disadvantage PLT computations when the prerender is swapped in. |
+ // So we set the new start time to current_time - 10s (since the vast |
+ // majority of PLTs are < 10s), provided that is not before the actual |
+ // time the prerender was started (so as to not artificially advantage |
+ // the PLT computation). |
+ base::Time simulated_new_start_time = |
+ current_time - base::TimeDelta::FromSeconds(10); |
+ if (simulated_new_start_time > current_prerender_->start_time) |
+ current_prerender_->start_time = simulated_new_start_time; |
+ } else { |
+ current_prerender_.reset( |
+ new PrerenderProperties(url_id, url, priority, current_time)); |
+ } |
+ current_prerender_->actual_start_time = current_time; |
+} |
+ |
} // namespace prerender |