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

Side by Side Diff: chrome/common/metrics/variations_util.cc

Issue 10828314: Move Variations stuff into variations/ directories and add OWNERS files for the variations client t… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Add OWNERS files Created 8 years, 4 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/common/metrics/variations_util.h"
6
7 #include <map>
8 #include <vector>
9
10 #include "base/memory/singleton.h"
11 #include "base/sha1.h"
12 #include "base/string16.h"
13 #include "base/stringprintf.h"
14 #include "base/sys_byteorder.h"
15 #include "base/utf_string_conversions.h"
16 #include "chrome/common/child_process_logging.h"
17 #include "chrome/common/metrics/variation_ids.h"
18
19 namespace {
20
21 // The internal singleton accessor for the map, used to keep it thread-safe.
22 class GroupMapAccessor {
23 public:
24 // Retrieve the singleton.
25 static GroupMapAccessor* GetInstance() {
26 return Singleton<GroupMapAccessor>::get();
27 }
28
29 GroupMapAccessor() {}
30 ~GroupMapAccessor() {}
31
32 // Note that this normally only sets the ID for a group the first time, unless
33 // |force| is set to true, in which case it will always override it.
34 void AssociateID(const chrome_variations::SelectedGroupId& group_identifier,
35 chrome_variations::VariationID id,
36 const bool force) {
37 base::AutoLock scoped_lock(lock_);
38 if (force ||
39 group_to_id_map_.find(group_identifier) == group_to_id_map_.end())
40 group_to_id_map_[group_identifier] = id;
41 }
42
43 chrome_variations::VariationID GetID(
44 const chrome_variations::SelectedGroupId& group_identifier) {
45 base::AutoLock scoped_lock(lock_);
46 GroupToIDMap::const_iterator it = group_to_id_map_.find(group_identifier);
47 if (it == group_to_id_map_.end())
48 return chrome_variations::kEmptyID;
49 return it->second;
50 }
51
52 private:
53 typedef std::map<chrome_variations::SelectedGroupId,
54 chrome_variations::VariationID,
55 chrome_variations::SelectedGroupIdCompare> GroupToIDMap;
56
57 base::Lock lock_;
58 GroupToIDMap group_to_id_map_;
59 };
60
61 // Creates unique identifier for the trial by hashing a name string, whether
62 // it's for the field trial or the group name.
63 uint32 HashName(const std::string& name) {
64 // SHA-1 is designed to produce a uniformly random spread in its output space,
65 // even for nearly-identical inputs.
66 unsigned char sha1_hash[base::kSHA1Length];
67 base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(name.c_str()),
68 name.size(),
69 sha1_hash);
70
71 COMPILE_ASSERT(sizeof(uint32) < sizeof(sha1_hash), need_more_data);
72 uint32 bits;
73 memcpy(&bits, sha1_hash, sizeof(bits));
74
75 return base::ByteSwapToLE32(bits);
76 }
77
78 chrome_variations::SelectedGroupId MakeSelectedGroupId(
79 const std::string& trial_name,
80 const std::string& group_name) {
81 chrome_variations::SelectedGroupId id;
82 id.name = HashName(trial_name);
83 id.group = HashName(group_name);
84 return id;
85 }
86
87 // Populates |name_group_ids| based on |selected_groups|.
88 void GetFieldTrialSelectedGroupIdsForSelectedGroups(
89 const base::FieldTrial::SelectedGroups& selected_groups,
90 std::vector<chrome_variations::SelectedGroupId>* name_group_ids) {
91 DCHECK(name_group_ids->empty());
92 for (base::FieldTrial::SelectedGroups::const_iterator it =
93 selected_groups.begin(); it != selected_groups.end(); ++it) {
94 name_group_ids->push_back(MakeSelectedGroupId(it->trial, it->group));
95 }
96 }
97
98 } // namespace
99
100 namespace chrome_variations {
101
102 void GetFieldTrialSelectedGroupIds(
103 std::vector<SelectedGroupId>* name_group_ids) {
104 DCHECK(name_group_ids->empty());
105 // A note on thread safety: Since GetFieldTrialSelectedGroups is thread
106 // safe, and we operate on a separate list of that data, this function is
107 // technically thread safe as well, with respect to the FieldTriaList data.
108 base::FieldTrial::SelectedGroups selected_groups;
109 base::FieldTrialList::GetFieldTrialSelectedGroups(&selected_groups);
110 GetFieldTrialSelectedGroupIdsForSelectedGroups(selected_groups,
111 name_group_ids);
112 }
113
114 void AssociateGoogleVariationID(const std::string& trial_name,
115 const std::string& group_name,
116 chrome_variations::VariationID id) {
117 GroupMapAccessor::GetInstance()->AssociateID(
118 MakeSelectedGroupId(trial_name, group_name), id, false);
119 }
120
121 void AssociateGoogleVariationIDForce(const std::string& trial_name,
122 const std::string& group_name,
123 chrome_variations::VariationID id) {
124 GroupMapAccessor::GetInstance()->AssociateID(
125 MakeSelectedGroupId(trial_name, group_name), id, true);
126 }
127
128 chrome_variations::VariationID GetGoogleVariationID(
129 const std::string& trial_name,
130 const std::string& group_name) {
131 return GroupMapAccessor::GetInstance()->GetID(
132 MakeSelectedGroupId(trial_name, group_name));
133 }
134
135 void GenerateVariationChunks(const std::vector<string16>& experiments,
136 std::vector<string16>* chunks) {
137 string16 current_chunk;
138 for (size_t i = 0; i < experiments.size(); ++i) {
139 const size_t needed_length =
140 (current_chunk.empty() ? 1 : 0) + experiments[i].length();
141 if (current_chunk.length() + needed_length > kMaxVariationChunkSize) {
142 chunks->push_back(current_chunk);
143 current_chunk = experiments[i];
144 } else {
145 if (!current_chunk.empty())
146 current_chunk.push_back(',');
147 current_chunk += experiments[i];
148 }
149 }
150 if (!current_chunk.empty())
151 chunks->push_back(current_chunk);
152 }
153
154 void SetChildProcessLoggingVariationList() {
155 std::vector<SelectedGroupId> name_group_ids;
156 GetFieldTrialSelectedGroupIds(&name_group_ids);
157 std::vector<string16> experiment_strings(name_group_ids.size());
158 for (size_t i = 0; i < name_group_ids.size(); ++i) {
159 experiment_strings[i] = UTF8ToUTF16(base::StringPrintf(
160 "%x-%x", name_group_ids[i].name, name_group_ids[i].group));
161 }
162 child_process_logging::SetExperimentList(experiment_strings);
163 }
164
165 } // namespace chrome_variations
166
167 // Functions below are exposed for testing explicitly behind this namespace.
168 // They simply wrap existing functions in this file.
169 namespace testing {
170
171 void TestGetFieldTrialSelectedGroupIdsForSelectedGroups(
172 const base::FieldTrial::SelectedGroups& selected_groups,
173 std::vector<chrome_variations::SelectedGroupId>* name_group_ids) {
174 ::GetFieldTrialSelectedGroupIdsForSelectedGroups(selected_groups,
175 name_group_ids);
176 }
177
178 uint32 TestHashName(const std::string& name) {
179 return ::HashName(name);
180 }
181
182 } // namespace testing
OLDNEW
« no previous file with comments | « chrome/common/metrics/variations_util.h ('k') | chrome/common/metrics/variations_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698