| Index: base/metrics/field_trial.cc
|
| ===================================================================
|
| --- base/metrics/field_trial.cc (revision 71223)
|
| +++ base/metrics/field_trial.cc (working copy)
|
| @@ -7,14 +7,18 @@
|
| #include "base/logging.h"
|
| #include "base/rand_util.h"
|
| #include "base/stringprintf.h"
|
| +#include "base/utf_string_conversions.h"
|
|
|
| +using base::Time;
|
| +using base::TimeDelta;
|
| +
|
| namespace base {
|
|
|
| // static
|
| -const int FieldTrial::kNotParticipating = -1;
|
| +const int FieldTrial::kNotFinalized = -1;
|
|
|
| // static
|
| -const int FieldTrial::kAllRemainingProbability = -2;
|
| +const int FieldTrial::kDefaultGroupNumber = 0;
|
|
|
| // static
|
| bool FieldTrial::enable_benchmarking_ = false;
|
| @@ -28,30 +32,74 @@
|
| // FieldTrial methods and members.
|
|
|
| FieldTrial::FieldTrial(const std::string& name,
|
| - const Probability total_probability)
|
| + const Probability total_probability,
|
| + const std::string& default_group_name,
|
| + const int year,
|
| + const int month,
|
| + const int day_of_month)
|
| : name_(name),
|
| divisor_(total_probability),
|
| + default_group_name_(default_group_name),
|
| random_(static_cast<Probability>(divisor_ * base::RandDouble())),
|
| accumulated_group_probability_(0),
|
| - next_group_number_(0),
|
| - group_(kNotParticipating) {
|
| + next_group_number_(kDefaultGroupNumber+1),
|
| + group_(kNotFinalized) {
|
| + Initialize(year, month, day_of_month);
|
| + DCHECK(!default_group_name_.empty());
|
| +}
|
| +
|
| +// The following is a private constructor used for testing.
|
| +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_ * base::RandDouble())),
|
| + accumulated_group_probability_(0),
|
| + next_group_number_(kDefaultGroupNumber+1),
|
| + group_(kNotFinalized) {
|
| + Initialize(2099, 12, 31);
|
| + DCHECK(!default_group_name_.empty());
|
| +}
|
| +
|
| +void FieldTrial::Initialize(const int year,
|
| + const int month,
|
| + const int day_of_month) {
|
| FieldTrialList::Register(this);
|
| +
|
| + DCHECK_GT(year, 1970);
|
| + DCHECK_GT(month, 0);
|
| + DCHECK_LT(month, 13);
|
| + DCHECK_GT(day_of_month, 0);
|
| + DCHECK_LT(day_of_month, 32);
|
| +
|
| + base::Time::Exploded exploded;
|
| + exploded.year = year;
|
| + exploded.month = month;
|
| + exploded.day_of_week = 0; // Should be unusued.
|
| + exploded.day_of_month = day_of_month;
|
| + exploded.hour = 0;
|
| + exploded.minute = 0;
|
| + exploded.second = 0;
|
| + exploded.millisecond = 0;
|
| +
|
| + expiration_time_ = Time::FromLocalExploded(exploded);
|
| + disable_field_trial_ = (GetBuildTime() > expiration_time_) ? true : false;
|
| }
|
|
|
| int FieldTrial::AppendGroup(const std::string& name,
|
| Probability group_probability) {
|
| DCHECK(group_probability <= divisor_);
|
| - DCHECK(group_probability >=0 ||
|
| - group_probability == kAllRemainingProbability);
|
| - if (group_probability == kAllRemainingProbability) {
|
| - accumulated_group_probability_ = divisor_;
|
| - } else {
|
| - if (enable_benchmarking_)
|
| - group_probability = 0;
|
| - accumulated_group_probability_ += group_probability;
|
| - }
|
| + DCHECK_GE(group_probability, 0);
|
| +
|
| + if (enable_benchmarking_ || disable_field_trial_)
|
| + group_probability = 0;
|
| +
|
| + accumulated_group_probability_ += group_probability;
|
| +
|
| DCHECK(accumulated_group_probability_ <= divisor_);
|
| - if (group_ == kNotParticipating && accumulated_group_probability_ > random_) {
|
| + if (group_ == kNotFinalized && accumulated_group_probability_ > random_) {
|
| // This is the group that crossed the random line, so we do the assignment.
|
| group_ = next_group_number_;
|
| if (name.empty())
|
| @@ -62,6 +110,16 @@
|
| return next_group_number_++;
|
| }
|
|
|
| +int FieldTrial::group() {
|
| + if (group_ == kNotFinalized) {
|
| + accumulated_group_probability_ = divisor_;
|
| + group_ = kDefaultGroupNumber;
|
| + group_name_ = default_group_name_;
|
| + }
|
| +
|
| + return group_;
|
| +}
|
| +
|
| // static
|
| std::string FieldTrial::MakeName(const std::string& name_prefix,
|
| const std::string& trial_name) {
|
| @@ -76,6 +134,18 @@
|
| enable_benchmarking_ = true;
|
| }
|
|
|
| +// static
|
| +Time FieldTrial::GetBuildTime() {
|
| + static Time integral_build_time;
|
| + if (integral_build_time.is_null()) {
|
| + const char* kDateTime = __DATE__ " " __TIME__;
|
| + bool result = Time::FromString(ASCIIToWide(kDateTime).c_str(),
|
| + &integral_build_time);
|
| + DCHECK(result);
|
| + }
|
| + return integral_build_time;
|
| +}
|
| +
|
| FieldTrial::~FieldTrial() {}
|
|
|
| //------------------------------------------------------------------------------
|
| @@ -129,7 +199,7 @@
|
| FieldTrial* field_trial = Find(name);
|
| if (field_trial)
|
| return field_trial->group();
|
| - return FieldTrial::kNotParticipating;
|
| + return FieldTrial::kNotFinalized;
|
| }
|
|
|
| // static
|
| @@ -189,8 +259,10 @@
|
| continue;
|
| }
|
| const int kTotalProbability = 100;
|
| - field_trial = new FieldTrial(name, kTotalProbability);
|
| - field_trial->AppendGroup(group_name, kTotalProbability);
|
| + field_trial = new FieldTrial(name, kTotalProbability, group_name, 2099, 12,
|
| + 31);
|
| + // The following call finalizes the FieldTrial.
|
| + field_trial->group();
|
| }
|
| return true;
|
| }
|
|
|