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

Side by Side Diff: components/safe_browsing_db/v4_store.cc

Issue 2409793002: Add detailed UMA metrics for v4_store, broken down by storeid. (Closed)
Patch Set: git pull Created 4 years, 2 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/base64.h" 5 #include "base/base64.h"
6 #include "base/bind.h" 6 #include "base/bind.h"
7 #include "base/files/file_util.h" 7 #include "base/files/file_util.h"
8 #include "base/memory/ptr_util.h" 8 #include "base/memory/ptr_util.h"
9 #include "base/metrics/histogram_macros.h" 9 #include "base/metrics/histogram_macros.h"
10 #include "base/metrics/sparse_histogram.h" 10 #include "base/metrics/sparse_histogram.h"
11 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "base/strings/stringprintf.h" 12 #include "base/strings/stringprintf.h"
13 #include "components/safe_browsing_db/v4_rice.h" 13 #include "components/safe_browsing_db/v4_rice.h"
14 #include "components/safe_browsing_db/v4_store.h" 14 #include "components/safe_browsing_db/v4_store.h"
15 #include "components/safe_browsing_db/v4_store.pb.h" 15 #include "components/safe_browsing_db/v4_store.pb.h"
16 #include "crypto/secure_hash.h" 16 #include "crypto/secure_hash.h"
17 #include "crypto/sha2.h" 17 #include "crypto/sha2.h"
18 18
19 using base::TimeTicks; 19 using base::TimeTicks;
20 20
21 namespace safe_browsing { 21 namespace safe_browsing {
22 22
23 namespace { 23 namespace {
24 24
25 // UMA related strings.
26 const char kDecodeAdditions[] = ".DecodeAdditions";
Nathan Parker 2016/10/11 20:51:48 I think it'd be clearer to group these into suffix
vakh (use Gerrit instead) 2016/10/11 23:08:05 Done.
27 const char kDecodeRemovals[] = ".DecodeRemovals";
28 const char kProcessFullUpdate[] = "SafeBrowsing.V4ProcessFullUpdate";
29 const char kProcessPartialUpdate[] = "SafeBrowsing.V4ProcessPartialUpdate";
30 const char kReadFromDisk[] = "SafeBrowsing.V4ReadFromDisk";
31 const char kResult[] = ".Result";
32 const char kTime[] = ".Time";
33
25 const uint32_t kFileMagic = 0x600D71FE; 34 const uint32_t kFileMagic = 0x600D71FE;
26
27 const uint32_t kFileVersion = 9; 35 const uint32_t kFileVersion = 9;
28 36
29 std::string GetUmaSuffixForStore(const base::FilePath& file_path) { 37 std::string GetUmaSuffixForStore(const base::FilePath& file_path) {
30 return base::StringPrintf( 38 return base::StringPrintf(
31 ".%" PRIsFP, file_path.BaseName().RemoveExtension().value().c_str()); 39 ".%" PRIsFP, file_path.BaseName().RemoveExtension().value().c_str());
32 } 40 }
33 41
34 void RecordTimeWithAndWithoutStore(const std::string& metric, 42 void RecordTimeWithAndWithoutSuffix(const std::string& metric,
35 base::TimeDelta time, 43 base::TimeDelta time,
36 const base::FilePath& file_path) { 44 const base::FilePath& file_path) {
37 // The histograms below are a modified expansion of the 45 // The histograms below are a modified expansion of the
38 // UMA_HISTOGRAM_LONG_TIMES macro adapted to allow for a dynamically suffixed 46 // UMA_HISTOGRAM_LONG_TIMES macro adapted to allow for a dynamically suffixed
39 // histogram name. 47 // histogram name.
40 // Note: The factory creates and owns the histogram. 48 // Note: The factory creates and owns the histogram.
41 const int kBucketCount = 100; 49 const int kBucketCount = 100;
42 base::HistogramBase* histogram = base::Histogram::FactoryTimeGet( 50 base::HistogramBase* histogram = base::Histogram::FactoryTimeGet(
43 metric, base::TimeDelta::FromMilliseconds(1), 51 metric + kTime, base::TimeDelta::FromMilliseconds(1),
44 base::TimeDelta::FromMinutes(1), kBucketCount, 52 base::TimeDelta::FromMinutes(1), kBucketCount,
45 base::HistogramBase::kUmaTargetedHistogramFlag); 53 base::HistogramBase::kUmaTargetedHistogramFlag);
46 if (histogram) { 54 if (histogram) {
47 histogram->AddTime(time); 55 histogram->AddTime(time);
48 } 56 }
49 57
50 std::string suffix = GetUmaSuffixForStore(file_path); 58 std::string suffix = GetUmaSuffixForStore(file_path);
51 base::HistogramBase* histogram_suffix = base::Histogram::FactoryTimeGet( 59 base::HistogramBase* histogram_suffix = base::Histogram::FactoryTimeGet(
52 metric + suffix, base::TimeDelta::FromMilliseconds(1), 60 metric + suffix + kTime, base::TimeDelta::FromMilliseconds(1),
53 base::TimeDelta::FromMinutes(1), kBucketCount, 61 base::TimeDelta::FromMinutes(1), kBucketCount,
54 base::HistogramBase::kUmaTargetedHistogramFlag); 62 base::HistogramBase::kUmaTargetedHistogramFlag);
55 if (histogram_suffix) { 63 if (histogram_suffix) {
56 histogram_suffix->AddTime(time); 64 histogram_suffix->AddTime(time);
57 } 65 }
58 } 66 }
59 67
68 void RecordEnumWithAndWithoutSuffix(const std::string& metric,
69 int32_t value,
70 int32_t maximum,
71 const base::FilePath& file_path) {
72 // The histograms below are an expansion of the UMA_HISTOGRAM_ENUMERATION
73 // macro adapted to allow for a dynamically suffixed histogram name.
74 // Note: The factory creates and owns the histogram.
75 base::HistogramBase* histogram = base::LinearHistogram::FactoryGet(
76 metric + kResult, 1, maximum, maximum + 1,
77 base::HistogramBase::kUmaTargetedHistogramFlag);
78 if (histogram) {
79 histogram->Add(value);
80 }
81
82 std::string suffix = GetUmaSuffixForStore(file_path);
83 base::HistogramBase* histogram_suffix = base::LinearHistogram::FactoryGet(
84 metric + suffix + kResult, 1, maximum, maximum + 1,
85 base::HistogramBase::kUmaTargetedHistogramFlag);
86 if (histogram_suffix) {
87 histogram_suffix->Add(value);
88 }
89 }
90
60 void RecordAddUnlumpedHashesTime(base::TimeDelta time) { 91 void RecordAddUnlumpedHashesTime(base::TimeDelta time) {
61 UMA_HISTOGRAM_LONG_TIMES("SafeBrowsing.V4AddUnlumpedHashesTime", time); 92 UMA_HISTOGRAM_LONG_TIMES("SafeBrowsing.V4AddUnlumpedHashes.Time", time);
Nathan Parker 2016/10/11 20:51:48 Should this one also vary by store name?
vakh (use Gerrit instead) 2016/10/11 23:08:05 No, I intend to delete this histogram actually. I'
62 } 93 }
63 94
64 void RecordApplyUpdateResult(ApplyUpdateResult result) { 95 void RecordApplyUpdateResult(const std::string& base_metric,
65 UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.V4ApplyUpdateResult", result, 96 ApplyUpdateResult result,
66 APPLY_UPDATE_RESULT_MAX); 97 const base::FilePath& file_path) {
98 RecordEnumWithAndWithoutSuffix(base_metric + ".ApplyUpdate", result,
Nathan Parker 2016/10/11 20:51:48 use a const string here too?
vakh (use Gerrit instead) 2016/10/11 23:08:05 Only used in this one place so defined inline.
99 APPLY_UPDATE_RESULT_MAX, file_path);
67 } 100 }
68 101
69 void RecordApplyUpdateResultWhenReadingFromDisk(ApplyUpdateResult result) { 102 void RecordDecodeAdditionsResult(const std::string& base_metric,
70 UMA_HISTOGRAM_ENUMERATION( 103 V4DecodeResult result,
71 "SafeBrowsing.V4ApplyUpdateResultWhenReadingFromDisk", result, 104 const base::FilePath& file_path) {
72 APPLY_UPDATE_RESULT_MAX); 105 RecordEnumWithAndWithoutSuffix(base_metric + kDecodeAdditions, result,
106 DECODE_RESULT_MAX, file_path);
73 } 107 }
74 108
75 void RecordDecodeAdditionsResult(V4DecodeResult result) { 109 void RecordDecodeAdditionsTime(const std::string& base_metric,
76 UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.V4DecodeAdditionsResult", result, 110 base::TimeDelta time,
77 DECODE_RESULT_MAX); 111 const base::FilePath& file_path) {
112 RecordTimeWithAndWithoutSuffix(base_metric + kDecodeAdditions, time,
113 file_path);
78 } 114 }
79 115
80 void RecordDecodeAdditionsTime(base::TimeDelta time, 116 void RecordDecodeRemovalsResult(const std::string& base_metric,
81 const base::FilePath& file_path) { 117 V4DecodeResult result,
82 RecordTimeWithAndWithoutStore("SafeBrowsing.V4DecodeAdditionsTime", time, 118 const base::FilePath& file_path) {
83 file_path); 119 RecordEnumWithAndWithoutSuffix(base_metric + kDecodeRemovals, result,
120 DECODE_RESULT_MAX, file_path);
84 } 121 }
85 122
86 void RecordDecodeRemovalsResult(V4DecodeResult result) { 123 void RecordDecodeRemovalsTime(const std::string& base_metric,
87 UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.V4DecodeRemovalsResult", result, 124 base::TimeDelta time,
88 DECODE_RESULT_MAX); 125 const base::FilePath& file_path) {
126 RecordTimeWithAndWithoutSuffix(base_metric + kDecodeRemovals, time,
127 file_path);
89 } 128 }
90 129
91 void RecordDecodeRemovalsTime(base::TimeDelta time, 130 void RecordMergeUpdateTime(const std::string& base_metric,
92 const base::FilePath& file_path) { 131 base::TimeDelta time,
93 RecordTimeWithAndWithoutStore("SafeBrowsing.V4DecodeRemovalsTime", time,
94 file_path);
95 }
96
97 void RecordMergeUpdateTime(base::TimeDelta time,
98 const base::FilePath& file_path) { 132 const base::FilePath& file_path) {
99 RecordTimeWithAndWithoutStore("SafeBrowsing.V4MergeUpdateTime", time, 133 RecordTimeWithAndWithoutSuffix(base_metric + ".MergeUpdate", time, file_path);
Nathan Parker 2016/10/11 20:51:48 And here too? Or, are you just using constants for
vakh (use Gerrit instead) 2016/10/11 23:08:05 Yup, except kProcessFullUpdate but defining it at
100 file_path);
101 }
102
103 void RecordProcessFullUpdateTime(base::TimeDelta time,
104 const base::FilePath& file_path) {
105 RecordTimeWithAndWithoutStore("SafeBrowsing.V4ProcessFullUpdateTime", time,
106 file_path);
107 }
108
109 void RecordProcessPartialUpdateTime(base::TimeDelta time,
110 const base::FilePath& file_path) {
111 RecordTimeWithAndWithoutStore("SafeBrowsing.V4ProcessPartialUpdateTime", time,
112 file_path);
113 }
114
115 void RecordReadFromDiskTime(base::TimeDelta time,
116 const base::FilePath& file_path) {
117 RecordTimeWithAndWithoutStore("SafeBrowsing.V4ReadFromDiskTime", time,
118 file_path);
119 } 134 }
120 135
121 void RecordStoreReadResult(StoreReadResult result) { 136 void RecordStoreReadResult(StoreReadResult result) {
122 UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.V4StoreReadResult", result, 137 UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.V4StoreRead.Result", result,
123 STORE_READ_RESULT_MAX); 138 STORE_READ_RESULT_MAX);
124 } 139 }
125 140
126 void RecordStoreWriteResult(StoreWriteResult result) { 141 void RecordStoreWriteResult(StoreWriteResult result) {
127 UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.V4StoreWriteResult", result, 142 UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.V4StoreWrite.Result", result,
128 STORE_WRITE_RESULT_MAX); 143 STORE_WRITE_RESULT_MAX);
129 } 144 }
130 145
131 // Returns the name of the temporary file used to buffer data for 146 // Returns the name of the temporary file used to buffer data for
132 // |filename|. Exported for unit tests. 147 // |filename|. Exported for unit tests.
133 const base::FilePath TemporaryFileForFilename(const base::FilePath& filename) { 148 const base::FilePath TemporaryFileForFilename(const base::FilePath& filename) {
134 return base::FilePath(filename.value() + FILE_PATH_LITERAL("_new")); 149 return base::FilePath(filename.value() + FILE_PATH_LITERAL("_new"));
135 } 150 }
136 151
137 } // namespace 152 } // namespace
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 store_path_.value().c_str(), state_base64.c_str()); 190 store_path_.value().c_str(), state_base64.c_str());
176 } 191 }
177 192
178 void V4Store::Reset() { 193 void V4Store::Reset() {
179 expected_checksum_.clear(); 194 expected_checksum_.clear();
180 hash_prefix_map_.clear(); 195 hash_prefix_map_.clear();
181 state_ = ""; 196 state_ = "";
182 } 197 }
183 198
184 ApplyUpdateResult V4Store::ProcessPartialUpdateAndWriteToDisk( 199 ApplyUpdateResult V4Store::ProcessPartialUpdateAndWriteToDisk(
200 const std::string& metric,
185 const HashPrefixMap& hash_prefix_map_old, 201 const HashPrefixMap& hash_prefix_map_old,
186 std::unique_ptr<ListUpdateResponse> response) { 202 std::unique_ptr<ListUpdateResponse> response) {
187 DCHECK(response->has_response_type()); 203 DCHECK(response->has_response_type());
188 DCHECK_EQ(ListUpdateResponse::PARTIAL_UPDATE, response->response_type()); 204 DCHECK_EQ(ListUpdateResponse::PARTIAL_UPDATE, response->response_type());
189 205
190 TimeTicks before = TimeTicks::Now(); 206 TimeTicks before = TimeTicks::Now();
191 ApplyUpdateResult result = ProcessUpdate(hash_prefix_map_old, response); 207 ApplyUpdateResult result =
208 ProcessUpdate(metric, hash_prefix_map_old, response);
192 if (result == APPLY_UPDATE_SUCCESS) { 209 if (result == APPLY_UPDATE_SUCCESS) {
193 RecordProcessPartialUpdateTime(TimeTicks::Now() - before, store_path_); 210 RecordTimeWithAndWithoutSuffix(metric, TimeTicks::Now() - before,
211 store_path_);
194 // TODO(vakh): Create a ListUpdateResponse containing RICE encoded 212 // TODO(vakh): Create a ListUpdateResponse containing RICE encoded
195 // hash prefixes and response_type as FULL_UPDATE, and write that to disk. 213 // hash prefixes and response_type as FULL_UPDATE, and write that to disk.
196 } 214 }
197 return result; 215 return result;
198 } 216 }
199 217
200 ApplyUpdateResult V4Store::ProcessFullUpdateAndWriteToDisk( 218 ApplyUpdateResult V4Store::ProcessFullUpdateAndWriteToDisk(
219 const std::string& metric,
201 std::unique_ptr<ListUpdateResponse> response) { 220 std::unique_ptr<ListUpdateResponse> response) {
202 TimeTicks before = TimeTicks::Now(); 221 TimeTicks before = TimeTicks::Now();
203 ApplyUpdateResult result = ProcessFullUpdate(response); 222 ApplyUpdateResult result = ProcessFullUpdate(metric, response);
204 if (result == APPLY_UPDATE_SUCCESS) { 223 if (result == APPLY_UPDATE_SUCCESS) {
205 RecordProcessFullUpdateTime(TimeTicks::Now() - before, store_path_); 224 RecordTimeWithAndWithoutSuffix(metric, TimeTicks::Now() - before,
225 store_path_);
206 RecordStoreWriteResult(WriteToDisk(std::move(response))); 226 RecordStoreWriteResult(WriteToDisk(std::move(response)));
207 } 227 }
208 return result; 228 return result;
209 } 229 }
210 230
211 ApplyUpdateResult V4Store::ProcessFullUpdate( 231 ApplyUpdateResult V4Store::ProcessFullUpdate(
232 const std::string& metric,
212 const std::unique_ptr<ListUpdateResponse>& response) { 233 const std::unique_ptr<ListUpdateResponse>& response) {
213 DCHECK(response->has_response_type()); 234 DCHECK(response->has_response_type());
214 DCHECK_EQ(ListUpdateResponse::FULL_UPDATE, response->response_type()); 235 DCHECK_EQ(ListUpdateResponse::FULL_UPDATE, response->response_type());
215 // TODO(vakh): For a full update, we don't need to process the update in 236 // TODO(vakh): For a full update, we don't need to process the update in
216 // lexographical order to store it, but we do need to do that for calculating 237 // lexographical order to store it, but we do need to do that for calculating
217 // checksum. It might save some CPU cycles to store the full update as-is and 238 // checksum. It might save some CPU cycles to store the full update as-is and
218 // walk the list of hash prefixes in lexographical order only for checksum 239 // walk the list of hash prefixes in lexographical order only for checksum
219 // calculation. 240 // calculation.
220 return ProcessUpdate(HashPrefixMap(), response); 241 return ProcessUpdate(metric, HashPrefixMap(), response);
221 } 242 }
222 243
223 ApplyUpdateResult V4Store::ProcessUpdate( 244 ApplyUpdateResult V4Store::ProcessUpdate(
245 const std::string& metric,
224 const HashPrefixMap& hash_prefix_map_old, 246 const HashPrefixMap& hash_prefix_map_old,
225 const std::unique_ptr<ListUpdateResponse>& response) { 247 const std::unique_ptr<ListUpdateResponse>& response) {
226 const RepeatedField<int32>* raw_removals = nullptr; 248 const RepeatedField<int32>* raw_removals = nullptr;
227 RepeatedField<int32> rice_removals; 249 RepeatedField<int32> rice_removals;
228 size_t removals_size = response->removals_size(); 250 size_t removals_size = response->removals_size();
229 DCHECK_LE(removals_size, 1u); 251 DCHECK_LE(removals_size, 1u);
230 if (removals_size == 1) { 252 if (removals_size == 1) {
231 const ThreatEntrySet& removal = response->removals().Get(0); 253 const ThreatEntrySet& removal = response->removals().Get(0);
232 const CompressionType compression_type = removal.compression_type(); 254 const CompressionType compression_type = removal.compression_type();
233 if (compression_type == RAW) { 255 if (compression_type == RAW) {
234 raw_removals = &removal.raw_indices().indices(); 256 raw_removals = &removal.raw_indices().indices();
235 } else if (compression_type == RICE) { 257 } else if (compression_type == RICE) {
236 DCHECK(removal.has_rice_indices()); 258 DCHECK(removal.has_rice_indices());
237 259
238 const RiceDeltaEncoding& rice_indices = removal.rice_indices(); 260 const RiceDeltaEncoding& rice_indices = removal.rice_indices();
239 TimeTicks before = TimeTicks::Now(); 261 TimeTicks before = TimeTicks::Now();
240 V4DecodeResult decode_result = V4RiceDecoder::DecodeIntegers( 262 V4DecodeResult decode_result = V4RiceDecoder::DecodeIntegers(
241 rice_indices.first_value(), rice_indices.rice_parameter(), 263 rice_indices.first_value(), rice_indices.rice_parameter(),
242 rice_indices.num_entries(), rice_indices.encoded_data(), 264 rice_indices.num_entries(), rice_indices.encoded_data(),
243 &rice_removals); 265 &rice_removals);
244 266
245 RecordDecodeRemovalsResult(decode_result); 267 RecordDecodeRemovalsResult(metric, decode_result, store_path_);
246 if (decode_result != DECODE_SUCCESS) { 268 if (decode_result != DECODE_SUCCESS) {
247 return RICE_DECODING_FAILURE; 269 return RICE_DECODING_FAILURE;
248 } 270 }
249 RecordDecodeRemovalsTime(TimeTicks::Now() - before, store_path_); 271 RecordDecodeRemovalsTime(metric, TimeTicks::Now() - before, store_path_);
250 raw_removals = &rice_removals; 272 raw_removals = &rice_removals;
251 } else { 273 } else {
252 NOTREACHED() << "Unexpected compression_type type: " << compression_type; 274 NOTREACHED() << "Unexpected compression_type type: " << compression_type;
253 return UNEXPECTED_COMPRESSION_TYPE_REMOVALS_FAILURE; 275 return UNEXPECTED_COMPRESSION_TYPE_REMOVALS_FAILURE;
254 } 276 }
255 } 277 }
256 278
257 HashPrefixMap hash_prefix_map; 279 HashPrefixMap hash_prefix_map;
258 ApplyUpdateResult apply_update_result = 280 ApplyUpdateResult apply_update_result = UpdateHashPrefixMapFromAdditions(
259 UpdateHashPrefixMapFromAdditions(response->additions(), &hash_prefix_map); 281 metric, response->additions(), &hash_prefix_map);
260 if (apply_update_result != APPLY_UPDATE_SUCCESS) { 282 if (apply_update_result != APPLY_UPDATE_SUCCESS) {
261 return apply_update_result; 283 return apply_update_result;
262 } 284 }
263 285
264 std::string expected_checksum; 286 std::string expected_checksum;
265 if (response->has_checksum() && response->checksum().has_sha256()) { 287 if (response->has_checksum() && response->checksum().has_sha256()) {
266 expected_checksum = response->checksum().sha256(); 288 expected_checksum = response->checksum().sha256();
267 } 289 }
268 290
269 TimeTicks before = TimeTicks::Now(); 291 TimeTicks before = TimeTicks::Now();
270 apply_update_result = MergeUpdate(hash_prefix_map_old, hash_prefix_map, 292 apply_update_result = MergeUpdate(hash_prefix_map_old, hash_prefix_map,
271 raw_removals, expected_checksum); 293 raw_removals, expected_checksum);
272 if (apply_update_result != APPLY_UPDATE_SUCCESS) { 294 if (apply_update_result != APPLY_UPDATE_SUCCESS) {
273 return apply_update_result; 295 return apply_update_result;
274 } 296 }
275 RecordMergeUpdateTime(TimeTicks::Now() - before, store_path_); 297 RecordMergeUpdateTime(metric, TimeTicks::Now() - before, store_path_);
276 298
277 state_ = response->new_client_state(); 299 state_ = response->new_client_state();
278 return APPLY_UPDATE_SUCCESS; 300 return APPLY_UPDATE_SUCCESS;
279 } 301 }
280 302
281 void V4Store::ApplyUpdate( 303 void V4Store::ApplyUpdate(
282 std::unique_ptr<ListUpdateResponse> response, 304 std::unique_ptr<ListUpdateResponse> response,
283 const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner, 305 const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner,
284 UpdatedStoreReadyCallback callback) { 306 UpdatedStoreReadyCallback callback) {
285 std::unique_ptr<V4Store> new_store( 307 std::unique_ptr<V4Store> new_store(new V4Store(task_runner_, store_path_));
286 new V4Store(this->task_runner_, this->store_path_));
287 ApplyUpdateResult apply_update_result; 308 ApplyUpdateResult apply_update_result;
309 std::string metric;
288 if (response->response_type() == ListUpdateResponse::PARTIAL_UPDATE) { 310 if (response->response_type() == ListUpdateResponse::PARTIAL_UPDATE) {
311 metric = kProcessPartialUpdate;
289 apply_update_result = new_store->ProcessPartialUpdateAndWriteToDisk( 312 apply_update_result = new_store->ProcessPartialUpdateAndWriteToDisk(
290 hash_prefix_map_, std::move(response)); 313 metric, hash_prefix_map_, std::move(response));
291 } else if (response->response_type() == ListUpdateResponse::FULL_UPDATE) { 314 } else if (response->response_type() == ListUpdateResponse::FULL_UPDATE) {
315 metric = kProcessFullUpdate;
292 apply_update_result = 316 apply_update_result =
293 new_store->ProcessFullUpdateAndWriteToDisk(std::move(response)); 317 new_store->ProcessFullUpdateAndWriteToDisk(metric, std::move(response));
294 } else { 318 } else {
295 apply_update_result = UNEXPECTED_RESPONSE_TYPE_FAILURE; 319 apply_update_result = UNEXPECTED_RESPONSE_TYPE_FAILURE;
296 NOTREACHED() << "Failure: Unexpected response type: " 320 NOTREACHED() << "Failure: Unexpected response type: "
297 << response->response_type(); 321 << response->response_type();
298 } 322 }
299 323
300 if (apply_update_result == APPLY_UPDATE_SUCCESS) { 324 if (apply_update_result == APPLY_UPDATE_SUCCESS) {
301 // new_store is done updating, pass it to the callback. 325 // new_store is done updating, pass it to the callback.
302 callback_task_runner->PostTask( 326 callback_task_runner->PostTask(
303 FROM_HERE, base::Bind(callback, base::Passed(&new_store))); 327 FROM_HERE, base::Bind(callback, base::Passed(&new_store)));
304 } else { 328 } else {
305 DVLOG(1) << "Failure: ApplyUpdate: reason: " << apply_update_result 329 DVLOG(1) << "Failure: ApplyUpdate: reason: " << apply_update_result
306 << "; store: " << *this; 330 << "; store: " << *this;
307 // new_store failed updating. Pass a nullptr to the callback. 331 // new_store failed updating. Pass a nullptr to the callback.
308 callback_task_runner->PostTask(FROM_HERE, base::Bind(callback, nullptr)); 332 callback_task_runner->PostTask(FROM_HERE, base::Bind(callback, nullptr));
309 } 333 }
310 334
311 RecordApplyUpdateResult(apply_update_result); 335 RecordApplyUpdateResult(metric, apply_update_result, store_path_);
312 } 336 }
313 337
314 ApplyUpdateResult V4Store::UpdateHashPrefixMapFromAdditions( 338 ApplyUpdateResult V4Store::UpdateHashPrefixMapFromAdditions(
339 const std::string& metric,
315 const RepeatedPtrField<ThreatEntrySet>& additions, 340 const RepeatedPtrField<ThreatEntrySet>& additions,
316 HashPrefixMap* additions_map) { 341 HashPrefixMap* additions_map) {
317 for (const auto& addition : additions) { 342 for (const auto& addition : additions) {
318 ApplyUpdateResult apply_update_result = APPLY_UPDATE_SUCCESS; 343 ApplyUpdateResult apply_update_result = APPLY_UPDATE_SUCCESS;
319 const CompressionType compression_type = addition.compression_type(); 344 const CompressionType compression_type = addition.compression_type();
320 if (compression_type == RAW) { 345 if (compression_type == RAW) {
321 DCHECK(addition.has_raw_hashes()); 346 DCHECK(addition.has_raw_hashes());
322 DCHECK(addition.raw_hashes().has_raw_hashes()); 347 DCHECK(addition.raw_hashes().has_raw_hashes());
323 348
324 apply_update_result = 349 apply_update_result =
325 AddUnlumpedHashes(addition.raw_hashes().prefix_size(), 350 AddUnlumpedHashes(addition.raw_hashes().prefix_size(),
326 addition.raw_hashes().raw_hashes(), additions_map); 351 addition.raw_hashes().raw_hashes(), additions_map);
327 } else if (compression_type == RICE) { 352 } else if (compression_type == RICE) {
328 DCHECK(addition.has_rice_hashes()); 353 DCHECK(addition.has_rice_hashes());
329 354
330 const RiceDeltaEncoding& rice_hashes = addition.rice_hashes(); 355 const RiceDeltaEncoding& rice_hashes = addition.rice_hashes();
331 std::vector<uint32_t> raw_hashes; 356 std::vector<uint32_t> raw_hashes;
332 TimeTicks before = TimeTicks::Now(); 357 TimeTicks before = TimeTicks::Now();
333 V4DecodeResult decode_result = V4RiceDecoder::DecodePrefixes( 358 V4DecodeResult decode_result = V4RiceDecoder::DecodePrefixes(
334 rice_hashes.first_value(), rice_hashes.rice_parameter(), 359 rice_hashes.first_value(), rice_hashes.rice_parameter(),
335 rice_hashes.num_entries(), rice_hashes.encoded_data(), &raw_hashes); 360 rice_hashes.num_entries(), rice_hashes.encoded_data(), &raw_hashes);
336 RecordDecodeAdditionsResult(decode_result); 361 RecordDecodeAdditionsResult(metric, decode_result, store_path_);
337 if (decode_result != DECODE_SUCCESS) { 362 if (decode_result != DECODE_SUCCESS) {
338 return RICE_DECODING_FAILURE; 363 return RICE_DECODING_FAILURE;
339 } else { 364 } else {
340 RecordDecodeAdditionsTime(TimeTicks::Now() - before, store_path_); 365 RecordDecodeAdditionsTime(metric, TimeTicks::Now() - before,
366 store_path_);
341 char* raw_hashes_start = reinterpret_cast<char*>(raw_hashes.data()); 367 char* raw_hashes_start = reinterpret_cast<char*>(raw_hashes.data());
342 size_t raw_hashes_size = sizeof(uint32_t) * raw_hashes.size(); 368 size_t raw_hashes_size = sizeof(uint32_t) * raw_hashes.size();
343 369
344 // Rice-Golomb encoding is used to send compressed compressed 4-byte 370 // Rice-Golomb encoding is used to send compressed compressed 4-byte
345 // hash prefixes. Hash prefixes longer than 4 bytes will not be 371 // hash prefixes. Hash prefixes longer than 4 bytes will not be
346 // compressed, and will be served in raw format instead. 372 // compressed, and will be served in raw format instead.
347 // Source: https://developers.google.com/safe-browsing/v4/compression 373 // Source: https://developers.google.com/safe-browsing/v4/compression
348 const PrefixSize kPrefixSize = 4; 374 const PrefixSize kPrefixSize = 4;
349 apply_update_result = AddUnlumpedHashes(kPrefixSize, raw_hashes_start, 375 apply_update_result = AddUnlumpedHashes(kPrefixSize, raw_hashes_start,
350 raw_hashes_size, additions_map); 376 raw_hashes_size, additions_map);
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 if (file_format.version_number() != kFileVersion) { 646 if (file_format.version_number() != kFileVersion) {
621 return FILE_VERSION_INCOMPATIBLE_FAILURE; 647 return FILE_VERSION_INCOMPATIBLE_FAILURE;
622 } 648 }
623 649
624 if (!file_format.has_list_update_response()) { 650 if (!file_format.has_list_update_response()) {
625 return HASH_PREFIX_INFO_MISSING_FAILURE; 651 return HASH_PREFIX_INFO_MISSING_FAILURE;
626 } 652 }
627 653
628 std::unique_ptr<ListUpdateResponse> response(new ListUpdateResponse); 654 std::unique_ptr<ListUpdateResponse> response(new ListUpdateResponse);
629 response->Swap(file_format.mutable_list_update_response()); 655 response->Swap(file_format.mutable_list_update_response());
630 ApplyUpdateResult apply_update_result = ProcessFullUpdate(response); 656 ApplyUpdateResult apply_update_result =
631 RecordApplyUpdateResultWhenReadingFromDisk(apply_update_result); 657 ProcessFullUpdate(kReadFromDisk, response);
658 RecordApplyUpdateResult(kReadFromDisk, apply_update_result, store_path_);
632 if (apply_update_result != APPLY_UPDATE_SUCCESS) { 659 if (apply_update_result != APPLY_UPDATE_SUCCESS) {
633 hash_prefix_map_.clear(); 660 hash_prefix_map_.clear();
634 return HASH_PREFIX_MAP_GENERATION_FAILURE; 661 return HASH_PREFIX_MAP_GENERATION_FAILURE;
635 } 662 }
636 RecordReadFromDiskTime(TimeTicks::Now() - before, store_path_); 663 RecordTimeWithAndWithoutSuffix(kReadFromDisk, TimeTicks::Now() - before,
664 store_path_);
637 665
638 return READ_SUCCESS; 666 return READ_SUCCESS;
639 } 667 }
640 668
641 StoreWriteResult V4Store::WriteToDisk( 669 StoreWriteResult V4Store::WriteToDisk(
642 std::unique_ptr<ListUpdateResponse> response) const { 670 std::unique_ptr<ListUpdateResponse> response) const {
643 // Do not write partial updates to the disk. 671 // Do not write partial updates to the disk.
644 // After merging the updates, the ListUpdateResponse passed to this method 672 // After merging the updates, the ListUpdateResponse passed to this method
645 // should be a FULL_UPDATE. 673 // should be a FULL_UPDATE.
646 if (!response->has_response_type() || 674 if (!response->has_response_type() ||
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 771
744 // Find the next smallest unmerged element in the map. 772 // Find the next smallest unmerged element in the map.
745 has_unmerged = GetNextSmallestUnmergedPrefix(hash_prefix_map_, iterator_map, 773 has_unmerged = GetNextSmallestUnmergedPrefix(hash_prefix_map_, iterator_map,
746 &next_smallest_prefix); 774 &next_smallest_prefix);
747 } 775 }
748 776
749 char checksum[crypto::kSHA256Length]; 777 char checksum[crypto::kSHA256Length];
750 checksum_ctx->Finish(checksum, sizeof(checksum)); 778 checksum_ctx->Finish(checksum, sizeof(checksum));
751 for (size_t i = 0; i < crypto::kSHA256Length; i++) { 779 for (size_t i = 0; i < crypto::kSHA256Length; i++) {
752 if (checksum[i] != expected_checksum_[i]) { 780 if (checksum[i] != expected_checksum_[i]) {
753 RecordApplyUpdateResultWhenReadingFromDisk(CHECKSUM_MISMATCH_FAILURE); 781 RecordApplyUpdateResult(kReadFromDisk, CHECKSUM_MISMATCH_FAILURE,
782 store_path_);
754 #if DCHECK_IS_ON() 783 #if DCHECK_IS_ON()
755 std::string checksum_b64, expected_checksum_b64; 784 std::string checksum_b64, expected_checksum_b64;
756 base::Base64Encode(base::StringPiece(checksum, arraysize(checksum)), 785 base::Base64Encode(base::StringPiece(checksum, arraysize(checksum)),
757 &checksum_b64); 786 &checksum_b64);
758 base::Base64Encode(expected_checksum_, &expected_checksum_b64); 787 base::Base64Encode(expected_checksum_, &expected_checksum_b64);
759 DVLOG(1) << "Failure: Checksum mismatch: calculated: " << checksum_b64 788 DVLOG(1) << "Failure: Checksum mismatch: calculated: " << checksum_b64
760 << "; expected: " << expected_checksum_b64 789 << "; expected: " << expected_checksum_b64
761 << "; store: " << *this; 790 << "; store: " << *this;
762 #endif 791 #endif
763 return false; 792 return false;
764 } 793 }
765 } 794 }
766 return true; 795 return true;
767 } 796 }
768 797
769 } // namespace safe_browsing 798 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698