Chromium Code Reviews| 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,56 @@ |
| // 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), |
| + expiration_year_(year), |
| + expiration_month_(month), |
| + expiration_day_of_month_(day_of_month) { |
| + DCHECK(!default_group_name_.empty()); |
| FieldTrialList::Register(this); |
| + |
| + DCHECK_GT(expiration_year_, 1970); |
| + DCHECK_GT(expiration_month_, 0); |
| + DCHECK_LT(expiration_month_, 13); |
| + DCHECK_GT(expiration_day_of_month_, 0); |
| + DCHECK_LT(expiration_day_of_month_, 32); |
| + |
| + base::Time::Exploded exploded; |
| + exploded.year = expiration_year_; |
| + exploded.month = expiration_month_; |
| + exploded.day_of_week = 0; // Should be unusued. |
| + exploded.day_of_month = expiration_day_of_month_; |
| + exploded.hour = 0; |
| + exploded.minute = 0; |
| + exploded.second = 0; |
| + exploded.millisecond = 0; |
| + |
| + base::Time 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 +92,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 +116,18 @@ |
| enable_benchmarking_ = true; |
| } |
| +// static |
| +Time FieldTrial::GetBuildTime() { |
| + static Time integral_build_time; |
|
jar (doing other things)
2011/01/15 20:52:47
Don't bother caching this. There may be a race on
|
| + 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 +181,7 @@ |
| FieldTrial* field_trial = Find(name); |
| if (field_trial) |
| return field_trial->group(); |
| - return FieldTrial::kNotParticipating; |
| + return FieldTrial::kNotFinalized; |
| } |
| // static |
| @@ -189,8 +241,9 @@ |
| 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); |
|
jar (doing other things)
2011/01/15 20:52:47
This constant is a little dangerous on two account
|
| + field_trial->group(); |
| } |
| return true; |
| } |