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

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

Issue 2151193002: Revert of PVer4: Keep track of the smallest hashes not their sizes. Replace counters with iterators. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@01_read_map_from_disk
Patch Set: Created 4 years, 5 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/metrics/histogram_macros.h" 8 #include "base/metrics/histogram_macros.h"
9 #include "base/metrics/sparse_histogram.h" 9 #include "base/metrics/sparse_histogram.h"
10 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 } 184 }
185 if (lumped_hashes.size() % prefix_size != 0) { 185 if (lumped_hashes.size() % prefix_size != 0) {
186 return ADDITIONS_SIZE_UNEXPECTED_FAILURE; 186 return ADDITIONS_SIZE_UNEXPECTED_FAILURE;
187 } 187 }
188 // TODO(vakh): Figure out a way to avoid the following copy operation. 188 // TODO(vakh): Figure out a way to avoid the following copy operation.
189 (*additions_map)[prefix_size] = lumped_hashes; 189 (*additions_map)[prefix_size] = lumped_hashes;
190 return APPLY_UPDATE_SUCCESS; 190 return APPLY_UPDATE_SUCCESS;
191 } 191 }
192 192
193 // static 193 // static
194 bool V4Store::GetNextSmallestUnmergedPrefix( 194 bool V4Store::GetNextSmallestPrefixSize(const HashPrefixMap& hash_prefix_map,
195 const HashPrefixMap& hash_prefix_map, 195 const CounterMap& counter_map,
196 const IteratorMap& iterator_map, 196 PrefixSize* smallest_prefix_size) {
197 HashPrefix* smallest_hash_prefix) { 197 HashPrefix smallest_prefix, current_prefix;
198 HashPrefix current_hash_prefix; 198 for (const auto& counter_pair : counter_map) {
199 bool has_unmerged = false; 199 PrefixSize prefix_size = counter_pair.first;
200 200 size_t index = counter_pair.second;
201 for (const auto& iterator_pair : iterator_map) { 201 size_t sized_index = prefix_size * index;
202 PrefixSize prefix_size = iterator_pair.first;
203 HashPrefixes::const_iterator start = iterator_pair.second;
204 HashPrefixes::const_iterator end = start + prefix_size;
205 202
206 const HashPrefixes& hash_prefixes = hash_prefix_map.at(prefix_size); 203 const HashPrefixes& hash_prefixes = hash_prefix_map.at(prefix_size);
207 if (end <= hash_prefixes.end()) { 204 if (sized_index < hash_prefixes.size()) {
208 current_hash_prefix = std::string(start, end); 205 current_prefix = hash_prefixes.substr(sized_index, prefix_size);
209 if (!has_unmerged || *smallest_hash_prefix > current_hash_prefix) { 206 if (smallest_prefix.empty() || smallest_prefix > current_prefix) {
210 has_unmerged = true; 207 smallest_prefix = current_prefix;
211 smallest_hash_prefix->swap(current_hash_prefix); 208 *smallest_prefix_size = prefix_size;
212 } 209 }
213 } 210 }
214 } 211 }
215 return has_unmerged; 212 return !smallest_prefix.empty();
216 } 213 }
217 214
218 // static 215 // static
219 void V4Store::InitializeIteratorMap(const HashPrefixMap& hash_prefix_map, 216 void V4Store::InitializeCounterMap(const HashPrefixMap& hash_prefix_map,
220 IteratorMap* iterator_map) { 217 CounterMap* counter_map) {
221 for (const auto& map_pair : hash_prefix_map) { 218 for (const auto& map_pair : hash_prefix_map) {
222 (*iterator_map)[map_pair.first] = map_pair.second.begin(); 219 (*counter_map)[map_pair.first] = 0;
223 } 220 }
224 } 221 }
225 222
226 // static 223 // static
224 HashPrefix V4Store::GetNextUnmergedPrefixForSize(
225 PrefixSize prefix_size,
226 const HashPrefixMap& hash_prefix_map,
227 const CounterMap& counter_map) {
228 const HashPrefixes& hash_prefixes = hash_prefix_map.at(prefix_size);
229 size_t index_within_list = counter_map.at(prefix_size);
230 size_t sized_index = prefix_size * index_within_list;
231 return hash_prefixes.substr(sized_index, prefix_size);
232 }
233
234 // static
227 void V4Store::ReserveSpaceInPrefixMap(const HashPrefixMap& other_prefixes_map, 235 void V4Store::ReserveSpaceInPrefixMap(const HashPrefixMap& other_prefixes_map,
228 HashPrefixMap* prefix_map_to_update) { 236 HashPrefixMap* prefix_map_to_update) {
229 for (const auto& pair : other_prefixes_map) { 237 for (const auto& pair : other_prefixes_map) {
230 PrefixSize prefix_size = pair.first; 238 PrefixSize prefix_size = pair.first;
231 size_t prefix_length_to_add = pair.second.length(); 239 size_t prefix_length_to_add = pair.second.length();
232 240
233 const HashPrefixes& existing_prefixes = 241 const HashPrefixes& existing_prefixes =
234 (*prefix_map_to_update)[prefix_size]; 242 (*prefix_map_to_update)[prefix_size];
235 size_t existing_capacity = existing_prefixes.capacity(); 243 size_t existing_capacity = existing_prefixes.capacity();
236 244
237 (*prefix_map_to_update)[prefix_size].reserve(existing_capacity + 245 (*prefix_map_to_update)[prefix_size].reserve(existing_capacity +
238 prefix_length_to_add); 246 prefix_length_to_add);
239 } 247 }
240 } 248 }
241 249
242 ApplyUpdateResult V4Store::MergeUpdate(const HashPrefixMap& old_prefixes_map, 250 ApplyUpdateResult V4Store::MergeUpdate(const HashPrefixMap& old_prefixes_map,
243 const HashPrefixMap& additions_map) { 251 const HashPrefixMap& additions_map) {
244 DCHECK(hash_prefix_map_.empty()); 252 DCHECK(hash_prefix_map_.empty());
245 hash_prefix_map_.clear(); 253 hash_prefix_map_.clear();
246 ReserveSpaceInPrefixMap(old_prefixes_map, &hash_prefix_map_); 254 ReserveSpaceInPrefixMap(old_prefixes_map, &hash_prefix_map_);
247 ReserveSpaceInPrefixMap(additions_map, &hash_prefix_map_); 255 ReserveSpaceInPrefixMap(additions_map, &hash_prefix_map_);
248 256
249 IteratorMap old_iterator_map; 257 PrefixSize next_size_for_old;
250 HashPrefix next_smallest_prefix_old; 258 CounterMap old_counter_map;
251 InitializeIteratorMap(old_prefixes_map, &old_iterator_map); 259 InitializeCounterMap(old_prefixes_map, &old_counter_map);
252 bool old_has_unmerged = GetNextSmallestUnmergedPrefix( 260 bool old_has_unmerged = GetNextSmallestPrefixSize(
253 old_prefixes_map, old_iterator_map, &next_smallest_prefix_old); 261 old_prefixes_map, old_counter_map, &next_size_for_old);
254 262
255 IteratorMap additions_iterator_map; 263 PrefixSize next_size_for_additions;
256 HashPrefix next_smallest_prefix_additions; 264 CounterMap additions_counter_map;
257 InitializeIteratorMap(additions_map, &additions_iterator_map); 265 InitializeCounterMap(additions_map, &additions_counter_map);
258 bool additions_has_unmerged = GetNextSmallestUnmergedPrefix( 266 bool additions_has_unmerged = GetNextSmallestPrefixSize(
259 additions_map, additions_iterator_map, &next_smallest_prefix_additions); 267 additions_map, additions_counter_map, &next_size_for_additions);
260 268
261 // Classical merge sort. 269 // Classical merge sort.
262 // The two constructs to merge are maps: old_prefixes_map, additions_map. 270 // The two constructs to merge are maps: old_prefixes_map, additions_map.
271
272 HashPrefix next_smallest_prefix_old, next_smallest_prefix_additions;
263 // At least one of the maps still has elements that need to be merged into the 273 // At least one of the maps still has elements that need to be merged into the
264 // new store. 274 // new store.
265 while (old_has_unmerged || additions_has_unmerged) { 275 while (old_has_unmerged || additions_has_unmerged) {
276 // Old map still has elements that need to be merged.
277 if (old_has_unmerged) {
278 // Get the lexographically smallest hash prefix from the old store.
279 next_smallest_prefix_old = GetNextUnmergedPrefixForSize(
280 next_size_for_old, old_prefixes_map, old_counter_map);
281 }
282
283 // Additions map still has elements that need to be merged.
284 if (additions_has_unmerged) {
285 // Get the lexographically smallest hash prefix from the additions in the
286 // latest update from the server.
287 next_smallest_prefix_additions = GetNextUnmergedPrefixForSize(
288 next_size_for_additions, additions_map, additions_counter_map);
289 }
290
266 // If the same hash prefix appears in the existing store and the additions 291 // If the same hash prefix appears in the existing store and the additions
267 // list, something is clearly wrong. Discard the update. 292 // list, something is clearly wrong. Discard the update.
268 if (old_has_unmerged && additions_has_unmerged && 293 if (old_has_unmerged && additions_has_unmerged &&
269 next_smallest_prefix_old == next_smallest_prefix_additions) { 294 next_smallest_prefix_old == next_smallest_prefix_additions) {
270 return ADDITIONS_HAS_EXISTING_PREFIX_FAILURE; 295 return ADDITIONS_HAS_EXISTING_PREFIX_FAILURE;
271 } 296 }
272 297
273 // Select which map to pick the next hash prefix from to keep the result in 298 // Select which map to pick the next hash prefix from to keep the result in
274 // lexographically sorted order. 299 // lexographically sorted order.
275 bool pick_from_old = 300 bool pick_from_old =
276 old_has_unmerged && 301 old_has_unmerged &&
277 (!additions_has_unmerged || 302 (!additions_has_unmerged ||
278 (next_smallest_prefix_old < next_smallest_prefix_additions)); 303 (next_smallest_prefix_old < next_smallest_prefix_additions));
279 304
280 PrefixSize next_smallest_prefix_size;
281 if (pick_from_old) { 305 if (pick_from_old) {
282 next_smallest_prefix_size = next_smallest_prefix_old.size(); 306 hash_prefix_map_[next_size_for_old] += next_smallest_prefix_old;
283 307
284 // Append the smallest hash to the appropriate list. 308 // Update the counter map, which means that we have merged one hash
285 hash_prefix_map_[next_smallest_prefix_size] += next_smallest_prefix_old;
286
287 // Update the iterator map, which means that we have merged one hash
288 // prefix of size |next_size_for_old| from the old store. 309 // prefix of size |next_size_for_old| from the old store.
289 old_iterator_map[next_smallest_prefix_size] += next_smallest_prefix_size; 310 old_counter_map[next_size_for_old]++;
290 311
291 // Find the next smallest unmerged element in the old store's map. 312 // Find the next smallest unmerged element in the old store's map.
292 old_has_unmerged = GetNextSmallestUnmergedPrefix( 313 old_has_unmerged = GetNextSmallestPrefixSize(
293 old_prefixes_map, old_iterator_map, &next_smallest_prefix_old); 314 old_prefixes_map, old_counter_map, &next_size_for_old);
294 } else { 315 } else {
295 next_smallest_prefix_size = next_smallest_prefix_additions.size(); 316 hash_prefix_map_[next_size_for_additions] +=
296
297 // Append the smallest hash to the appropriate list.
298 hash_prefix_map_[next_smallest_prefix_size] +=
299 next_smallest_prefix_additions; 317 next_smallest_prefix_additions;
300 318
301 // Update the iterator map, which means that we have merged one hash 319 // Update the counter map, which means that we have merged one hash
302 // prefix of size |next_smallest_prefix_size| from the update. 320 // prefix of size |next_size_for_additions| from the update.
303 additions_iterator_map[next_smallest_prefix_size] += 321 additions_counter_map[next_size_for_additions]++;
304 next_smallest_prefix_size;
305 322
306 // Find the next smallest unmerged element in the additions map. 323 // Find the next smallest unmerged element in the additions map.
307 additions_has_unmerged = 324 additions_has_unmerged = GetNextSmallestPrefixSize(
308 GetNextSmallestUnmergedPrefix(additions_map, additions_iterator_map, 325 additions_map, additions_counter_map, &next_size_for_additions);
309 &next_smallest_prefix_additions);
310 } 326 }
311 } 327 }
312 328
313 return APPLY_UPDATE_SUCCESS; 329 return APPLY_UPDATE_SUCCESS;
314 } 330 }
315 331
316 StoreReadResult V4Store::ReadFromDisk() { 332 StoreReadResult V4Store::ReadFromDisk() {
317 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 333 DCHECK(task_runner_->RunsTasksOnCurrentThread());
318 334
319 std::string contents; 335 std::string contents;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 408
393 if (!base::Move(new_filename, store_path_)) { 409 if (!base::Move(new_filename, store_path_)) {
394 DVLOG(1) << "store_path_: " << store_path_.value(); 410 DVLOG(1) << "store_path_: " << store_path_.value();
395 return UNABLE_TO_RENAME_FAILURE; 411 return UNABLE_TO_RENAME_FAILURE;
396 } 412 }
397 413
398 return WRITE_SUCCESS; 414 return WRITE_SUCCESS;
399 } 415 }
400 416
401 } // namespace safe_browsing 417 } // namespace safe_browsing
OLDNEW
« no previous file with comments | « components/safe_browsing_db/v4_store.h ('k') | components/safe_browsing_db/v4_store_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698