OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/metrics/field_trial.h" | 5 #include "base/metrics/field_trial.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/rand_util.h" | 8 #include "base/rand_util.h" |
9 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
| 10 #include "base/utf_string_conversions.h" |
| 11 |
| 12 using base::Time; |
| 13 using base::TimeDelta; |
10 | 14 |
11 namespace base { | 15 namespace base { |
12 | 16 |
13 // static | 17 // static |
14 const int FieldTrial::kNotParticipating = -1; | 18 const int FieldTrial::kNotParticipating = -1; |
15 | 19 |
16 // static | 20 // static |
17 const int FieldTrial::kAllRemainingProbability = -2; | 21 const int FieldTrial::kAllRemainingProbability = -2; |
18 | 22 |
19 // static | 23 // static |
20 bool FieldTrial::enable_benchmarking_ = false; | 24 bool FieldTrial::enable_benchmarking_ = false; |
21 | 25 |
22 // static | 26 // static |
23 const char FieldTrialList::kPersistentStringSeparator('/'); | 27 const char FieldTrialList::kPersistentStringSeparator('/'); |
24 | 28 |
25 static const char kHistogramFieldTrialSeparator('_'); | 29 static const char kHistogramFieldTrialSeparator('_'); |
26 | 30 |
27 //------------------------------------------------------------------------------ | 31 //------------------------------------------------------------------------------ |
28 // FieldTrial methods and members. | 32 // FieldTrial methods and members. |
29 | 33 |
30 FieldTrial::FieldTrial(const std::string& name, | 34 FieldTrial::FieldTrial(const std::string& name, |
31 const Probability total_probability) | 35 const Probability total_probability) |
32 : name_(name), | 36 : name_(name), |
33 divisor_(total_probability), | 37 divisor_(total_probability), |
34 random_(static_cast<Probability>(divisor_ * base::RandDouble())), | 38 random_(static_cast<Probability>(divisor_ * base::RandDouble())), |
35 accumulated_group_probability_(0), | 39 accumulated_group_probability_(0), |
36 next_group_number_(0), | 40 next_group_number_(0), |
37 group_(kNotParticipating) { | 41 group_(kNotParticipating), |
| 42 disable_duration_(base::TimeDelta::FromDays(30)), |
| 43 disable_field_trail_(false) { |
38 FieldTrialList::Register(this); | 44 FieldTrialList::Register(this); |
| 45 DetermineIfFieldTrailIsToBeDisabled(); |
| 46 } |
| 47 |
| 48 void FieldTrial::DetermineIfFieldTrailIsToBeDisabled() { |
| 49 if (base::Time::NowFromSystemTime() - GetBuildTime() >= disable_duration_) |
| 50 disable_field_trail_ = true; |
39 } | 51 } |
40 | 52 |
41 int FieldTrial::AppendGroup(const std::string& name, | 53 int FieldTrial::AppendGroup(const std::string& name, |
42 Probability group_probability) { | 54 Probability group_probability) { |
43 DCHECK(group_probability <= divisor_); | 55 DCHECK(group_probability <= divisor_); |
44 DCHECK(group_probability >=0 || | 56 DCHECK(group_probability >=0 || |
45 group_probability == kAllRemainingProbability); | 57 group_probability == kAllRemainingProbability); |
46 if (group_probability == kAllRemainingProbability) { | 58 if (group_probability == kAllRemainingProbability) { |
47 accumulated_group_probability_ = divisor_; | 59 accumulated_group_probability_ = divisor_; |
48 } else { | 60 } else { |
49 if (enable_benchmarking_) | 61 if (enable_benchmarking_ || disable_field_trail_) |
50 group_probability = 0; | 62 group_probability = 0; |
| 63 |
51 accumulated_group_probability_ += group_probability; | 64 accumulated_group_probability_ += group_probability; |
52 } | 65 } |
53 DCHECK(accumulated_group_probability_ <= divisor_); | 66 DCHECK(accumulated_group_probability_ <= divisor_); |
54 if (group_ == kNotParticipating && accumulated_group_probability_ > random_) { | 67 if (group_ == kNotParticipating && accumulated_group_probability_ > random_) { |
55 // This is the group that crossed the random line, so we do the assignment. | 68 // This is the group that crossed the random line, so we do the assignment. |
56 group_ = next_group_number_; | 69 group_ = next_group_number_; |
57 if (name.empty()) | 70 if (name.empty()) |
58 base::StringAppendF(&group_name_, "%d", group_); | 71 base::StringAppendF(&group_name_, "%d", group_); |
59 else | 72 else |
60 group_name_ = name; | 73 group_name_ = name; |
61 } | 74 } |
62 return next_group_number_++; | 75 return next_group_number_++; |
63 } | 76 } |
64 | 77 |
| 78 void FieldTrial::SetDisableDuration(const base::TimeDelta& duration) { |
| 79 disable_duration_ = duration; |
| 80 DetermineIfFieldTrailIsToBeDisabled(); |
| 81 } |
| 82 |
65 // static | 83 // static |
66 std::string FieldTrial::MakeName(const std::string& name_prefix, | 84 std::string FieldTrial::MakeName(const std::string& name_prefix, |
67 const std::string& trial_name) { | 85 const std::string& trial_name) { |
68 std::string big_string(name_prefix); | 86 std::string big_string(name_prefix); |
69 big_string.append(1, kHistogramFieldTrialSeparator); | 87 big_string.append(1, kHistogramFieldTrialSeparator); |
70 return big_string.append(FieldTrialList::FindFullName(trial_name)); | 88 return big_string.append(FieldTrialList::FindFullName(trial_name)); |
71 } | 89 } |
72 | 90 |
73 // static | 91 // static |
74 void FieldTrial::EnableBenchmarking() { | 92 void FieldTrial::EnableBenchmarking() { |
75 DCHECK_EQ(0u, FieldTrialList::GetFieldTrialCount()); | 93 DCHECK_EQ(0u, FieldTrialList::GetFieldTrialCount()); |
76 enable_benchmarking_ = true; | 94 enable_benchmarking_ = true; |
77 } | 95 } |
78 | 96 |
| 97 // static |
| 98 Time FieldTrial::GetBuildTime() { |
| 99 static Time integral_build_time; |
| 100 if (integral_build_time.is_null()) { |
| 101 const char* kDateTime = __DATE__ " " __TIME__; |
| 102 bool result = Time::FromString(ASCIIToWide(kDateTime).c_str(), |
| 103 &integral_build_time); |
| 104 DCHECK(result); |
| 105 } |
| 106 return integral_build_time; |
| 107 } |
| 108 |
79 FieldTrial::~FieldTrial() {} | 109 FieldTrial::~FieldTrial() {} |
80 | 110 |
81 //------------------------------------------------------------------------------ | 111 //------------------------------------------------------------------------------ |
82 // FieldTrialList methods and members. | 112 // FieldTrialList methods and members. |
83 | 113 |
84 // static | 114 // static |
85 FieldTrialList* FieldTrialList::global_ = NULL; | 115 FieldTrialList* FieldTrialList::global_ = NULL; |
86 | 116 |
87 // static | 117 // static |
88 bool FieldTrialList::register_without_global_ = false; | 118 bool FieldTrialList::register_without_global_ = false; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 | 234 |
205 // static | 235 // static |
206 size_t FieldTrialList::GetFieldTrialCount() { | 236 size_t FieldTrialList::GetFieldTrialCount() { |
207 if (!global_) | 237 if (!global_) |
208 return 0; | 238 return 0; |
209 AutoLock auto_lock(global_->lock_); | 239 AutoLock auto_lock(global_->lock_); |
210 return global_->registered_.size(); | 240 return global_->registered_.size(); |
211 } | 241 } |
212 | 242 |
213 } // namespace base | 243 } // namespace base |
OLD | NEW |