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

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

Issue 2633383002: Change FieldTrial::State to not use StringPiece members. (Closed)
Patch Set: Created 3 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
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> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/base_switches.h" 10 #include "base/base_switches.h"
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 if (!pickle->WriteString(string2)) 76 if (!pickle->WriteString(string2))
77 return false; 77 return false;
78 return true; 78 return true;
79 } 79 }
80 80
81 // Writes out the field trial's contents (via trial_state) to the pickle. The 81 // Writes out the field trial's contents (via trial_state) to the pickle. The
82 // format of the pickle looks like: 82 // format of the pickle looks like:
83 // TrialName, GroupName, ParamKey1, ParamValue1, ParamKey2, ParamValue2, ... 83 // TrialName, GroupName, ParamKey1, ParamValue1, ParamKey2, ParamValue2, ...
84 // If there are no parameters, then it just ends at GroupName. 84 // If there are no parameters, then it just ends at GroupName.
85 bool PickleFieldTrial(const FieldTrial::State& trial_state, Pickle* pickle) { 85 bool PickleFieldTrial(const FieldTrial::State& trial_state, Pickle* pickle) {
86 if (!WriteStringPair(pickle, trial_state.trial_name, trial_state.group_name)) 86 if (!WriteStringPair(pickle, *trial_state.trial_name,
87 *trial_state.group_name)) {
87 return false; 88 return false;
89 }
88 90
89 // Get field trial params. 91 // Get field trial params.
90 std::map<std::string, std::string> params; 92 std::map<std::string, std::string> params;
91 FieldTrialParamAssociator::GetInstance()->GetFieldTrialParamsWithoutFallback( 93 FieldTrialParamAssociator::GetInstance()->GetFieldTrialParamsWithoutFallback(
92 trial_state.trial_name.as_string(), trial_state.group_name.as_string(), 94 *trial_state.trial_name, *trial_state.group_name, &params);
93 &params);
94 95
95 // Write params to pickle. 96 // Write params to pickle.
96 for (const auto& param : params) { 97 for (const auto& param : params) {
97 if (!WriteStringPair(pickle, param.first, param.second)) 98 if (!WriteStringPair(pickle, param.first, param.second))
98 return false; 99 return false;
99 } 100 }
100 return true; 101 return true;
101 } 102 }
102 103
103 // Created a time value based on |year|, |month| and |day_of_month| parameters. 104 // Created a time value based on |year|, |month| and |day_of_month| parameters.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 // static_cast<FieldTrial::Probability>(100 * 0.57) == 56 140 // static_cast<FieldTrial::Probability>(100 * 0.57) == 56
140 // static_cast<FieldTrial::Probability>(100 * 0.58) == 57 141 // static_cast<FieldTrial::Probability>(100 * 0.58) == 57
141 // static_cast<FieldTrial::Probability>(100 * 0.59) == 59 142 // static_cast<FieldTrial::Probability>(100 * 0.59) == 59
142 const double kEpsilon = 1e-8; 143 const double kEpsilon = 1e-8;
143 const FieldTrial::Probability result = 144 const FieldTrial::Probability result =
144 static_cast<FieldTrial::Probability>(divisor * entropy_value + kEpsilon); 145 static_cast<FieldTrial::Probability>(divisor * entropy_value + kEpsilon);
145 // Ensure that adding the epsilon still results in a value < |divisor|. 146 // Ensure that adding the epsilon still results in a value < |divisor|.
146 return std::min(result, divisor - 1); 147 return std::min(result, divisor - 1);
147 } 148 }
148 149
150 // Separate type from FieldTrial::State so that it can use StringPieces.
151 struct FieldTrialStringEntry {
152 StringPiece trial_name;
153 StringPiece group_name;
154 bool activated;
155 };
156
149 // Parses the --force-fieldtrials string |trials_string| into |entries|. 157 // Parses the --force-fieldtrials string |trials_string| into |entries|.
150 // Returns true if the string was parsed correctly. On failure, the |entries| 158 // Returns true if the string was parsed correctly. On failure, the |entries|
151 // array may end up being partially filled. 159 // array may end up being partially filled.
152 bool ParseFieldTrialsString(const std::string& trials_string, 160 bool ParseFieldTrialsString(const std::string& trials_string,
153 std::vector<FieldTrial::State>* entries) { 161 std::vector<FieldTrialStringEntry>* entries) {
154 const StringPiece trials_string_piece(trials_string); 162 const StringPiece trials_string_piece(trials_string);
155 163
156 size_t next_item = 0; 164 size_t next_item = 0;
157 while (next_item < trials_string.length()) { 165 while (next_item < trials_string.length()) {
158 size_t name_end = trials_string.find(kPersistentStringSeparator, next_item); 166 size_t name_end = trials_string.find(kPersistentStringSeparator, next_item);
159 if (name_end == trials_string.npos || next_item == name_end) 167 if (name_end == trials_string.npos || next_item == name_end)
160 return false; 168 return false;
161 size_t group_name_end = 169 size_t group_name_end =
162 trials_string.find(kPersistentStringSeparator, name_end + 1); 170 trials_string.find(kPersistentStringSeparator, name_end + 1);
163 if (name_end + 1 == group_name_end) 171 if (name_end + 1 == group_name_end)
164 return false; 172 return false;
165 if (group_name_end == trials_string.npos) 173 if (group_name_end == trials_string.npos)
166 group_name_end = trials_string.length(); 174 group_name_end = trials_string.length();
167 175
168 FieldTrial::State entry; 176 FieldTrialStringEntry entry;
169 // Verify if the trial should be activated or not. 177 // Verify if the trial should be activated or not.
170 if (trials_string[next_item] == kActivationMarker) { 178 if (trials_string[next_item] == kActivationMarker) {
171 // Name cannot be only the indicator. 179 // Name cannot be only the indicator.
172 if (name_end - next_item == 1) 180 if (name_end - next_item == 1)
173 return false; 181 return false;
174 next_item++; 182 next_item++;
175 entry.activated = true; 183 entry.activated = true;
176 } 184 }
177 entry.trial_name = 185 entry.trial_name =
178 trials_string_piece.substr(next_item, name_end - next_item); 186 trials_string_piece.substr(next_item, name_end - next_item);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 bool FieldTrial::enable_benchmarking_ = false; 243 bool FieldTrial::enable_benchmarking_ = false;
236 244
237 int FieldTrialList::kNoExpirationYear = 0; 245 int FieldTrialList::kNoExpirationYear = 0;
238 246
239 //------------------------------------------------------------------------------ 247 //------------------------------------------------------------------------------
240 // FieldTrial methods and members. 248 // FieldTrial methods and members.
241 249
242 FieldTrial::EntropyProvider::~EntropyProvider() { 250 FieldTrial::EntropyProvider::~EntropyProvider() {
243 } 251 }
244 252
245 FieldTrial::State::State() : activated(false) {} 253 FieldTrial::State::State()
254 : trial_name(nullptr), group_name(nullptr), activated(false) {}
brucedawson 2017/01/24 00:44:14 See comment in header file and consider removing t
Alexei Svitkine (slow) 2017/01/24 16:40:19 Done.
246 255
247 FieldTrial::State::State(const State& other) = default; 256 FieldTrial::State::State(const State& other) = default;
248 257
249 FieldTrial::State::~State() {} 258 FieldTrial::State::~State() {}
250 259
251 bool FieldTrial::FieldTrialEntry::GetTrialAndGroupName( 260 bool FieldTrial::FieldTrialEntry::GetTrialAndGroupName(
252 StringPiece* trial_name, 261 StringPiece* trial_name,
253 StringPiece* group_name) const { 262 StringPiece* group_name) const {
254 PickleIterator iter = GetPickleIterator(); 263 PickleIterator iter = GetPickleIterator();
255 return ReadStringPair(&iter, trial_name, group_name); 264 return ReadStringPair(&iter, trial_name, group_name);
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 DCHECK_NE(group_, kNotFinalized); 458 DCHECK_NE(group_, kNotFinalized);
450 active_group->trial_name = trial_name_; 459 active_group->trial_name = trial_name_;
451 active_group->group_name = group_name_; 460 active_group->group_name = group_name_;
452 return true; 461 return true;
453 } 462 }
454 463
455 bool FieldTrial::GetState(State* field_trial_state) { 464 bool FieldTrial::GetState(State* field_trial_state) {
456 if (!enable_field_trial_) 465 if (!enable_field_trial_)
457 return false; 466 return false;
458 FinalizeGroupChoice(); 467 FinalizeGroupChoice();
459 field_trial_state->trial_name = trial_name_; 468 field_trial_state->trial_name = &trial_name_;
460 field_trial_state->group_name = group_name_; 469 field_trial_state->group_name = &group_name_;
461 field_trial_state->activated = group_reported_; 470 field_trial_state->activated = group_reported_;
462 return true; 471 return true;
463 } 472 }
464 473
465 bool FieldTrial::GetStateWhileLocked(State* field_trial_state) { 474 bool FieldTrial::GetStateWhileLocked(State* field_trial_state) {
466 if (!enable_field_trial_) 475 if (!enable_field_trial_)
467 return false; 476 return false;
468 FinalizeGroupChoiceImpl(true); 477 FinalizeGroupChoiceImpl(true);
469 field_trial_state->trial_name = trial_name_; 478 field_trial_state->trial_name = &trial_name_;
470 field_trial_state->group_name = group_name_; 479 field_trial_state->group_name = &group_name_;
471 field_trial_state->activated = group_reported_; 480 field_trial_state->activated = group_reported_;
472 return true; 481 return true;
473 } 482 }
474 483
475 //------------------------------------------------------------------------------ 484 //------------------------------------------------------------------------------
476 // FieldTrialList methods and members. 485 // FieldTrialList methods and members.
477 486
478 // static 487 // static
479 FieldTrialList* FieldTrialList::global_ = NULL; 488 FieldTrialList* FieldTrialList::global_ = NULL;
480 489
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 void FieldTrialList::AllStatesToString(std::string* output) { 657 void FieldTrialList::AllStatesToString(std::string* output) {
649 if (!global_) 658 if (!global_)
650 return; 659 return;
651 AutoLock auto_lock(global_->lock_); 660 AutoLock auto_lock(global_->lock_);
652 661
653 for (const auto& registered : global_->registered_) { 662 for (const auto& registered : global_->registered_) {
654 FieldTrial::State trial; 663 FieldTrial::State trial;
655 if (!registered.second->GetStateWhileLocked(&trial)) 664 if (!registered.second->GetStateWhileLocked(&trial))
656 continue; 665 continue;
657 DCHECK_EQ(std::string::npos, 666 DCHECK_EQ(std::string::npos,
658 trial.trial_name.find(kPersistentStringSeparator)); 667 trial.trial_name->find(kPersistentStringSeparator));
659 DCHECK_EQ(std::string::npos, 668 DCHECK_EQ(std::string::npos,
660 trial.group_name.find(kPersistentStringSeparator)); 669 trial.group_name->find(kPersistentStringSeparator));
661 if (trial.activated) 670 if (trial.activated)
662 output->append(1, kActivationMarker); 671 output->append(1, kActivationMarker);
663 trial.trial_name.AppendToString(output); 672 output->append(*trial.trial_name);
brucedawson 2017/01/24 00:44:14 This reads much cleaner, as a minor side effect.
Alexei Svitkine (slow) 2017/01/24 16:40:19 Acknowledged.
664 output->append(1, kPersistentStringSeparator); 673 output->append(1, kPersistentStringSeparator);
665 trial.group_name.AppendToString(output); 674 output->append(*trial.group_name);
666 output->append(1, kPersistentStringSeparator); 675 output->append(1, kPersistentStringSeparator);
667 } 676 }
668 } 677 }
669 678
670 // static 679 // static
671 void FieldTrialList::GetActiveFieldTrialGroups( 680 void FieldTrialList::GetActiveFieldTrialGroups(
672 FieldTrial::ActiveGroups* active_groups) { 681 FieldTrial::ActiveGroups* active_groups) {
673 DCHECK(active_groups->empty()); 682 DCHECK(active_groups->empty());
674 if (!global_) 683 if (!global_)
675 return; 684 return;
676 AutoLock auto_lock(global_->lock_); 685 AutoLock auto_lock(global_->lock_);
677 686
678 for (RegistrationMap::iterator it = global_->registered_.begin(); 687 for (RegistrationMap::iterator it = global_->registered_.begin();
679 it != global_->registered_.end(); ++it) { 688 it != global_->registered_.end(); ++it) {
680 FieldTrial::ActiveGroup active_group; 689 FieldTrial::ActiveGroup active_group;
681 if (it->second->GetActiveGroup(&active_group)) 690 if (it->second->GetActiveGroup(&active_group))
682 active_groups->push_back(active_group); 691 active_groups->push_back(active_group);
683 } 692 }
684 } 693 }
685 694
686 // static 695 // static
687 void FieldTrialList::GetActiveFieldTrialGroupsFromString( 696 void FieldTrialList::GetActiveFieldTrialGroupsFromString(
688 const std::string& trials_string, 697 const std::string& trials_string,
689 FieldTrial::ActiveGroups* active_groups) { 698 FieldTrial::ActiveGroups* active_groups) {
690 std::vector<FieldTrial::State> entries; 699 std::vector<FieldTrialStringEntry> entries;
691 if (!ParseFieldTrialsString(trials_string, &entries)) 700 if (!ParseFieldTrialsString(trials_string, &entries))
692 return; 701 return;
693 702
694 for (const auto& entry : entries) { 703 for (const auto& entry : entries) {
695 if (entry.activated) { 704 if (entry.activated) {
696 FieldTrial::ActiveGroup group; 705 FieldTrial::ActiveGroup group;
697 group.trial_name = entry.trial_name.as_string(); 706 group.trial_name = entry.trial_name.as_string();
698 group.group_name = entry.group_name.as_string(); 707 group.group_name = entry.group_name.as_string();
699 active_groups->push_back(group); 708 active_groups->push_back(group);
700 } 709 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 } 741 }
733 742
734 // static 743 // static
735 bool FieldTrialList::CreateTrialsFromString( 744 bool FieldTrialList::CreateTrialsFromString(
736 const std::string& trials_string, 745 const std::string& trials_string,
737 const std::set<std::string>& ignored_trial_names) { 746 const std::set<std::string>& ignored_trial_names) {
738 DCHECK(global_); 747 DCHECK(global_);
739 if (trials_string.empty() || !global_) 748 if (trials_string.empty() || !global_)
740 return true; 749 return true;
741 750
742 std::vector<FieldTrial::State> entries; 751 std::vector<FieldTrialStringEntry> entries;
743 if (!ParseFieldTrialsString(trials_string, &entries)) 752 if (!ParseFieldTrialsString(trials_string, &entries))
744 return false; 753 return false;
745 754
746 for (const auto& entry : entries) { 755 for (const auto& entry : entries) {
747 const std::string trial_name = entry.trial_name.as_string(); 756 const std::string trial_name = entry.trial_name.as_string();
748 const std::string group_name = entry.group_name.as_string(); 757 const std::string group_name = entry.group_name.as_string();
749 758
750 if (ContainsKey(ignored_trial_names, trial_name)) 759 if (ContainsKey(ignored_trial_names, trial_name))
751 continue; 760 continue;
752 761
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after
1343 return; 1352 return;
1344 } 1353 }
1345 AutoLock auto_lock(global_->lock_); 1354 AutoLock auto_lock(global_->lock_);
1346 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); 1355 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name();
1347 trial->AddRef(); 1356 trial->AddRef();
1348 trial->SetTrialRegistered(); 1357 trial->SetTrialRegistered();
1349 global_->registered_[trial->trial_name()] = trial; 1358 global_->registered_[trial->trial_name()] = trial;
1350 } 1359 }
1351 1360
1352 } // namespace base 1361 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698