| 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) {
|
|
|