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

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

Issue 23710041: Fix inconsistent FieldTrial group assignment due to float errors. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 3 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 | « base/metrics/field_trial.h ('k') | base/metrics/field_trial_unittest.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 #include "base/metrics/field_trial.h" 5 #include "base/metrics/field_trial.h"
6 6
7 #include <algorithm>
8
7 #include "base/build_time.h" 9 #include "base/build_time.h"
8 #include "base/logging.h" 10 #include "base/logging.h"
9 #include "base/rand_util.h" 11 #include "base/rand_util.h"
10 #include "base/sha1.h" 12 #include "base/sha1.h"
11 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
13 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
14 #include "base/sys_byteorder.h" 16 #include "base/sys_byteorder.h"
15 17
16 namespace base { 18 namespace base {
(...skipping 14 matching lines...) Expand all
31 exploded.day_of_week = 0; // Should be unused. 33 exploded.day_of_week = 0; // Should be unused.
32 exploded.day_of_month = day_of_month; 34 exploded.day_of_month = day_of_month;
33 exploded.hour = 0; 35 exploded.hour = 0;
34 exploded.minute = 0; 36 exploded.minute = 0;
35 exploded.second = 0; 37 exploded.second = 0;
36 exploded.millisecond = 0; 38 exploded.millisecond = 0;
37 39
38 return Time::FromLocalExploded(exploded); 40 return Time::FromLocalExploded(exploded);
39 } 41 }
40 42
43 // Returns the boundary value for comparing against the FieldTrial's added
44 // groups for a given |divisor| (total probability) and |entropy_value|.
45 FieldTrial::Probability GetGroupBoundaryValue(
46 FieldTrial::Probability divisor,
47 double entropy_value) {
48 // Add a tiny epsilon value to get consistent results when converting floating
49 // points to int. Without it, boundary values have inconsistent results, e.g.:
50 //
51 // static_cast<FieldTrial::Probability>(100 * 0.56) == 56
52 // static_cast<FieldTrial::Probability>(100 * 0.57) == 56
53 // static_cast<FieldTrial::Probability>(100 * 0.58) == 57
54 // static_cast<FieldTrial::Probability>(100 * 0.59) == 59
55 const double kEpsilon = 1e-8;
56 const FieldTrial::Probability result =
57 static_cast<FieldTrial::Probability>(divisor * entropy_value + kEpsilon);
58 // Ensure that adding the epsilon still results in a value < |divisor|.
59 return std::min(result, divisor - 1);
60 }
61
41 } // namespace 62 } // namespace
42 63
43 static const char kHistogramFieldTrialSeparator('_');
44
45 // statics 64 // statics
46 const int FieldTrial::kNotFinalized = -1; 65 const int FieldTrial::kNotFinalized = -1;
47 const int FieldTrial::kDefaultGroupNumber = 0; 66 const int FieldTrial::kDefaultGroupNumber = 0;
48 bool FieldTrial::enable_benchmarking_ = false; 67 bool FieldTrial::enable_benchmarking_ = false;
49 68
50 const char FieldTrialList::kPersistentStringSeparator('/'); 69 const char FieldTrialList::kPersistentStringSeparator('/');
51 int FieldTrialList::kNoExpirationYear = 0; 70 int FieldTrialList::kNoExpirationYear = 0;
52 71
53 //------------------------------------------------------------------------------ 72 //------------------------------------------------------------------------------
54 // FieldTrial methods and members. 73 // FieldTrial methods and members.
55 74
56 FieldTrial::FieldTrial(const std::string& trial_name, 75 FieldTrial::FieldTrial(const std::string& trial_name,
57 const Probability total_probability, 76 const Probability total_probability,
58 const std::string& default_group_name, 77 const std::string& default_group_name,
59 double entropy_value) 78 double entropy_value)
60 : trial_name_(trial_name), 79 : trial_name_(trial_name),
61 divisor_(total_probability), 80 divisor_(total_probability),
62 default_group_name_(default_group_name), 81 default_group_name_(default_group_name),
63 random_(static_cast<Probability>(divisor_ * entropy_value)), 82 random_(GetGroupBoundaryValue(total_probability, entropy_value)),
64 accumulated_group_probability_(0), 83 accumulated_group_probability_(0),
65 next_group_number_(kDefaultGroupNumber + 1), 84 next_group_number_(kDefaultGroupNumber + 1),
66 group_(kNotFinalized), 85 group_(kNotFinalized),
67 enable_field_trial_(true), 86 enable_field_trial_(true),
68 forced_(false), 87 forced_(false),
69 group_reported_(false) { 88 group_reported_(false) {
70 DCHECK_GT(total_probability, 0); 89 DCHECK_GT(total_probability, 0);
71 DCHECK(!trial_name_.empty()); 90 DCHECK(!trial_name_.empty());
72 DCHECK(!default_group_name_.empty()); 91 DCHECK(!default_group_name_.empty());
73 } 92 }
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 used_without_global_ = true; 507 used_without_global_ = true;
489 return; 508 return;
490 } 509 }
491 AutoLock auto_lock(global_->lock_); 510 AutoLock auto_lock(global_->lock_);
492 DCHECK(!global_->PreLockedFind(trial->trial_name())); 511 DCHECK(!global_->PreLockedFind(trial->trial_name()));
493 trial->AddRef(); 512 trial->AddRef();
494 global_->registered_[trial->trial_name()] = trial; 513 global_->registered_[trial->trial_name()] = trial;
495 } 514 }
496 515
497 } // namespace base 516 } // namespace base
OLDNEW
« no previous file with comments | « base/metrics/field_trial.h ('k') | base/metrics/field_trial_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698