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

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

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

Powered by Google App Engine
This is Rietveld 408576698