MCPcopy Create free account
hub / github.com/CodingGay/BlackDex / Erase

Method Erase

Bcore/src/main/cpp/base/hash_set.h:320–364  ·  view source on GitHub ↗

Erase algorithm: Make an empty slot where the iterator is pointing. Scan forwards until we hit another empty slot. If an element in between doesn't rehash to the range from the current empty slot to the iterator. It must be before the empty slot, in that case we can move it to the empty slot and set the empty slot to be the location we just moved from. Relies on maintaining the invariant that ther

Source from the content-addressed store, hash-verified

318 // Relies on maintaining the invariant that there's no empty slots from the 'ideal' index of an
319 // element to its actual location/index.
320 iterator Erase(iterator it) {
321 // empty_index is the index that will become empty.
322 size_t empty_index = it.index_;
323 DCHECK(!IsFreeSlot(empty_index));
324 size_t next_index = empty_index;
325 bool filled = false; // True if we filled the empty index.
326 while (true) {
327 next_index = NextIndex(next_index);
328 T& next_element = ElementForIndex(next_index);
329 // If the next element is empty, we are done. Make sure to clear the current empty index.
330 if (emptyfn_.IsEmpty(next_element)) {
331 emptyfn_.MakeEmpty(ElementForIndex(empty_index));
332 break;
333 }
334 // Otherwise try to see if the next element can fill the current empty index.
335 const size_t next_hash = hashfn_(next_element);
336 // Calculate the ideal index, if it is within empty_index + 1 to next_index then there is
337 // nothing we can do.
338 size_t next_ideal_index = IndexForHash(next_hash);
339 // Loop around if needed for our check.
340 size_t unwrapped_next_index = next_index;
341 if (unwrapped_next_index < empty_index) {
342 unwrapped_next_index += NumBuckets();
343 }
344 // Loop around if needed for our check.
345 size_t unwrapped_next_ideal_index = next_ideal_index;
346 if (unwrapped_next_ideal_index < empty_index) {
347 unwrapped_next_ideal_index += NumBuckets();
348 }
349 if (unwrapped_next_ideal_index <= empty_index ||
350 unwrapped_next_ideal_index > unwrapped_next_index) {
351 // If the target index isn't within our current range it must have been probed from before
352 // the empty index.
353 ElementForIndex(empty_index) = std::move(next_element);
354 filled = true; // TODO: Optimize
355 empty_index = next_index;
356 }
357 }
358 --num_elements_;
359 // If we didn't fill the slot then we need go to the next non free slot.
360 if (!filled) {
361 ++it;
362 }
363 return it;
364 }
365
366 // Find an element, returns end() if not found.
367 // Allows custom key (K) types, example of when this is useful:

Callers

nothing calls this directly

Calls 2

IsEmptyMethod · 0.45
MakeEmptyMethod · 0.45

Tested by

no test coverage detected