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

Unified Diff: chrome/browser/prerender/prerender_local_predictor.cc

Issue 15021007: Do conservative prerendering based on the LocalPredictor in Dev/Canary. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 7 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 side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698