1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/variations/processed_study.h"
10 #include "base/version.h"
11 #include "components/variations/proto/study.pb.h"
13 namespace variations
{
17 // Validates the sanity of |study| and computes the total probability.
18 bool ValidateStudyAndComputeTotalProbability(
20 base::FieldTrial::Probability
* total_probability
) {
21 // At the moment, a missing default_experiment_name makes the study invalid.
22 if (study
.default_experiment_name().empty()) {
23 DVLOG(1) << study
.name() << " has no default experiment defined.";
26 if (study
.filter().has_min_version() &&
27 !Version::IsValidWildcardString(study
.filter().min_version())) {
28 DVLOG(1) << study
.name() << " has invalid min version: "
29 << study
.filter().min_version();
32 if (study
.filter().has_max_version() &&
33 !Version::IsValidWildcardString(study
.filter().max_version())) {
34 DVLOG(1) << study
.name() << " has invalid max version: "
35 << study
.filter().max_version();
39 const std::string
& default_group_name
= study
.default_experiment_name();
40 base::FieldTrial::Probability divisor
= 0;
42 bool found_default_group
= false;
43 std::set
<std::string
> experiment_names
;
44 for (int i
= 0; i
< study
.experiment_size(); ++i
) {
45 if (study
.experiment(i
).name().empty()) {
46 DVLOG(1) << study
.name() << " is missing experiment " << i
<< " name";
49 if (!experiment_names
.insert(study
.experiment(i
).name()).second
) {
50 DVLOG(1) << study
.name() << " has a repeated experiment name "
51 << study
.experiment(i
).name();
55 if (!study
.experiment(i
).has_forcing_flag())
56 divisor
+= study
.experiment(i
).probability_weight();
57 if (study
.experiment(i
).name() == default_group_name
)
58 found_default_group
= true;
61 if (!found_default_group
) {
62 DVLOG(1) << study
.name() << " is missing default experiment in its "
64 // The default group was not found in the list of groups. This study is not
69 *total_probability
= divisor
;
77 ProcessedStudy::ProcessedStudy()
78 : study_(NULL
), total_probability_(0), is_expired_(false) {
81 ProcessedStudy::~ProcessedStudy() {
84 bool ProcessedStudy::Init(const Study
* study
, bool is_expired
) {
85 base::FieldTrial::Probability total_probability
= 0;
86 if (!ValidateStudyAndComputeTotalProbability(*study
, &total_probability
))
90 is_expired_
= is_expired
;
91 total_probability_
= total_probability
;
95 int ProcessedStudy::GetExperimentIndexByName(const std::string
& name
) const {
96 for (int i
= 0; i
< study_
->experiment_size(); ++i
) {
97 if (study_
->experiment(i
).name() == name
)
105 bool ProcessedStudy::ValidateAndAppendStudy(
108 std::vector
<ProcessedStudy
>* processed_studies
) {
109 ProcessedStudy processed_study
;
110 if (processed_study
.Init(study
, is_expired
)) {
111 processed_studies
->push_back(processed_study
);
117 } // namespace variations