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

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

Issue 7289020: Updating histograms to allow for experiments & log origin-based histograms. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 6 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_manager.cc
===================================================================
--- chrome/browser/prerender/prerender_manager.cc (revision 91002)
+++ chrome/browser/prerender/prerender_manager.cc (working copy)
@@ -78,6 +78,36 @@
} // namespace
+// Helper macros for experiment-based and origin-based histogram reporting.
+#define PREFIXED_HISTOGRAM(histogram) \
+ PREFIXED_HISTOGRAM_INTERNAL(GetCurrentOrigin(), GetCurrentExperimentId(), \
+ IsOriginExperimentWash(), histogram)
+
+#define PREFIXED_HISTOGRAM_PRERENDER_MANAGER(pm, histogram) \
+ PREFIXED_HISTOGRAM_INTERNAL(pm->GetCurrentOrigin(), \
+ pm->GetCurrentExperimentId(), \
+ pm->IsOriginExperimentWash(), histogram)
+
+#define PREFIXED_HISTOGRAM_ORIGIN_EXPERIMENT(origin, experiment, histogram) \
+ PREFIXED_HISTOGRAM_INTERNAL(origin, experiment, false, histogram)
+
+#define PREFIXED_HISTOGRAM_INTERNAL(origin, experiment, wash, histogram) { \
+ static char experiment_id = kNoExperiment; \
dominich.google 2011/06/30 19:55:15 This should be a uint8 now. If you have two histo
tburkard 2011/06/30 21:40:20 Done.
+ if (experiment_id == kNoExperiment && experiment != kNoExperiment) \
+ experiment_id = experiment; \
+ if (wash || \
+ (experiment != kNoExperiment && (origin != ORIGIN_LINK_REL_PRERENDER || \
+ experiment != experiment_id))) { \
+ histogram; \
+ } else if (experiment != kNoExperiment) { \
+ histogram; \
+ } else if (origin == ORIGIN_OMNIBOX) { \
+ histogram; \
+ } else { \
+ histogram; \
+ } \
+}
+
class PrerenderManager::OnCloseTabContentsDeleter : public TabContentsDelegate {
public:
OnCloseTabContentsDeleter(PrerenderManager* manager,
@@ -176,6 +206,29 @@
}
// static
+uint8 PrerenderManager::GetQueryStringBasedExperiment(const GURL& url) {
+ url_parse::Parsed parsed;
+ url_parse::ParseStandardURL(url.spec().c_str(), url.spec().length(),
+ &parsed);
+ url_parse::Component query = parsed.query;
+ url_parse::Component key, value;
+ while (url_parse::ExtractQueryKeyValue(url.spec().c_str(), &query, &key,
+ &value)) {
+ if (key.len != 3 || strncmp(url.spec().c_str() + key.begin, "lpe", key.len))
+ continue;
+
+ // We found a lpe= query string component.
+ if (value.len != 1)
+ continue;
+ uint8 exp = *(url.spec().c_str() + value.begin) - '0';
+ if (exp < 1 || exp > 9)
+ continue;
+ return exp;
+ }
+ return kNoExperiment;
+}
+
+// static
bool PrerenderManager::IsValidHttpMethod(const std::string& method) {
// method has been canonicalized to upper case at this point so we can just
// compare them.
@@ -229,6 +282,9 @@
max_prerender_memory_mb_(kDefaultMaxPrerenderMemoryMB),
max_elements_(kDefaultMaxPrerenderElements),
prerender_contents_factory_(PrerenderContents::CreateFactory()),
+ last_experiment_id_(kNoExperiment),
+ last_origin_(ORIGIN_LINK_REL_PRERENDER),
+ origin_experiment_wash_(false),
last_prerender_start_time_(GetCurrentTimeTicks() -
base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs)),
runnable_method_factory_(this),
@@ -275,6 +331,26 @@
const GURL& referrer) {
DCHECK(CalledOnValidThread());
+ // Check if we are doing an experiment.
+ uint8 experiment = PrerenderManager::GetQueryStringBasedExperiment(url_arg);
+
+ // We need to update last_experiment_id_, last_origin_, and
+ // origin_experiment_wash_.
+ if (!WithinWindow()) {
+ // If we are outside a window, this is a fresh start and we are fine,
+ // and there is no mix.
+ origin_experiment_wash_ = false;
+ } else {
+ // If we are inside the last window, there is a mish mash of origins
+ // and experiments if either there was a mish mash before, or the current
+ // experiment/origin does not match the previous one.
+ if (experiment != last_experiment_id_ || origin != last_origin_)
+ origin_experiment_wash_ = true;
+ }
+
+ last_origin_ = origin;
+ last_experiment_id_ = experiment;
+
// If we observe multiple tags within the 30 second window, we will still
// reset the window to begin at the most recent occurrence, so that we will
// always be in a window in the 30 seconds from each occurrence.
@@ -311,7 +387,7 @@
// case, when a new tab is added to a process used for prerendering.
if (RenderProcessHost::ShouldTryToUseExistingProcessHost() &&
!RenderProcessHost::run_renderer_in_process()) {
- RecordFinalStatus(origin, FINAL_STATUS_TOO_MANY_PROCESSES);
+ RecordFinalStatus(origin, experiment, FINAL_STATUS_TOO_MANY_PROCESSES);
return false;
}
@@ -320,7 +396,7 @@
// Cancel the prerender. We could add it to the pending prerender list but
// this doesn't make sense as the next prerender request will be triggered
// by a navigation and is unlikely to be the same site.
- RecordFinalStatus(origin, FINAL_STATUS_RATE_LIMIT_EXCEEDED);
+ RecordFinalStatus(origin, experiment, FINAL_STATUS_RATE_LIMIT_EXCEEDED);
return false;
}
@@ -333,13 +409,14 @@
// Don't prerender page if parent RenderViewHost no longer exists, or it has
// no view. The latter should only happen when the RenderView has closed.
if (!source_render_view_host || !source_render_view_host->view()) {
- RecordFinalStatus(origin, FINAL_STATUS_SOURCE_RENDER_VIEW_CLOSED);
+ RecordFinalStatus(origin, experiment,
+ FINAL_STATUS_SOURCE_RENDER_VIEW_CLOSED);
return false;
}
}
PrerenderContents* prerender_contents =
- CreatePrerenderContents(url, referrer, origin);
+ CreatePrerenderContents(url, referrer, origin, experiment);
if (!prerender_contents || !prerender_contents->Init())
return false;
@@ -509,8 +586,9 @@
RecordTimeUntilUsed(GetCurrentTimeTicks() -
prerender_contents->load_start_time());
- UMA_HISTOGRAM_COUNTS("Prerender.PrerendersPerSessionCount",
- ++prerenders_per_session_count_);
+ PREFIXED_HISTOGRAM(UMA_HISTOGRAM_COUNTS(
+ GetDefaultHistogramName("Prerender.PrerendersPerSessionCount"),
+ ++prerenders_per_session_count_));
prerender_contents->set_final_status(FINAL_STATUS_USED);
RenderViewHost* render_view_host =
@@ -620,10 +698,11 @@
PrerenderContents* PrerenderManager::CreatePrerenderContents(
const GURL& url,
const GURL& referrer,
- Origin origin) {
+ Origin origin,
+ uint8 experiment_id) {
DCHECK(CalledOnValidThread());
return prerender_contents_factory_->CreatePrerenderContents(
- this, prerender_tracker_, profile_, url, referrer, origin);
+ this, prerender_tracker_, profile_, url, referrer, origin, experiment_id);
}
bool PrerenderManager::IsPendingDelete(PrerenderContents* entry) const {
@@ -650,14 +729,15 @@
// Helper macro for histograms.
#define RECORD_PLT(tag, perceived_page_load_time) { \
+ PREFIXED_HISTOGRAM_PRERENDER_MANAGER(prerender_manager, \
UMA_HISTOGRAM_CUSTOM_TIMES( \
- base::FieldTrial::MakeName(std::string("Prerender.") + tag, \
- "Prefetch"), \
+ base::FieldTrial::MakeName( \
+ prerender_manager->GetDefaultHistogramName(tag), "Prefetch"), \
perceived_page_load_time, \
base::TimeDelta::FromMilliseconds(10), \
base::TimeDelta::FromSeconds(60), \
- 100); \
- }
+ 100)); \
+}
// static
void PrerenderManager::RecordPerceivedPageLoadTime(
@@ -785,8 +865,10 @@
DCHECK(CalledOnValidThread());
base::TimeDelta elapsed_time =
GetCurrentTimeTicks() - last_prerender_start_time_;
- UMA_HISTOGRAM_TIMES("Prerender.TimeBetweenPrerenderRequests",
- elapsed_time);
+ PREFIXED_HISTOGRAM(
+ UMA_HISTOGRAM_TIMES(
+ GetDefaultHistogramName("Prerender.TimeBetweenPrerenderRequests"),
+ elapsed_time));
if (!rate_limit_enabled_)
return true;
return elapsed_time >
@@ -1026,12 +1108,85 @@
void PrerenderManager::RecordTimeUntilUsed(base::TimeDelta time_until_used) {
DCHECK(CalledOnValidThread());
- UMA_HISTOGRAM_CUSTOM_TIMES(
- "Prerender.TimeUntilUsed",
+ PREFIXED_HISTOGRAM(UMA_HISTOGRAM_CUSTOM_TIMES(
+ GetDefaultHistogramName("Prerender.TimeUntilUsed"),
time_until_used,
base::TimeDelta::FromMilliseconds(10),
base::TimeDelta::FromSeconds(kDefaultMaxPrerenderAgeSeconds),
- 50);
+ 50));
}
+void PrerenderManager::RecordFinalStatus(Origin origin,
+ uint8 experiment_id,
+ FinalStatus final_status) const {
+ DCHECK(final_status != FINAL_STATUS_MAX);
+ // FINAL_STATUS_CONTROL_GROUP indicates that the PrerenderContents
+ // was created only to measure "would-have-been-prerendered" for
+ // control group measurements. Don't pollute data with it.
+ if (PrerenderManager::IsControlGroup() ||
+ final_status == FINAL_STATUS_CONTROL_GROUP)
+ return;
+ PREFIXED_HISTOGRAM_ORIGIN_EXPERIMENT(origin, experiment_id,
+ UMA_HISTOGRAM_ENUMERATION(
+ GetHistogramName(origin, experiment_id, "FinalStatus"),
+ final_status,
+ FINAL_STATUS_MAX));
+}
+
+std::string PrerenderManager::ComposeHistogramName(std::string prefix_type,
dominich.google 2011/06/30 19:55:15 const references here
tburkard 2011/06/30 21:40:20 Done.
+ std::string name) const {
+ if (prefix_type.empty())
+ return std::string("Prerender.") + name;
+ return std::string("Prerender.") + prefix_type + std::string("_") + name;
+}
+
+std::string PrerenderManager::GetHistogramName(Origin origin,
+ uint8 experiment_id,
+ std::string name) const{
dominich.google 2011/06/30 19:55:15 const reference.
tburkard 2011/06/30 21:40:20 Done.
+ switch (origin) {
+ case ORIGIN_OMNIBOX:
+ if (experiment_id != kNoExperiment)
+ return ComposeHistogramName("wash", name);
+ return ComposeHistogramName("omnibox", name);
+ case ORIGIN_LINK_REL_PRERENDER:
+ if (experiment_id == kNoExperiment)
+ return ComposeHistogramName("", name);
+ return ComposeHistogramName("exp" + std::string(1, experiment_id + '0'),
+ name);
+ default:
+ NOTREACHED();
+ break;
+ };
+
+ // Dummy return value to make the compiler happy.
+ NOTREACHED();
+ return ComposeHistogramName("wash", name);
+}
+
+std::string PrerenderManager::GetDefaultHistogramName(std::string name) const {
dominich.google 2011/06/30 19:55:15 const reference.
tburkard 2011/06/30 21:40:20 Done.
+ if (!WithinWindow())
+ return ComposeHistogramName("", name);
+ if (origin_experiment_wash_)
+ return ComposeHistogramName("wash", name);
+ return GetHistogramName(last_origin_, last_experiment_id_, name);
+}
+
+uint8 PrerenderManager::GetCurrentExperimentId() const {
+ if (!WithinWindow())
+ return kNoExperiment;
+ return last_experiment_id_;
+}
+
+Origin PrerenderManager::GetCurrentOrigin() const {
+ if (!WithinWindow())
+ return ORIGIN_LINK_REL_PRERENDER;
+ return last_origin_;
+}
+
+bool PrerenderManager::IsOriginExperimentWash() const {
+ if (!WithinWindow())
+ return false;
+ return origin_experiment_wash_;
+}
+
} // namespace prerender

Powered by Google App Engine
This is Rietveld 408576698