Skip to content

Commit 8e3bff1

Browse files
aneubeckitsibitzi
authored andcommitted
Ensure invariance
1 parent 4261d8d commit 8e3bff1

File tree

2 files changed

+13
-18
lines changed

2 files changed

+13
-18
lines changed

crates/geo_filters/src/diff_count.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -210,17 +210,16 @@ impl<C: GeoConfig<Diff>> GeoDiffCount<'_, C> {
210210
match msb.binary_search_by(|k| bucket.cmp(k)) {
211211
Ok(idx) => {
212212
msb.remove(idx);
213-
let (first, second) = {
213+
let first = {
214214
let mut lsb = iter_ones(self.lsb.bit_chunks().peekable());
215-
(lsb.next(), lsb.next())
215+
lsb.next()
216216
};
217-
let new_smallest = if let Some(smallest) = first {
217+
if let Some(smallest) = first {
218218
msb.push(C::BucketType::from_usize(smallest));
219-
second.map(|_| smallest).unwrap_or(0)
219+
self.lsb.resize(smallest);
220220
} else {
221-
0
221+
self.lsb.resize(0);
222222
};
223-
self.lsb.resize(new_smallest);
224223
}
225224
Err(idx) => {
226225
msb.insert(idx, bucket);
@@ -236,6 +235,12 @@ impl<C: GeoConfig<Diff>> GeoDiffCount<'_, C> {
236235
.into_usize();
237236
self.lsb.resize(new_smallest);
238237
self.lsb.toggle(smallest);
238+
} else if msb.len() == self.config.max_msb_len() {
239+
let smallest = msb
240+
.last()
241+
.expect("should have at least one element")
242+
.into_usize();
243+
self.lsb.resize(smallest);
239244
}
240245
}
241246
}

crates/geo_filters/src/diff_count/bitvec.rs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,12 @@ use crate::config::BITS_PER_BLOCK;
1212
/// bit consumes 1 byte). It only implements the minimum number of operations that we need for our
1313
/// GeoDiffCount implementation. In particular it supports xor-ing of two bit vectors and
1414
/// iterating through one bits.
15-
#[derive(Clone, Default, Debug)]
15+
#[derive(Clone, Default, Debug, Eq, PartialEq)]
1616
pub(crate) struct BitVec<'a> {
1717
num_bits: usize,
1818
blocks: Cow<'a, [u64]>,
1919
}
2020

21-
impl PartialEq for BitVec<'_> {
22-
fn eq(&self, other: &Self) -> bool {
23-
self.bit_chunks().eq(other.bit_chunks())
24-
}
25-
}
26-
27-
impl Eq for BitVec<'_> {}
28-
2921
impl Ord for BitVec<'_> {
3022
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
3123
match self.num_bits.cmp(&other.num_bits) {
@@ -49,11 +41,9 @@ impl BitVec<'_> {
4941
/// NOTE: If the bitchunks iterator is empty, the result is NOT sized to `num_bits` but will
5042
/// be EMPTY instead.
5143
pub fn from_bit_chunks<I: Iterator<Item = BitChunk>>(
52-
mut chunks: Peekable<I>,
44+
chunks: Peekable<I>,
5345
num_bits: usize,
5446
) -> Self {
55-
// if there are no chunks, we keep the size zero
56-
let num_bits = chunks.peek().map(|_| num_bits).unwrap_or_default();
5747
let mut result = Self::default();
5848
result.resize(num_bits);
5949
let blocks = result.blocks.to_mut();

0 commit comments

Comments
 (0)