Index: base/metrics/field_trial.cc |
=================================================================== |
--- base/metrics/field_trial.cc (revision 152812) |
+++ base/metrics/field_trial.cc (working copy) |
@@ -56,34 +56,39 @@ |
FieldTrial::FieldTrial(const std::string& name, |
const Probability total_probability, |
const std::string& default_group_name) |
- : name_(name), |
- divisor_(total_probability), |
- default_group_name_(default_group_name), |
- random_(static_cast<Probability>(divisor_ * RandDouble())), |
- accumulated_group_probability_(0), |
- next_group_number_(kDefaultGroupNumber + 1), |
- group_(kNotFinalized), |
- enable_field_trial_(true), |
- forced_(false) { |
+ : name_(name), |
+ divisor_(total_probability), |
+ default_group_name_(default_group_name), |
+ random_(static_cast<Probability>(divisor_ * RandDouble())), |
+ accumulated_group_probability_(0), |
+ next_group_number_(kDefaultGroupNumber + 1), |
+ group_(kNotFinalized), |
+ enable_field_trial_(true), |
+ forced_(false) { |
DCHECK_GT(total_probability, 0); |
DCHECK(!name_.empty()); |
DCHECK(!default_group_name_.empty()); |
} |
+FieldTrial::EntropyProvider::~EntropyProvider() { |
+} |
+ |
void FieldTrial::UseOneTimeRandomization() { |
// No need to specify randomization when the group choice was forced. |
if (forced_) |
return; |
DCHECK_EQ(group_, kNotFinalized); |
DCHECK_EQ(kDefaultGroupNumber + 1, next_group_number_); |
- if (!FieldTrialList::IsOneTimeRandomizationEnabled()) { |
+ const EntropyProvider* entropy_provider = |
+ FieldTrialList::GetEntropyProviderForOneTimeRandomization(); |
+ if (!entropy_provider) { |
NOTREACHED(); |
Disable(); |
return; |
} |
random_ = static_cast<Probability>( |
- divisor_ * HashClientId(FieldTrialList::client_id(), name_)); |
+ divisor_ * entropy_provider->GetEntropyForTrial(name_)); |
} |
void FieldTrial::Disable() { |
@@ -198,27 +203,6 @@ |
DVLOG(1) << "Field trial: " << name_ << " Group choice:" << group_name_; |
} |
-// static |
-double FieldTrial::HashClientId(const std::string& client_id, |
- const std::string& trial_name) { |
- // SHA-1 is designed to produce a uniformly random spread in its output space, |
- // even for nearly-identical inputs, so it helps massage whatever client_id |
- // and trial_name we get into something with a uniform distribution, which |
- // is desirable so that we don't skew any part of the 0-100% spectrum. |
- std::string input(client_id + trial_name); |
- unsigned char sha1_hash[kSHA1Length]; |
- SHA1HashBytes(reinterpret_cast<const unsigned char*>(input.c_str()), |
- input.size(), |
- sha1_hash); |
- |
- COMPILE_ASSERT(sizeof(uint64) < sizeof(sha1_hash), need_more_data); |
- uint64 bits; |
- memcpy(&bits, sha1_hash, sizeof(bits)); |
- bits = base::ByteSwapToLE64(bits); |
- |
- return BitsToOpenEndedUnitInterval(bits); |
-} |
- |
//------------------------------------------------------------------------------ |
// FieldTrialList methods and members. |
@@ -228,9 +212,13 @@ |
// static |
bool FieldTrialList::used_without_global_ = false; |
-FieldTrialList::FieldTrialList(const std::string& client_id) |
+FieldTrialList::Observer::~Observer() { |
+} |
+ |
+FieldTrialList::FieldTrialList( |
+ const FieldTrial::EntropyProvider* entropy_provider) |
: application_start_time_(TimeTicks::Now()), |
- client_id_(client_id), |
+ entropy_provider_(entropy_provider), |
observer_list_(new ObserverListThreadSafe<FieldTrialList::Observer>( |
ObserverListBase<FieldTrialList::Observer>::NOTIFY_EXISTING_ONLY)) { |
DCHECK(!global_); |
@@ -446,22 +434,19 @@ |
} |
// static |
-bool FieldTrialList::IsOneTimeRandomizationEnabled() { |
+const FieldTrial::EntropyProvider* |
+ FieldTrialList::GetEntropyProviderForOneTimeRandomization() { |
if (!global_) { |
used_without_global_ = true; |
- return false; |
+ return NULL; |
} |
- return !global_->client_id_.empty(); |
+ return global_->entropy_provider_.get(); |
} |
// static |
-const std::string& FieldTrialList::client_id() { |
- DCHECK(global_); |
- if (!global_) |
- return EmptyString(); |
- |
- return global_->client_id_; |
+bool FieldTrialList::IsOneTimeRandomizationEnabled() { |
+ return GetEntropyProviderForOneTimeRandomization() != NULL; |
} |
FieldTrial* FieldTrialList::PreLockedFind(const std::string& name) { |