Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: base/metrics/field_trial.h

Issue 9117037: Added a Unique ID for a Field Trial containing it's hashed name and the selected group ID. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | base/metrics/field_trial.cc » ('j') | base/metrics/field_trial.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 // FieldTrial is a class for handling details of statistical experiments 5 // FieldTrial is a class for handling details of statistical experiments
6 // performed by actual users in the field (i.e., in a shipped or beta product). 6 // performed by actual users in the field (i.e., in a shipped or beta product).
7 // All code is called exclusively on the UI thread currently. 7 // All code is called exclusively on the UI thread currently.
8 // 8 //
9 // The simplest example is an experiment to see whether one of two options 9 // The simplest example is an experiment to see whether one of two options
10 // produces "better" results across our user population. In that scenario, UMA 10 // produces "better" results across our user population. In that scenario, UMA
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 #include "base/synchronization/lock.h" 85 #include "base/synchronization/lock.h"
86 #include "base/time.h" 86 #include "base/time.h"
87 87
88 namespace base { 88 namespace base {
89 89
90 class FieldTrialList; 90 class FieldTrialList;
91 91
92 class BASE_EXPORT FieldTrial : public RefCounted<FieldTrial> { 92 class BASE_EXPORT FieldTrial : public RefCounted<FieldTrial> {
93 public: 93 public:
94 typedef int Probability; // Probability type for being selected in a trial. 94 typedef int Probability; // Probability type for being selected in a trial.
95 // The Unique ID of a trial, where the name and group identifiers are
96 // hashes of the trial and group name strings.
97 struct NameGroupId{
Alexei Svitkine (slow) 2012/01/25 15:25:19 Nit: Add a space before {.
MAD 2012/01/25 17:02:33 Done.
98 uint32 name;
99 uint32 group;
100 };
95 101
96 // A return value to indicate that a given instance has not yet had a group 102 // A return value to indicate that a given instance has not yet had a group
97 // assignment (and hence is not yet participating in the trial). 103 // assignment (and hence is not yet participating in the trial).
98 static const int kNotFinalized; 104 static const int kNotFinalized;
99 105
100 // This is the group number of the 'default' group. This provides an easy way 106 // This is the group number of the 'default' group. This provides an easy way
101 // to assign all the remaining probability to a group ('default'). 107 // to assign all the remaining probability to a group ('default').
102 static const int kDefaultGroupNumber; 108 static const int kDefaultGroupNumber;
103 109
110 // This value is reserved for an uninitialized hash value.
111 static const uint32 kReservedHashValue;
112
104 // The name is used to register the instance with the FieldTrialList class, 113 // The name is used to register the instance with the FieldTrialList class,
105 // and can be used to find the trial (only one trial can be present for each 114 // and can be used to find the trial (only one trial can be present for each
106 // name). |name| and |default_group_name| may not be empty. 115 // name). |name| and |default_group_name| may not be empty.
107 // 116 //
108 // Group probabilities that are later supplied must sum to less than or equal 117 // Group probabilities that are later supplied must sum to less than or equal
109 // to the total_probability. Arguments year, month and day_of_month specify 118 // to the total_probability. Arguments year, month and day_of_month specify
110 // the expiration time. If the build time is after the expiration time then 119 // the expiration time. If the build time is after the expiration time then
111 // the field trial reverts to the 'default' group. 120 // the field trial reverts to the 'default' group.
112 // 121 //
113 // Using this constructor creates a startup-randomized FieldTrial. If you 122 // Using this constructor creates a startup-randomized FieldTrial. If you
(...skipping 27 matching lines...) Expand all
141 // Return the randomly selected group number that was assigned. 150 // Return the randomly selected group number that was assigned.
142 // Return kDefaultGroupNumber if the instance is in the 'default' group. 151 // Return kDefaultGroupNumber if the instance is in the 'default' group.
143 // Note that this will force an instance to participate, and make it illegal 152 // Note that this will force an instance to participate, and make it illegal
144 // to attempt to probabilistically add any other groups to the trial. 153 // to attempt to probabilistically add any other groups to the trial.
145 int group(); 154 int group();
146 155
147 // If the group's name is empty, a string version containing the group 156 // If the group's name is empty, a string version containing the group
148 // number is used as the group name. 157 // number is used as the group name.
149 std::string group_name(); 158 std::string group_name();
150 159
160 // Gets the unique identifier of the Field Trial, but only if a winner was
161 // elected. Returns true if a winner is returned, false otherwise.
Alexei Svitkine (slow) 2012/01/25 15:25:19 Can you reword this to either explain what you mea
MAD 2012/01/25 17:02:33 Done.
162 bool GetNameGroupId(NameGroupId* name_group_id);
163
151 // Return the default group name of the FieldTrial. 164 // Return the default group name of the FieldTrial.
152 std::string default_group_name() const { return default_group_name_; } 165 std::string default_group_name() const { return default_group_name_; }
153 166
154 // Helper function for the most common use: as an argument to specify the 167 // Helper function for the most common use: as an argument to specify the
155 // name of a HISTOGRAM. Use the original histogram name as the name_prefix. 168 // name of a HISTOGRAM. Use the original histogram name as the name_prefix.
156 static std::string MakeName(const std::string& name_prefix, 169 static std::string MakeName(const std::string& name_prefix,
157 const std::string& trial_name); 170 const std::string& trial_name);
158 171
159 // Enable benchmarking sets field trials to a common setting. 172 // Enable benchmarking sets field trials to a common setting.
160 static void EnableBenchmarking(); 173 static void EnableBenchmarking();
161 174
162 private: 175 private:
163 // Allow tests to access our innards for testing purposes. 176 // Allow tests to access our innards for testing purposes.
164 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, Registration); 177 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, Registration);
165 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, AbsoluteProbabilities); 178 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, AbsoluteProbabilities);
166 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, RemainingProbability); 179 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, RemainingProbability);
167 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, FiftyFiftyProbability); 180 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, FiftyFiftyProbability);
168 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, MiddleProbabilities); 181 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, MiddleProbabilities);
169 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, OneWinner); 182 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, OneWinner);
170 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DisableProbability); 183 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DisableProbability);
171 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, Save); 184 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, Save);
172 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DuplicateRestore); 185 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DuplicateRestore);
173 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, MakeName); 186 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, MakeName);
174 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, HashClientId); 187 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, HashClientId);
175 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, HashClientIdIsUniform); 188 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, HashClientIdIsUniform);
176 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, UseOneTimeRandomization); 189 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, UseOneTimeRandomization);
190 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, NameGroupIds);
177 191
178 friend class base::FieldTrialList; 192 friend class base::FieldTrialList;
179 193
180 friend class RefCounted<FieldTrial>; 194 friend class RefCounted<FieldTrial>;
181 195
182 virtual ~FieldTrial(); 196 virtual ~FieldTrial();
183 197
184 // Returns the group_name. A winner need not have been chosen. 198 // Returns the group_name. A winner need not have been chosen.
185 std::string group_name_internal() const { return group_name_; } 199 std::string group_name_internal() const { return group_name_; }
186 200
187 // Calculates a uniformly-distributed double between [0.0, 1.0) given 201 // Calculates a uniformly-distributed double between [0.0, 1.0) given
188 // a |client_id| and a |trial_name| (the latter is used as salt to avoid 202 // a |client_id| and a |trial_name| (the latter is used as salt to avoid
189 // separate one-time randomized trials from all having the same results). 203 // separate one-time randomized trials from all having the same results).
190 static double HashClientId(const std::string& client_id, 204 static double HashClientId(const std::string& client_id,
191 const std::string& trial_name); 205 const std::string& trial_name);
192 206
207 // Creates unique identifier for the trial by hashing the name string.
Alexei Svitkine (slow) 2012/01/25 15:25:19 The comment should probably mention that this hash
MAD 2012/01/25 17:02:33 Done.
208 static uint32 HashName(const std::string& name);
209
193 // The name of the field trial, as can be found via the FieldTrialList. 210 // The name of the field trial, as can be found via the FieldTrialList.
194 const std::string name_; 211 const std::string name_;
195 212
213 // The hashed name of the field trial to be sent as a unique identifier.
214 const uint32 name_hash_;
215
196 // The maximum sum of all probabilities supplied, which corresponds to 100%. 216 // The maximum sum of all probabilities supplied, which corresponds to 100%.
197 // This is the scaling factor used to adjust supplied probabilities. 217 // This is the scaling factor used to adjust supplied probabilities.
198 const Probability divisor_; 218 const Probability divisor_;
199 219
200 // The name of the default group. 220 // The name of the default group.
201 const std::string default_group_name_; 221 const std::string default_group_name_;
202 222
203 // The randomly selected probability that is used to select a group (or have 223 // The randomly selected probability that is used to select a group (or have
204 // the instance not participate). It is the product of divisor_ and a random 224 // the instance not participate). It is the product of divisor_ and a random
205 // number between [0, 1). 225 // number between [0, 1).
206 Probability random_; 226 Probability random_;
207 227
208 // Sum of the probabilities of all appended groups. 228 // Sum of the probabilities of all appended groups.
209 Probability accumulated_group_probability_; 229 Probability accumulated_group_probability_;
210 230
211 int next_group_number_; 231 int next_group_number_;
212 232
213 // The pseudo-randomly assigned group number. 233 // The pseudo-randomly assigned group number.
214 // This is kNotFinalized if no group has been assigned. 234 // This is kNotFinalized if no group has been assigned.
215 int group_; 235 int group_;
216 236
217 // A textual name for the randomly selected group. Valid after |group()| 237 // A textual name for the randomly selected group. Valid after |group()|
218 // has been called. 238 // has been called.
219 std::string group_name_; 239 std::string group_name_;
220 240
241 // The hashed name of the group to be sent as a unique identifier.
242 // Is not valid while group_ is equal to kNotFinalized.
243 uint32 group_name_hash_;
244
221 // When enable_field_trial_ is false, field trial reverts to the 'default' 245 // When enable_field_trial_ is false, field trial reverts to the 'default'
222 // group. 246 // group.
223 bool enable_field_trial_; 247 bool enable_field_trial_;
224 248
225 // When benchmarking is enabled, field trials all revert to the 'default' 249 // When benchmarking is enabled, field trials all revert to the 'default'
226 // group. 250 // group.
227 static bool enable_benchmarking_; 251 static bool enable_benchmarking_;
228 252
229 DISALLOW_COPY_AND_ASSIGN(FieldTrial); 253 DISALLOW_COPY_AND_ASSIGN(FieldTrial);
230 }; 254 };
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 302
279 // Returns the group name chosen for the named trial, or the 303 // Returns the group name chosen for the named trial, or the
280 // empty string if the trial does not exist. 304 // empty string if the trial does not exist.
281 static std::string FindFullName(const std::string& name); 305 static std::string FindFullName(const std::string& name);
282 306
283 // Returns true if the named trial has been registered. 307 // Returns true if the named trial has been registered.
284 static bool TrialExists(const std::string& name); 308 static bool TrialExists(const std::string& name);
285 309
286 // Create a persistent representation of all FieldTrial instances and the 310 // Create a persistent representation of all FieldTrial instances and the
287 // |client_id()| state for resurrection in another process. This allows 311 // |client_id()| state for resurrection in another process. This allows
288 // randomization to be done in one process, and secondary processes can by 312 // randomization to be done in one process, and secondary processes can be
289 // synchronized on the result. The resulting string contains the 313 // synchronized on the result. The resulting string contains the
290 // |client_id()|, the names, the trial name, and a "/" separator. 314 // |client_id()|, the names, the trial name, and a "/" separator.
291 static void StatesToString(std::string* output); 315 static void StatesToString(std::string* output);
292 316
317 // Returns an array of Unique IDs for each currently running Field Trials.
Alexei Svitkine (slow) 2012/01/25 15:25:19 Can you expand this comment to explain what "curre
MAD 2012/01/25 17:02:33 Done.
318 static void GetFieldTrialNameGroupIds(
319 std::vector<FieldTrial::NameGroupId>* name_group_ids);
320
293 // Use a previously generated state string (re: StatesToString()) augment the 321 // Use a previously generated state string (re: StatesToString()) augment the
294 // current list of field tests to include the supplied tests, and using a 100% 322 // current list of field tests to include the supplied tests, and using a 100%
295 // probability for each test, force them to have the same group string. This 323 // probability for each test, force them to have the same group string. This
296 // is commonly used in a non-browser process, to carry randomly selected state 324 // is commonly used in a non-browser process, to carry randomly selected state
297 // in a browser process into this non-browser process. This method calls 325 // in a browser process into this non-browser process. This method calls
298 // CreateFieldTrial to create the FieldTrial in the non-browser process. 326 // CreateFieldTrial to create the FieldTrial in the non-browser process.
299 // Currently only the group_name_ and name_ are restored, as well as the 327 // Currently only the group_name_ and name_ are restored, as well as the
300 // |client_id()| state, that could be used for one-time randomized trials 328 // |client_id()| state, that could be used for one-time randomized trials
301 // set up only in child processes. 329 // set up only in child processes.
302 static bool CreateTrialsInChildProcess(const std::string& prior_trials); 330 static bool CreateTrialsInChildProcess(const std::string& prior_trials);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 407
380 // List of observers to be notified when a group is selected for a FieldTrial. 408 // List of observers to be notified when a group is selected for a FieldTrial.
381 ObserverList<Observer> observer_list_; 409 ObserverList<Observer> observer_list_;
382 410
383 DISALLOW_COPY_AND_ASSIGN(FieldTrialList); 411 DISALLOW_COPY_AND_ASSIGN(FieldTrialList);
384 }; 412 };
385 413
386 } // namespace base 414 } // namespace base
387 415
388 #endif // BASE_METRICS_FIELD_TRIAL_H_ 416 #endif // BASE_METRICS_FIELD_TRIAL_H_
OLDNEW
« no previous file with comments | « no previous file | base/metrics/field_trial.cc » ('j') | base/metrics/field_trial.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698