OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
99 virtual double GetEntropyForTrial(const std::string& trial_name, | 99 virtual double GetEntropyForTrial(const std::string& trial_name, |
100 uint32 randomization_seed) const = 0; | 100 uint32 randomization_seed) const = 0; |
101 }; | 101 }; |
102 | 102 |
103 // A pair representing a Field Trial and its selected group. | 103 // A pair representing a Field Trial and its selected group. |
104 struct ActiveGroup { | 104 struct ActiveGroup { |
105 std::string trial_name; | 105 std::string trial_name; |
106 std::string group_name; | 106 std::string group_name; |
107 }; | 107 }; |
108 | 108 |
109 // A triplet representing a Field Trial, its selected group and whether it's | |
110 // active. | |
111 struct FieldTrialState { | |
112 std::string trial_name; | |
113 std::string group_name; | |
114 bool activated; | |
115 }; | |
116 | |
109 typedef std::vector<ActiveGroup> ActiveGroups; | 117 typedef std::vector<ActiveGroup> ActiveGroups; |
118 typedef std::vector<FieldTrialState> AllGroups; | |
110 | 119 |
111 // A return value to indicate that a given instance has not yet had a group | 120 // A return value to indicate that a given instance has not yet had a group |
112 // assignment (and hence is not yet participating in the trial). | 121 // assignment (and hence is not yet participating in the trial). |
113 static const int kNotFinalized; | 122 static const int kNotFinalized; |
114 | 123 |
115 // Disables this trial, meaning it always determines the default group | 124 // Disables this trial, meaning it always determines the default group |
116 // has been selected. May be called immediately after construction, or | 125 // has been selected. May be called immediately after construction, or |
117 // at any time after initialization (should not be interleaved with | 126 // at any time after initialization (should not be interleaved with |
118 // AppendGroup calls). Once disabled, there is no way to re-enable a | 127 // AppendGroup calls). Once disabled, there is no way to re-enable a |
119 // trial. | 128 // trial. |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
173 private: | 182 private: |
174 // Allow tests to access our innards for testing purposes. | 183 // Allow tests to access our innards for testing purposes. |
175 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, Registration); | 184 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, Registration); |
176 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, AbsoluteProbabilities); | 185 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, AbsoluteProbabilities); |
177 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, RemainingProbability); | 186 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, RemainingProbability); |
178 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, FiftyFiftyProbability); | 187 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, FiftyFiftyProbability); |
179 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, MiddleProbabilities); | 188 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, MiddleProbabilities); |
180 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, OneWinner); | 189 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, OneWinner); |
181 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DisableProbability); | 190 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DisableProbability); |
182 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, ActiveGroups); | 191 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, ActiveGroups); |
192 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, AllGroups); | |
183 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, ActiveGroupsNotFinalized); | 193 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, ActiveGroupsNotFinalized); |
184 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, Save); | 194 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, Save); |
185 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DuplicateRestore); | 195 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DuplicateRestore); |
186 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, SetForcedTurnFeatureOff); | 196 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, SetForcedTurnFeatureOff); |
187 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, SetForcedTurnFeatureOn); | 197 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, SetForcedTurnFeatureOn); |
188 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, SetForcedChangeDefault_Default); | 198 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, SetForcedChangeDefault_Default); |
189 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, SetForcedChangeDefault_NonDefault); | 199 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, SetForcedChangeDefault_NonDefault); |
190 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, FloatBoundariesGiveEqualGroupSizes); | 200 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, FloatBoundariesGiveEqualGroupSizes); |
191 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DoesNotSurpassTotalProbability); | 201 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DoesNotSurpassTotalProbability); |
192 | 202 |
(...skipping 30 matching lines...) Expand all Loading... | |
223 void FinalizeGroupChoice(); | 233 void FinalizeGroupChoice(); |
224 | 234 |
225 // Returns the trial name and selected group name for this field trial via | 235 // Returns the trial name and selected group name for this field trial via |
226 // the output parameter |active_group|, but only if the group has already | 236 // the output parameter |active_group|, but only if the group has already |
227 // been chosen and has been externally observed via |group()| and the trial | 237 // been chosen and has been externally observed via |group()| and the trial |
228 // has not been disabled. In that case, true is returned and |active_group| | 238 // has not been disabled. In that case, true is returned and |active_group| |
229 // is filled in; otherwise, the result is false and |active_group| is left | 239 // is filled in; otherwise, the result is false and |active_group| is left |
230 // untouched. | 240 // untouched. |
231 bool GetActiveGroup(ActiveGroup* active_group) const; | 241 bool GetActiveGroup(ActiveGroup* active_group) const; |
232 | 242 |
243 // Returns the trial name and selected group name for this field trial via | |
244 // the output parameter |field_trial_state|, but only if the trial has not | |
245 // been disabled. In that case, true is returned and |field_trial_state| is | |
246 // filled in; otherwise, the result is false and |field_trial_state| is left | |
247 // untouched. | |
248 bool GetFieldTrialState(FieldTrialState* field_trial_state) const; | |
Alexei Svitkine (slow)
2014/11/05 22:50:53
Nit: Actually, just name this GetState().
Georges Khalil
2014/11/06 18:36:28
Done.
| |
249 | |
233 // Returns the group_name. A winner need not have been chosen. | 250 // Returns the group_name. A winner need not have been chosen. |
234 std::string group_name_internal() const { return group_name_; } | 251 std::string group_name_internal() const { return group_name_; } |
235 | 252 |
236 // The name of the field trial, as can be found via the FieldTrialList. | 253 // The name of the field trial, as can be found via the FieldTrialList. |
237 const std::string trial_name_; | 254 const std::string trial_name_; |
238 | 255 |
239 // The maximum sum of all probabilities supplied, which corresponds to 100%. | 256 // The maximum sum of all probabilities supplied, which corresponds to 100%. |
240 // This is the scaling factor used to adjust supplied probabilities. | 257 // This is the scaling factor used to adjust supplied probabilities. |
241 const Probability divisor_; | 258 const Probability divisor_; |
242 | 259 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
397 // Creates a persistent representation of active FieldTrial instances for | 414 // Creates a persistent representation of active FieldTrial instances for |
398 // resurrection in another process. This allows randomization to be done in | 415 // resurrection in another process. This allows randomization to be done in |
399 // one process, and secondary processes can be synchronized on the result. | 416 // one process, and secondary processes can be synchronized on the result. |
400 // The resulting string contains the name and group name pairs of all | 417 // The resulting string contains the name and group name pairs of all |
401 // registered FieldTrials for which the group has been chosen and externally | 418 // registered FieldTrials for which the group has been chosen and externally |
402 // observed (via |group()|) and which have not been disabled, with "/" used | 419 // observed (via |group()|) and which have not been disabled, with "/" used |
403 // to separate all names and to terminate the string. This string is parsed | 420 // to separate all names and to terminate the string. This string is parsed |
404 // by |CreateTrialsFromString()|. | 421 // by |CreateTrialsFromString()|. |
405 static void StatesToString(std::string* output); | 422 static void StatesToString(std::string* output); |
406 | 423 |
424 // Creates a persistent representation of all FieldTrial instances for | |
425 // resurrection in another process. This allows randomization to be done in | |
426 // one process, and secondary processes can be synchronized on the result. | |
427 // The resulting string contains the name and group name pairs of all | |
428 // registered FieldTrials which have not been disabled, with "/" used | |
429 // to separate all names and to terminate the string. All activated trials | |
430 // have their name prefixed with "*". This string is parsed by | |
431 // |CreateTrialsFromString()|. | |
432 static void AllStatesToString(std::string* output); | |
433 | |
407 // Fills in the supplied vector |active_groups| (which must be empty when | 434 // Fills in the supplied vector |active_groups| (which must be empty when |
408 // called) with a snapshot of all registered FieldTrials for which the group | 435 // called) with a snapshot of all registered FieldTrials for which the group |
409 // has been chosen and externally observed (via |group()|) and which have | 436 // has been chosen and externally observed (via |group()|) and which have |
410 // not been disabled. | 437 // not been disabled. |
411 static void GetActiveFieldTrialGroups( | 438 static void GetActiveFieldTrialGroups( |
412 FieldTrial::ActiveGroups* active_groups); | 439 FieldTrial::ActiveGroups* active_groups); |
413 | 440 |
414 // Use a state string (re: StatesToString()) to augment the current list of | 441 // Use a state string (re: StatesToString()) to augment the current list of |
415 // field trials to include the supplied trials, and using a 100% probability | 442 // field trials to include the supplied trials, and using a 100% probability |
416 // for each trial, force them to have the same group string. This is commonly | 443 // for each trial, force them to have the same group string. This is commonly |
(...skipping 26 matching lines...) Expand all Loading... | |
443 // Remove an observer. | 470 // Remove an observer. |
444 static void RemoveObserver(Observer* observer); | 471 static void RemoveObserver(Observer* observer); |
445 | 472 |
446 // Notify all observers that a group has been finalized for |field_trial|. | 473 // Notify all observers that a group has been finalized for |field_trial|. |
447 static void NotifyFieldTrialGroupSelection(FieldTrial* field_trial); | 474 static void NotifyFieldTrialGroupSelection(FieldTrial* field_trial); |
448 | 475 |
449 // Return the number of active field trials. | 476 // Return the number of active field trials. |
450 static size_t GetFieldTrialCount(); | 477 static size_t GetFieldTrialCount(); |
451 | 478 |
452 private: | 479 private: |
480 // Fills in the supplied vector |all_groups| (which must be empty when called) | |
481 // with a snapshot of all registered FieldTrials which have not been disabled. | |
482 static void GetAllFieldTrialGroups( | |
483 FieldTrial::AllGroups* all_groups); | |
484 | |
453 // A map from FieldTrial names to the actual instances. | 485 // A map from FieldTrial names to the actual instances. |
454 typedef std::map<std::string, FieldTrial*> RegistrationMap; | 486 typedef std::map<std::string, FieldTrial*> RegistrationMap; |
455 | 487 |
456 // If one-time randomization is enabled, returns a weak pointer to the | 488 // If one-time randomization is enabled, returns a weak pointer to the |
457 // corresponding EntropyProvider. Otherwise, returns NULL. | 489 // corresponding EntropyProvider. Otherwise, returns NULL. |
458 static const FieldTrial::EntropyProvider* | 490 static const FieldTrial::EntropyProvider* |
459 GetEntropyProviderForOneTimeRandomization(); | 491 GetEntropyProviderForOneTimeRandomization(); |
460 | 492 |
461 // Helper function should be called only while holding lock_. | 493 // Helper function should be called only while holding lock_. |
462 FieldTrial* PreLockedFind(const std::string& name); | 494 FieldTrial* PreLockedFind(const std::string& name); |
(...skipping 21 matching lines...) Expand all Loading... | |
484 | 516 |
485 // List of observers to be notified when a group is selected for a FieldTrial. | 517 // List of observers to be notified when a group is selected for a FieldTrial. |
486 scoped_refptr<ObserverListThreadSafe<Observer> > observer_list_; | 518 scoped_refptr<ObserverListThreadSafe<Observer> > observer_list_; |
487 | 519 |
488 DISALLOW_COPY_AND_ASSIGN(FieldTrialList); | 520 DISALLOW_COPY_AND_ASSIGN(FieldTrialList); |
489 }; | 521 }; |
490 | 522 |
491 } // namespace base | 523 } // namespace base |
492 | 524 |
493 #endif // BASE_METRICS_FIELD_TRIAL_H_ | 525 #endif // BASE_METRICS_FIELD_TRIAL_H_ |
OLD | NEW |