summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgavinp@chromium.org <gavinp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-27 16:56:45 +0000
committergavinp@chromium.org <gavinp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-27 16:56:45 +0000
commit47f17f7dd6c6718e98ab9c6f1e970cd6d526b18d (patch)
tree7e2136f085b79f9289cd7454de45fca2b8224655
parent70ebea88dc660be8bd16c3fff01c8147197ae81e (diff)
downloadchromium_src-47f17f7dd6c6718e98ab9c6f1e970cd6d526b18d.zip
chromium_src-47f17f7dd6c6718e98ab9c6f1e970cd6d526b18d.tar.gz
chromium_src-47f17f7dd6c6718e98ab9c6f1e970cd6d526b18d.tar.bz2
Make three simultanious prerenders the default maximum in Canary and Dev only.
Very basic support for three simultanious prerenders, as a basis for continued updates on the API. R=dominich@chromium.org BUG=None Review URL: https://chromiumcodereview.appspot.com/10802024 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148761 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/prerender/prerender_browsertest.cc16
-rw-r--r--chrome/browser/prerender/prerender_config.cc2
-rw-r--r--chrome/browser/prerender/prerender_config.h5
-rw-r--r--chrome/browser/prerender/prerender_field_trial.cc25
-rw-r--r--chrome/browser/prerender/prerender_histograms.cc13
-rw-r--r--chrome/browser/prerender/prerender_histograms.h4
-rw-r--r--chrome/browser/prerender/prerender_manager.cc17
-rw-r--r--chrome/browser/prerender/prerender_manager.h5
-rw-r--r--chrome/browser/prerender/prerender_unittest.cc104
9 files changed, 116 insertions, 75 deletions
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
index cdc8a99..52b77cc 100644
--- a/chrome/browser/prerender/prerender_browsertest.cc
+++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -235,8 +235,8 @@ class TestPrerenderContents : public PrerenderContents {
virtual void AddPendingPrerender(
base::WeakPtr<PrerenderHandle> weak_prerender_handle,
const GURL& url,
- const content::Referrer& referrer,
- const gfx::Size& size) OVERRIDE {
+ const content::Referrer& referrer,
+ const gfx::Size& size) OVERRIDE {
PrerenderContents::AddPendingPrerender(
weak_prerender_handle, url, referrer, size);
if (expected_pending_prerenders_ > 0 &&
@@ -1524,12 +1524,13 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderInfiniteLoopMultiple) {
const char* const kHtmlFileC =
"files/prerender/prerender_infinite_c_multiple.html";
- // We need to set the final status to expect here before starting any
- // prerenders. We set them on a queue so whichever we see first is expected to
- // be evicted, and the second should stick around until we exit.
+ // This test is conceptually simplest if concurrency is at two, since we
+ // don't have to worry about which of kHtmlFileB or kHtmlFileC gets evicted.
+ GetPrerenderManager()->mutable_config().max_concurrency = 2;
+
std::deque<FinalStatus> expected_final_status_queue;
expected_final_status_queue.push_back(FINAL_STATUS_USED);
- expected_final_status_queue.push_back(FINAL_STATUS_EVICTED);
+ expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1);
@@ -1549,8 +1550,7 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderInfiniteLoopMultiple) {
// active entry.
bool url_b_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileB);
bool url_c_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileC);
- EXPECT_TRUE((url_b_is_active_prerender || url_c_is_active_prerender) &&
- !(url_b_is_active_prerender && url_c_is_active_prerender));
+ EXPECT_TRUE(url_b_is_active_prerender && url_c_is_active_prerender);
EXPECT_FALSE(UrlIsPending(kHtmlFileB));
EXPECT_FALSE(UrlIsPending(kHtmlFileC));
}
diff --git a/chrome/browser/prerender/prerender_config.cc b/chrome/browser/prerender/prerender_config.cc
index f409918..43f34d9 100644
--- a/chrome/browser/prerender/prerender_config.cc
+++ b/chrome/browser/prerender/prerender_config.cc
@@ -7,7 +7,7 @@
namespace prerender {
Config::Config() : max_bytes(100 * 1024 * 1024),
- max_elements(1),
+ max_concurrency(1),
rate_limit_enabled(true),
max_age(base::TimeDelta::FromSeconds(30)),
https_allowed(true),
diff --git a/chrome/browser/prerender/prerender_config.h b/chrome/browser/prerender/prerender_config.h
index 04f244b..70f609a 100644
--- a/chrome/browser/prerender/prerender_config.h
+++ b/chrome/browser/prerender/prerender_config.h
@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_PRERENDER_PRERENDER_CONFIG_H_
#define CHROME_BROWSER_PRERENDER_PRERENDER_CONFIG_H_
+#include <string>
+
#include "base/time.h"
#include "ui/gfx/rect.h"
@@ -17,7 +19,7 @@ struct Config {
size_t max_bytes;
// Number of simultaneous prendered pages allowed.
- unsigned int max_elements;
+ size_t max_concurrency;
// Is rate limiting enabled?
bool rate_limit_enabled;
@@ -42,3 +44,4 @@ struct Config {
} // namespace prerender
#endif // CHROME_BROWSER_PRERENDER_PRERENDER_CONFIG_H_
+
diff --git a/chrome/browser/prerender/prerender_field_trial.cc b/chrome/browser/prerender/prerender_field_trial.cc
index 1d48b47..60ce6a3 100644
--- a/chrome/browser/prerender/prerender_field_trial.cc
+++ b/chrome/browser/prerender/prerender_field_trial.cc
@@ -52,6 +52,7 @@ void SetupPrerenderFieldTrial() {
const FieldTrial::Probability divisor = 1000;
FieldTrial::Probability control_probability;
+ FieldTrial::Probability experiment_multi_prerender_probability;
FieldTrial::Probability experiment_5min_ttl_probability;
FieldTrial::Probability experiment_no_use_probability;
@@ -61,30 +62,40 @@ void SetupPrerenderFieldTrial() {
// Use very conservatives and stable settings in beta and stable.
const FieldTrial::Probability release_prerender_enabled_probability = 980;
const FieldTrial::Probability release_control_probability = 10;
+ const FieldTrial::Probability
+ release_experiment_multi_prerender_probability = 0;
const FieldTrial::Probability release_experiment_5min_ttl_probability = 10;
const FieldTrial::Probability release_experiment_no_use_probability = 0;
COMPILE_ASSERT(
release_prerender_enabled_probability + release_control_probability +
+ release_experiment_multi_prerender_probability +
release_experiment_5min_ttl_probability +
release_experiment_no_use_probability == divisor,
release_experiment_probabilities_must_equal_divisor);
control_probability = release_experiment_5min_ttl_probability;
+ experiment_multi_prerender_probability =
+ release_experiment_multi_prerender_probability;
experiment_5min_ttl_probability = release_control_probability;
experiment_no_use_probability = release_experiment_no_use_probability;
} else {
// In testing channels, use more experiments and a larger control group to
// improve quality of data.
- const FieldTrial::Probability dev_prerender_enabled_probability = 333;
- const FieldTrial::Probability dev_control_probability = 333;
- const FieldTrial::Probability dev_experiment_5min_ttl_probability = 167;
- const FieldTrial::Probability dev_experiment_no_use_probability = 167;
+ const FieldTrial::Probability dev_prerender_enabled_probability = 250;
+ const FieldTrial::Probability dev_control_probability = 250;
+ const FieldTrial::Probability
+ dev_experiment_multi_prerender_probability = 250;
+ const FieldTrial::Probability dev_experiment_5min_ttl_probability = 125;
+ const FieldTrial::Probability dev_experiment_no_use_probability = 125;
COMPILE_ASSERT(dev_prerender_enabled_probability + dev_control_probability +
+ dev_experiment_multi_prerender_probability +
dev_experiment_5min_ttl_probability +
dev_experiment_no_use_probability == divisor,
dev_experiment_probabilities_must_equal_divisor);
control_probability = dev_experiment_5min_ttl_probability;
+ experiment_multi_prerender_probability =
+ dev_experiment_multi_prerender_probability;
experiment_5min_ttl_probability = dev_control_probability;
experiment_no_use_probability = dev_experiment_no_use_probability;
}
@@ -97,6 +108,9 @@ void SetupPrerenderFieldTrial() {
const int control_group =
trial->AppendGroup("PrerenderControl",
control_probability);
+ const int experiment_multi_prerender_group =
+ trial->AppendGroup("PrerenderMulti",
+ experiment_multi_prerender_probability);
const int experiment_5_min_TTL_group =
trial->AppendGroup("Prerender5minTTL",
experiment_5min_ttl_probability);
@@ -111,6 +125,9 @@ void SetupPrerenderFieldTrial() {
} else if (trial_group == control_group) {
PrerenderManager::SetMode(
PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
+ } else if (trial_group == experiment_multi_prerender_group) {
+ PrerenderManager::SetMode(
+ PrerenderManager::PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP);
} else if (trial_group == experiment_5_min_TTL_group) {
PrerenderManager::SetMode(
PrerenderManager::PRERENDER_MODE_EXPERIMENT_5MIN_TTL_GROUP);
diff --git a/chrome/browser/prerender/prerender_histograms.cc b/chrome/browser/prerender/prerender_histograms.cc
index a79c637..657d0f6 100644
--- a/chrome/browser/prerender/prerender_histograms.cc
+++ b/chrome/browser/prerender/prerender_histograms.cc
@@ -6,6 +6,7 @@
#include <string>
+#include "base/format_macros.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/stringprintf.h"
@@ -156,6 +157,18 @@ void PrerenderHistograms::RecordPrerenderStarted(Origin origin) const {
}
}
+void PrerenderHistograms::RecordConcurrency(size_t prerender_count) const {
+ static const size_t kMaxRecordableConcurrency = 3;
+ const size_t max_concurrency = PrerenderManager::GetMaxConcurrency();
+ DCHECK_GE(kMaxRecordableConcurrency, max_concurrency);
+ if (max_concurrency > 1) {
+ UMA_HISTOGRAM_ENUMERATION(
+ StringPrintf("Prerender.PrerenderCountOf%" PRIuS "Max",
+ max_concurrency),
+ prerender_count, kMaxRecordableConcurrency + 1);
+ }
+}
+
void PrerenderHistograms::RecordUsedPrerender(Origin origin) const {
if (OriginIsOmnibox(origin)) {
UMA_HISTOGRAM_ENUMERATION(
diff --git a/chrome/browser/prerender/prerender_histograms.h b/chrome/browser/prerender/prerender_histograms.h
index 9e10541..61ca823 100644
--- a/chrome/browser/prerender/prerender_histograms.h
+++ b/chrome/browser/prerender/prerender_histograms.h
@@ -79,6 +79,10 @@ class PrerenderHistograms {
// To be called when a new prerender is started.
void RecordPrerenderStarted(Origin origin) const;
+ // To be called when we know how many prerenders are running after starting
+ // a prerender.
+ void RecordConcurrency(size_t prerender_count) const;
+
// Called when we swap in a prerender.
void RecordUsedPrerender(Origin origin) const;
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc
index 5e7b4c6b..736792b 100644
--- a/chrome/browser/prerender/prerender_manager.cc
+++ b/chrome/browser/prerender/prerender_manager.cc
@@ -69,9 +69,6 @@ const int kWindowDurationSeconds = 30;
// Time interval at which periodic cleanups are performed.
const int kPeriodicCleanupIntervalMs = 1000;
-// Time interval before a new prerender is allowed.
-const int kMinTimeBetweenPrerendersMs = 500;
-
// Valid HTTP methods for prerendering.
const char* const kValidHttpMethods[] = {
"GET",
@@ -196,6 +193,7 @@ PrerenderManager::PrerenderManager(Profile* profile,
// Any other checks simply make sure that the PrerenderManager is accessed on
// the same thread that it was created on.
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ config_.max_concurrency = GetMaxConcurrency();
}
PrerenderManager::~PrerenderManager() {
@@ -555,6 +553,8 @@ const char* PrerenderManager::GetModeString() {
return "_Enabled";
case PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP:
return "_Control";
+ case PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP:
+ return "_Multi";
case PRERENDER_MODE_EXPERIMENT_5MIN_TTL_GROUP:
return "_5MinTTL";
case PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP:
@@ -586,6 +586,13 @@ bool PrerenderManager::IsNoUseGroup() {
return GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP;
}
+// static
+size_t PrerenderManager::GetMaxConcurrency() {
+ if (GetMode() == PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP)
+ return 3;
+ return 1;
+}
+
bool PrerenderManager::IsWebContentsPrerendering(
WebContents* web_contents) const {
DCHECK(CalledOnValidThread());
@@ -945,12 +952,14 @@ PrerenderHandle* PrerenderManager::AddPrerender(
session_storage_namespace,
control_group_behavior);
- while (active_prerender_list_.size() > config_.max_elements) {
+ while (active_prerender_list_.size() > config_.max_concurrency) {
prerender_contents = active_prerender_list_.front()->contents_;
DCHECK(prerender_contents);
prerender_contents->Destroy(FINAL_STATUS_EVICTED);
}
+ histograms_->RecordConcurrency(active_prerender_list_.size());
+
StartSchedulingPeriodicCleanups();
return prerender_handle;
}
diff --git a/chrome/browser/prerender/prerender_manager.h b/chrome/browser/prerender/prerender_manager.h
index 3341572..edada5a 100644
--- a/chrome/browser/prerender/prerender_manager.h
+++ b/chrome/browser/prerender/prerender_manager.h
@@ -78,6 +78,7 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP,
PRERENDER_MODE_EXPERIMENT_5MIN_TTL_GROUP,
PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP,
+ PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP,
PRERENDER_MODE_MAX
};
@@ -176,6 +177,7 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
static bool ActuallyPrerendering();
static bool IsControlGroup();
static bool IsNoUseGroup();
+ static size_t GetMaxConcurrency();
// Query the list of current prerender pages to see if the given web contents
// is prerendering a page.
@@ -313,6 +315,9 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
typedef base::hash_map<content::WebContents*, bool> WouldBePrerenderedMap;
+ // Time interval before a new prerender is allowed.
+ static const int kMinTimeBetweenPrerendersMs = 500;
+
// Time window for which we record old navigations, in milliseconds.
static const int kNavigationRecordWindowMs = 5000;
diff --git a/chrome/browser/prerender/prerender_unittest.cc b/chrome/browser/prerender/prerender_unittest.cc
index 07684df..d5639af 100644
--- a/chrome/browser/prerender/prerender_unittest.cc
+++ b/chrome/browser/prerender/prerender_unittest.cc
@@ -5,6 +5,7 @@
#include "base/command_line.h"
#include "base/memory/scoped_vector.h"
#include "base/message_loop.h"
+#include "base/stringprintf.h"
#include "base/time.h"
#include "chrome/browser/prerender/prerender_contents.h"
#include "chrome/browser/prerender/prerender_handle.h"
@@ -74,6 +75,7 @@ const gfx::Size kSize(640, 480);
class UnitTestPrerenderManager : public PrerenderManager {
public:
+ using PrerenderManager::kMinTimeBetweenPrerendersMs;
using PrerenderManager::kNavigationRecordWindowMs;
using PrerenderManager::GetMaxAge;
@@ -386,67 +388,50 @@ TEST_F(PrerenderTest, ExpireTest) {
ASSERT_EQ(null, prerender_manager()->FindEntry(url));
}
-// LRU Test. Make sure that if we prerender more than one request, that
+// LRU Test. Make sure that if we prerender more requests than we support, that
// the oldest one will be dropped.
TEST_F(PrerenderTest, DropOldestRequestTest) {
- GURL url("http://www.google.com/");
- DummyPrerenderContents* prerender_contents =
- prerender_manager()->CreateNextPrerenderContents(
- url,
- FINAL_STATUS_EVICTED);
- DummyPrerenderContents* null = NULL;
- EXPECT_TRUE(AddSimplePrerender(url));
- EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
- EXPECT_TRUE(prerender_contents->prerendering_has_started());
-
- GURL url1("http://news.google.com/");
- DummyPrerenderContents* prerender_contents1 =
- prerender_manager()->CreateNextPrerenderContents(
- url1,
- FINAL_STATUS_USED);
- EXPECT_TRUE(AddSimplePrerender(url1));
- EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
- EXPECT_TRUE(prerender_contents1->prerendering_has_started());
-
- ASSERT_EQ(null, prerender_manager()->FindEntry(url));
- ASSERT_EQ(prerender_contents1, prerender_manager()->FindAndUseEntry(url1));
-}
+ std::vector<int> concurrencies_to_test;
+ concurrencies_to_test.push_back(
+ prerender_manager()->config().max_concurrency);
+ concurrencies_to_test.push_back(1);
+ concurrencies_to_test.push_back(2);
-// Two element prerender test. Ensure that the LRU operates correctly if we
-// permit 2 elements to be kept prerendered.
-TEST_F(PrerenderTest, TwoElementPrerenderTest) {
- prerender_manager()->mutable_config().max_elements = 2;
- GURL url("http://www.google.com/");
- DummyPrerenderContents* prerender_contents =
- prerender_manager()->CreateNextPrerenderContents(
- url,
- FINAL_STATUS_EVICTED);
DummyPrerenderContents* null = NULL;
- EXPECT_TRUE(AddSimplePrerender(url));
- EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
- EXPECT_TRUE(prerender_contents->prerendering_has_started());
-
- GURL url1("http://news.google.com/");
- DummyPrerenderContents* prerender_contents1 =
- prerender_manager()->CreateNextPrerenderContents(
- url1,
- FINAL_STATUS_USED);
- EXPECT_TRUE(AddSimplePrerender(url1));
- EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
- EXPECT_TRUE(prerender_contents1->prerendering_has_started());
-
- GURL url2("http://images.google.com/");
- DummyPrerenderContents* prerender_contents2 =
- prerender_manager()->CreateNextPrerenderContents(
- url2,
- FINAL_STATUS_USED);
- EXPECT_TRUE(AddSimplePrerender(url2));
- EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
- EXPECT_TRUE(prerender_contents2->prerendering_has_started());
+ GURL url_to_evict("http://www.google.com/evictme");
+
+ for (std::vector<int>::const_iterator i = concurrencies_to_test.begin();
+ i != concurrencies_to_test.end();
+ ++i) {
+ const int max_concurrency = *i;
+ prerender_manager()->mutable_config().max_concurrency = max_concurrency;
+
+ DummyPrerenderContents* prerender_contents_to_evict =
+ prerender_manager()->CreateNextPrerenderContents(
+ url_to_evict, FINAL_STATUS_EVICTED);
+ EXPECT_TRUE(AddSimplePrerender(url_to_evict));
+ EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
+ EXPECT_TRUE(prerender_contents_to_evict->prerendering_has_started());
+
+ std::vector<GURL> urls;
+ std::vector<PrerenderContents*> prerender_contentses;
+
+ for (int j = 0; j < max_concurrency; ++j) {
+ urls.push_back(GURL(base::StringPrintf("http://google.com/use#%d", j)));
+ prerender_contentses.push_back(
+ prerender_manager()->CreateNextPrerenderContents(urls.back(),
+ FINAL_STATUS_USED));
+ EXPECT_TRUE(AddSimplePrerender(urls.back()));
+ EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
+ EXPECT_TRUE(prerender_contentses.back()->prerendering_has_started());
+ }
- ASSERT_EQ(null, prerender_manager()->FindEntry(url));
- ASSERT_EQ(prerender_contents1, prerender_manager()->FindAndUseEntry(url1));
- ASSERT_EQ(prerender_contents2, prerender_manager()->FindAndUseEntry(url2));
+ ASSERT_EQ(null, prerender_manager()->FindEntry(url_to_evict));
+ for (int j = 0; j < max_concurrency; ++j) {
+ ASSERT_EQ(prerender_contentses[j],
+ prerender_manager()->FindAndUseEntry(urls[j]));
+ }
+ }
}
TEST_F(PrerenderTest, AliasURLTest) {
@@ -511,6 +496,10 @@ TEST_F(PrerenderTest, RateLimitInWindowTest) {
// Ensure that we don't ignore prerender requests outside the rate limit.
TEST_F(PrerenderTest, RateLimitOutsideWindowTest) {
+ // Setting concurrency to one lets us force eviction by adding only one more
+ // prerender.
+ prerender_manager()->mutable_config().max_concurrency = 1;
+
GURL url("http://www.google.com/");
DummyPrerenderContents* prerender_contents =
prerender_manager()->CreateNextPrerenderContents(
@@ -523,7 +512,8 @@ TEST_F(PrerenderTest, RateLimitOutsideWindowTest) {
prerender_manager()->set_rate_limit_enabled(true);
prerender_manager()->AdvanceTimeTicks(
- base::TimeDelta::FromMilliseconds(2000));
+ base::TimeDelta::FromMilliseconds(
+ UnitTestPrerenderManager::kMinTimeBetweenPrerendersMs + 500));
GURL url1("http://news.google.com/");
DummyPrerenderContents* rate_limit_prerender_contents =