Skip to content

Commit be3beac

Browse files
committed
simplify quotientfilter remove
1 parent 6026d0d commit be3beac

1 file changed

Lines changed: 30 additions & 25 deletions

File tree

probables/quotientfilter/quotientfilter.py

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -395,68 +395,73 @@ def _add(self, q: int, r: int):
395395

396396
def _remove_element(self, q: int, r: int) -> None:
397397
idx = self._contained_at_loc(q, r)
398-
399-
# element not in the filter, exit
400398
if idx == -1:
401399
return
402400

403401
next_idx = (idx + 1) & self.__mod_size
402+
remove_orig_idx = self._should_remove_orig_idx(idx, next_idx)
404403

405-
# track if this is the only element in this run...
406-
remove_orig_idx = False
407-
if self._is_run_or_cluster_start(idx) and self._is_continuation[next_idx] == 0:
408-
remove_orig_idx = True
409-
410-
# element is the end of a cluster and the next element is either the beginning of a cluster or empty
411404
if self._is_empty_element(next_idx) or self._is_cluster_start(next_idx):
412-
self._filter[idx] = 0
413-
self._is_occupied.clear_bit(idx)
414-
self._is_continuation.clear_bit(idx)
415-
self._is_shifted.clear_bit(idx)
416-
417-
if remove_orig_idx:
418-
self._is_occupied[q] = 0
405+
self._remove_and_clear_bits(idx, q, remove_orig_idx)
419406
return
420407

421-
# find the minimum idx for the cluster; will be needed to determine if elements are in cluster start positions.
408+
min_idx = self._find_cluster_start(idx)
409+
idx, next_idx = self._handle_first_move(idx, next_idx)
410+
idx, next_idx = self._shift_elements(idx, next_idx)
411+
self._clear_last_element(idx)
412+
if remove_orig_idx:
413+
self._is_occupied[q] = 0
414+
self._fixup_cluster(min_idx, next_idx)
415+
416+
def _should_remove_orig_idx(self, idx: int, next_idx: int) -> bool:
417+
return self._is_run_or_cluster_start(idx) and self._is_continuation[next_idx] == 0
418+
419+
def _remove_and_clear_bits(self, idx: int, q: int, remove_orig_idx: bool) -> None:
420+
self._filter[idx] = 0
421+
self._is_occupied.clear_bit(idx)
422+
self._is_continuation.clear_bit(idx)
423+
self._is_shifted.clear_bit(idx)
424+
if remove_orig_idx:
425+
self._is_occupied[q] = 0
426+
427+
def _find_cluster_start(self, idx: int) -> int:
422428
min_idx = idx
423429
while not self._is_cluster_start(min_idx):
424430
min_idx = (min_idx - 1) & self.__mod_size
431+
return min_idx
425432

426-
# this is an edge case for first move...
433+
def _handle_first_move(self, idx: int, next_idx: int):
427434
if self._is_run_or_cluster_start(idx) and self._is_continuation[next_idx] == 1:
428435
self._filter[idx] = self._filter[next_idx]
429436
self._is_continuation[idx] = 0
430437
self._is_shifted[idx] = self._is_shifted[next_idx]
431-
432438
idx = next_idx
433439
next_idx = (idx + 1) & self.__mod_size
440+
return idx, next_idx
434441

442+
def _shift_elements(self, idx: int, next_idx: int):
435443
while not self._is_cluster_start(next_idx) and not self._is_empty_element(next_idx):
436444
self._filter[idx] = self._filter[next_idx]
437445
self._is_continuation[idx] = self._is_continuation[next_idx]
438446
self._is_shifted[idx] = self._is_shifted[next_idx]
439-
440447
idx = next_idx
441448
next_idx = (idx + 1) & self.__mod_size
442-
# clean out the last element
449+
return idx, next_idx
450+
451+
def _clear_last_element(self, idx: int) -> None:
443452
self._filter[idx] = 0
444453
self._is_continuation[idx] = 0
445454
self._is_shifted[idx] = 0
446455
self._is_occupied[idx] = 0
447456

448-
if remove_orig_idx:
449-
self._is_occupied[q] = 0
450-
451-
# now figure out if things are in the correct place....
457+
def _fixup_cluster(self, min_idx: int, next_idx: int) -> None:
452458
cur_quot = -1
453459
queue: list[int] = []
454460
while min_idx != next_idx:
455461
if self._is_occupied[min_idx] == 1:
456462
queue.append(min_idx)
457463
if self._is_run_start(min_idx) == 1:
458464
cur_quot = queue.pop(0)
459-
460465
if cur_quot == min_idx:
461466
self._is_continuation[min_idx] = 0
462467
self._is_shifted[min_idx] = 0

0 commit comments

Comments
 (0)