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

Unified Diff: base/metrics/field_trial.cc

Issue 6883102: Add one-time randomization support for FieldTrial, and the ability to (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 8 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: base/metrics/field_trial.cc
diff --git a/base/metrics/field_trial.cc b/base/metrics/field_trial.cc
index c1416dbce2e80a61bc188104c49780c82b9b57c2..44c56b2ec2dfc480577dd9939a1878f3d01619bf 100644
--- a/base/metrics/field_trial.cc
+++ b/base/metrics/field_trial.cc
@@ -1,11 +1,14 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/metrics/field_trial.h"
+#include "base/file_util.h"
#include "base/logging.h"
+#include "base/pickle.h"
#include "base/rand_util.h"
+#include "base/sha1.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
@@ -37,10 +40,11 @@ FieldTrial::FieldTrial(const std::string& name,
: name_(name),
divisor_(total_probability),
default_group_name_(default_group_name),
- random_(static_cast<Probability>(divisor_ * base::RandDouble())),
+ random_(static_cast<Probability>(divisor_ * RandDouble())),
accumulated_group_probability_(0),
next_group_number_(kDefaultGroupNumber+1),
- group_(kNotFinalized) {
+ group_(kNotFinalized),
+ disable_field_trial_(false) {
DCHECK_GT(total_probability, 0);
DCHECK(!default_group_name_.empty());
FieldTrialList::Register(this);
@@ -51,7 +55,7 @@ FieldTrial::FieldTrial(const std::string& name,
DCHECK_GT(day_of_month, 0);
DCHECK_LT(day_of_month, 32);
- base::Time::Exploded exploded;
+ Time::Exploded exploded;
exploded.year = year;
exploded.month = month;
exploded.day_of_week = 0; // Should be unused.
@@ -61,8 +65,26 @@ FieldTrial::FieldTrial(const std::string& name,
exploded.second = 0;
exploded.millisecond = 0;
- base::Time expiration_time = Time::FromLocalExploded(exploded);
- disable_field_trial_ = (GetBuildTime() > expiration_time) ? true : false;
+ Time expiration_time = Time::FromLocalExploded(exploded);
+ if (GetBuildTime() > expiration_time) {
+ Disable();
+ }
jar (doing other things) 2011/04/21 01:03:50 style nit: Don't bother with braces on one line if
Jói 2011/04/21 19:50:33 Done.
+}
+
+void FieldTrial::UseOneTimeRandomization(const std::string& machine_id) {
+ DCHECK_EQ(group_, kNotFinalized);
+ if (machine_id.empty()) {
+ NOTREACHED();
+ disable_field_trial_ = true;
+ return;
+ }
+
+ random_ = static_cast<Probability>(
+ divisor_ * MachineIdToUniformDouble(machine_id));
jar (doing other things) 2011/04/21 01:03:50 Is your hope to make these repeatable on a given m
Jói 2011/04/21 19:50:33 I'm now using the UMA ID and salting with the tria
+}
+
+void FieldTrial::Disable() {
+ disable_field_trial_ = true;
}
int FieldTrial::AppendGroup(const std::string& name,
@@ -80,7 +102,7 @@ int FieldTrial::AppendGroup(const std::string& name,
// This is the group that crossed the random line, so we do the assignment.
group_ = next_group_number_;
if (name.empty())
- base::StringAppendF(&group_name_, "%d", group_);
+ StringAppendF(&group_name_, "%d", group_);
else
group_name_ = name;
}
@@ -127,6 +149,28 @@ Time FieldTrial::GetBuildTime() {
return integral_build_time;
}
+// static
+double FieldTrial::MachineIdToUniformDouble(const std::string& machine_id) {
+ // We use SHA-1 over the unique ID we have for machine/user (we add
+ // the user part by adding the user's home directory). SHA-1 is designed
+ // to produce a uniformly random spread in its output space, even for
+ // nearly-identical inputs, so it helps make this data look like a uniform
+ // random distribution.
+ Pickle pickle;
+ pickle.WriteString(machine_id);
+ file_util::GetHomeDir().WriteToPickle(&pickle);
jar (doing other things) 2011/04/21 01:03:50 Pickling is a waste. It doesn't add to the entrop
Jói 2011/04/21 19:50:33 Done.
+
+ unsigned char sha1_hash[SHA1_LENGTH];
+ SHA1HashBytes(reinterpret_cast<const unsigned char*>(pickle.data()),
+ pickle.size(),
+ sha1_hash);
+
+ COMPILE_ASSERT(sizeof(uint64) < sizeof(sha1_hash), need_more_data);
+ uint64* bits = reinterpret_cast<uint64*>(&sha1_hash[0]);
+
+ return BitsToRandDouble(*bits);
+}
+
//------------------------------------------------------------------------------
// FieldTrialList methods and members.

Powered by Google App Engine
This is Rietveld 408576698