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

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

Issue 10151017: Remove the hash fields from FieldTrials. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: header order Created 8 years, 8 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
« no previous file with comments | « no previous file | base/metrics/field_trial.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 // Memory.RendererTotal_StandardMem // 96% of users will fill this histogram. 70 // Memory.RendererTotal_StandardMem // 96% of users will fill this histogram.
71 71
72 //------------------------------------------------------------------------------ 72 //------------------------------------------------------------------------------
73 73
74 #ifndef BASE_METRICS_FIELD_TRIAL_H_ 74 #ifndef BASE_METRICS_FIELD_TRIAL_H_
75 #define BASE_METRICS_FIELD_TRIAL_H_ 75 #define BASE_METRICS_FIELD_TRIAL_H_
76 #pragma once 76 #pragma once
77 77
78 #include <map> 78 #include <map>
79 #include <string> 79 #include <string>
80 #include <vector>
80 81
81 #include "base/base_export.h" 82 #include "base/base_export.h"
82 #include "base/gtest_prod_util.h" 83 #include "base/gtest_prod_util.h"
83 #include "base/memory/ref_counted.h" 84 #include "base/memory/ref_counted.h"
84 #include "base/observer_list.h" 85 #include "base/observer_list.h"
85 #include "base/synchronization/lock.h" 86 #include "base/synchronization/lock.h"
86 #include "base/time.h" 87 #include "base/time.h"
87 88
88 namespace base { 89 namespace base {
89 90
90 class FieldTrialList; 91 class FieldTrialList;
91 92
92 class BASE_EXPORT FieldTrial : public RefCounted<FieldTrial> { 93 class BASE_EXPORT FieldTrial : public RefCounted<FieldTrial> {
93 public: 94 public:
94 typedef int Probability; // Probability type for being selected in a trial. 95 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
96 // hashes of the trial and group name strings. 97 // A pair representing a Field Trial and its selected group.
97 struct NameGroupId { 98 struct SelectedGroup {
98 uint32 name; 99 std::string trial;
99 uint32 group; 100 std::string group;
100 }; 101 };
101 102
103 typedef std::vector<SelectedGroup> SelectedGroups;
104
102 // A return value to indicate that a given instance has not yet had a group 105 // A return value to indicate that a given instance has not yet had a group
103 // assignment (and hence is not yet participating in the trial). 106 // assignment (and hence is not yet participating in the trial).
104 static const int kNotFinalized; 107 static const int kNotFinalized;
105 108
106 // Changes the field trial to use one-time randomization, i.e. produce the 109 // Changes the field trial to use one-time randomization, i.e. produce the
107 // same result for the current trial on every run of this client. Must be 110 // same result for the current trial on every run of this client. Must be
108 // called right after construction. 111 // called right after construction.
109 void UseOneTimeRandomization(); 112 void UseOneTimeRandomization();
110 113
111 // Disables this trial, meaning it always determines the default group 114 // Disables this trial, meaning it always determines the default group
(...skipping 16 matching lines...) Expand all
128 131
129 // Return the randomly selected group number that was assigned. 132 // Return the randomly selected group number that was assigned.
130 // Note that this will force an instance to participate, and make it illegal 133 // Note that this will force an instance to participate, and make it illegal
131 // to attempt to probabilistically add any other groups to the trial. 134 // to attempt to probabilistically add any other groups to the trial.
132 int group(); 135 int group();
133 136
134 // If the group's name is empty, a string version containing the group number 137 // If the group's name is empty, a string version containing the group number
135 // is used as the group name. This causes a winner to be chosen if none was. 138 // is used as the group name. This causes a winner to be chosen if none was.
136 std::string group_name(); 139 std::string group_name();
137 140
138 // Gets the unique identifier of the Field Trial, but only if a group was 141 // Gets the SelectedGroup of the Field Trial, but only if a group was
139 // officially chosen, otherwise name_group_id is left untouched and false 142 // officially chosen, otherwise name_group_id is left untouched and false
140 // is returned. When true is returned, the name and group ids were 143 // is returned. When true is returned, the trial and group names were
141 // successfully set in name_group_id. 144 // successfully set in selected_group.
142 bool GetNameGroupId(NameGroupId* name_group_id); 145 bool GetSelectedGroup(SelectedGroup* selected_group);
143 146
144 // Helper function for the most common use: as an argument to specify the 147 // Helper function for the most common use: as an argument to specify the
145 // name of a HISTOGRAM. Use the original histogram name as the name_prefix. 148 // name of a HISTOGRAM. Use the original histogram name as the name_prefix.
146 static std::string MakeName(const std::string& name_prefix, 149 static std::string MakeName(const std::string& name_prefix,
147 const std::string& trial_name); 150 const std::string& trial_name);
148 151
149 // Helper function to create a NameGroupId from |trial_name| and |group_name|.
150 static NameGroupId MakeNameGroupId(const std::string& trial_name,
151 const std::string& group_name);
152
153 // Enable benchmarking sets field trials to a common setting. 152 // Enable benchmarking sets field trials to a common setting.
154 static void EnableBenchmarking(); 153 static void EnableBenchmarking();
155 154
156 private: 155 private:
157 // Allow tests to access our innards for testing purposes. 156 // Allow tests to access our innards for testing purposes.
158 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, Registration); 157 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, Registration);
159 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, AbsoluteProbabilities); 158 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, AbsoluteProbabilities);
160 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, RemainingProbability); 159 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, RemainingProbability);
161 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, FiftyFiftyProbability); 160 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, FiftyFiftyProbability);
162 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, MiddleProbabilities); 161 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, MiddleProbabilities);
163 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, OneWinner); 162 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, OneWinner);
164 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DisableProbability); 163 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DisableProbability);
165 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, Save); 164 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, Save);
166 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DuplicateRestore); 165 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DuplicateRestore);
167 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, MakeName); 166 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, MakeName);
168 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, HashClientId); 167 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, HashClientId);
169 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, HashClientIdIsUniform); 168 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, HashClientIdIsUniform);
170 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, HashName);
171 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, NameGroupIds); 169 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, NameGroupIds);
172 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, UseOneTimeRandomization); 170 FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, UseOneTimeRandomization);
173 171
174 friend class base::FieldTrialList; 172 friend class base::FieldTrialList;
175 173
176 friend class RefCounted<FieldTrial>; 174 friend class RefCounted<FieldTrial>;
177 175
178 // This is the group number of the 'default' group when a choice wasn't forced 176 // This is the group number of the 'default' group when a choice wasn't forced
179 // by a call to FieldTrialList::CreateFieldTrial. It is kept private so that 177 // by a call to FieldTrialList::CreateFieldTrial. It is kept private so that
180 // consumers don't use it by mistake in cases where the group was forced. 178 // consumers don't use it by mistake in cases where the group was forced.
(...skipping 12 matching lines...) Expand all
193 191
194 // Returns the group_name. A winner need not have been chosen. 192 // Returns the group_name. A winner need not have been chosen.
195 std::string group_name_internal() const { return group_name_; } 193 std::string group_name_internal() const { return group_name_; }
196 194
197 // Calculates a uniformly-distributed double between [0.0, 1.0) given 195 // Calculates a uniformly-distributed double between [0.0, 1.0) given
198 // a |client_id| and a |trial_name| (the latter is used as salt to avoid 196 // a |client_id| and a |trial_name| (the latter is used as salt to avoid
199 // separate one-time randomized trials from all having the same results). 197 // separate one-time randomized trials from all having the same results).
200 static double HashClientId(const std::string& client_id, 198 static double HashClientId(const std::string& client_id,
201 const std::string& trial_name); 199 const std::string& trial_name);
202 200
203 // Creates unique identifier for the trial by hashing a name string, whether
204 // it's for the field trial or the group name.
205 static uint32 HashName(const std::string& name);
206
207 // The name of the field trial, as can be found via the FieldTrialList. 201 // The name of the field trial, as can be found via the FieldTrialList.
208 const std::string name_; 202 const std::string name_;
209 203
210 // The hashed name of the field trial to be sent as a unique identifier.
211 const uint32 name_hash_;
212
213 // The maximum sum of all probabilities supplied, which corresponds to 100%. 204 // The maximum sum of all probabilities supplied, which corresponds to 100%.
214 // This is the scaling factor used to adjust supplied probabilities. 205 // This is the scaling factor used to adjust supplied probabilities.
215 const Probability divisor_; 206 const Probability divisor_;
216 207
217 // The name of the default group. 208 // The name of the default group.
218 const std::string default_group_name_; 209 const std::string default_group_name_;
219 210
220 // The randomly selected probability that is used to select a group (or have 211 // The randomly selected probability that is used to select a group (or have
221 // the instance not participate). It is the product of divisor_ and a random 212 // the instance not participate). It is the product of divisor_ and a random
222 // number between [0, 1). 213 // number between [0, 1).
223 Probability random_; 214 Probability random_;
224 215
225 // Sum of the probabilities of all appended groups. 216 // Sum of the probabilities of all appended groups.
226 Probability accumulated_group_probability_; 217 Probability accumulated_group_probability_;
227 218
228 int next_group_number_; 219 int next_group_number_;
229 220
230 // The pseudo-randomly assigned group number. 221 // The pseudo-randomly assigned group number.
231 // This is kNotFinalized if no group has been assigned. 222 // This is kNotFinalized if no group has been assigned.
232 int group_; 223 int group_;
233 224
234 // A textual name for the randomly selected group. Valid after |group()| 225 // A textual name for the randomly selected group. Valid after |group()|
235 // has been called. 226 // has been called.
236 std::string group_name_; 227 std::string group_name_;
237 228
238 // The hashed name of the group to be sent as a unique identifier.
239 // Is not valid while group_ is equal to kNotFinalized.
240 uint32 group_name_hash_;
241
242 // When enable_field_trial_ is false, field trial reverts to the 'default' 229 // When enable_field_trial_ is false, field trial reverts to the 'default'
243 // group. 230 // group.
244 bool enable_field_trial_; 231 bool enable_field_trial_;
245 232
246 // When forced_ is true, we return the chosen group from AppendGroup when 233 // When forced_ is true, we return the chosen group from AppendGroup when
247 // appropriate. 234 // appropriate.
248 bool forced_; 235 bool forced_;
249 236
250 // When benchmarking is enabled, field trials all revert to the 'default' 237 // When benchmarking is enabled, field trials all revert to the 'default'
251 // group. 238 // group.
252 static bool enable_benchmarking_; 239 static bool enable_benchmarking_;
253 240
254 // This value is reserved for an uninitialized hash value.
255 static const uint32 kReservedHashValue;
256
257 DISALLOW_COPY_AND_ASSIGN(FieldTrial); 241 DISALLOW_COPY_AND_ASSIGN(FieldTrial);
258 }; 242 };
259 243
260 //------------------------------------------------------------------------------ 244 //------------------------------------------------------------------------------
261 // Class with a list of all active field trials. A trial is active if it has 245 // Class with a list of all active field trials. A trial is active if it has
262 // been registered, which includes evaluating its state based on its probaility. 246 // been registered, which includes evaluating its state based on its probaility.
263 // Only one instance of this class exists. 247 // Only one instance of this class exists.
264 class BASE_EXPORT FieldTrialList { 248 class BASE_EXPORT FieldTrialList {
265 public: 249 public:
266 // Define a separator character to use when creating a persistent form of an 250 // Define a separator character to use when creating a persistent form of an
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 static bool TrialExists(const std::string& name); 320 static bool TrialExists(const std::string& name);
337 321
338 // Creates a persistent representation of all FieldTrial instances for 322 // Creates a persistent representation of all FieldTrial instances for
339 // resurrection in another process. This allows randomization to be done in 323 // resurrection in another process. This allows randomization to be done in
340 // one process, and secondary processes can be synchronized on the result. 324 // one process, and secondary processes can be synchronized on the result.
341 // The resulting string contains the name and group name pairs for all trials, 325 // The resulting string contains the name and group name pairs for all trials,
342 // with "/" used to separate all names and to terminate the string. This 326 // with "/" used to separate all names and to terminate the string. This
343 // string is parsed by CreateTrialsFromString(). 327 // string is parsed by CreateTrialsFromString().
344 static void StatesToString(std::string* output); 328 static void StatesToString(std::string* output);
345 329
346 // Returns an array of Unique IDs for each Field Trial that has a chosen 330 // Fills in the supplied vector |selected_groups| (which must be empty when
347 // group. Field Trials for which a group has not been chosen yet are NOT 331 // called) with a snapshot of all existing FieldTrials for which a group has
348 // returned in this list. 332 // been chosen (if the group is not yet known, then it excluded from the
349 static void GetFieldTrialNameGroupIds( 333 // vector).
350 std::vector<FieldTrial::NameGroupId>* name_group_ids); 334 static void GetFieldTrialSelectedGroups(
335 FieldTrial::SelectedGroups* selected_groups);
351 336
352 // Use a state string (re: StatesToString()) to augment the current list of 337 // Use a state string (re: StatesToString()) to augment the current list of
353 // field tests to include the supplied tests, and using a 100% probability for 338 // field tests to include the supplied tests, and using a 100% probability for
354 // each test, force them to have the same group string. This is commonly used 339 // each test, force them to have the same group string. This is commonly used
355 // in a non-browser process, to carry randomly selected state in a browser 340 // in a non-browser process, to carry randomly selected state in a browser
356 // process into this non-browser process, but could also be invoked through a 341 // process into this non-browser process, but could also be invoked through a
357 // command line argument to the browser process. 342 // command line argument to the browser process.
358 static bool CreateTrialsFromString(const std::string& prior_trials); 343 static bool CreateTrialsFromString(const std::string& prior_trials);
359 344
360 // Create a FieldTrial with the given |name| and using 100% probability for 345 // Create a FieldTrial with the given |name| and using 100% probability for
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 424
440 // List of observers to be notified when a group is selected for a FieldTrial. 425 // List of observers to be notified when a group is selected for a FieldTrial.
441 ObserverList<Observer> observer_list_; 426 ObserverList<Observer> observer_list_;
442 427
443 DISALLOW_COPY_AND_ASSIGN(FieldTrialList); 428 DISALLOW_COPY_AND_ASSIGN(FieldTrialList);
444 }; 429 };
445 430
446 } // namespace base 431 } // namespace base
447 432
448 #endif // BASE_METRICS_FIELD_TRIAL_H_ 433 #endif // BASE_METRICS_FIELD_TRIAL_H_
OLDNEW
« no previous file with comments | « no previous file | base/metrics/field_trial.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698