From 43a5922f6f11784f74e6f553467b1be802bc2213 Mon Sep 17 00:00:00 2001 From: Carl Meyer Date: Thu, 12 Sep 2024 14:25:45 -0400 Subject: [PATCH] [red-knot] add BitSet::is_empty and BitSet::union (#13333) Add `::is_empty` and `::union` methods to the `BitSet` implementation. Allowing unused for now, until these methods become used later with the declared-types implementation. --------- Co-authored-by: Alex Waygood --- .../src/semantic_index/use_def/bitset.rs | 87 ++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/crates/red_knot_python_semantic/src/semantic_index/use_def/bitset.rs b/crates/red_knot_python_semantic/src/semantic_index/use_def/bitset.rs index ac8ce65398e1b..2d9611c54ed9a 100644 --- a/crates/red_knot_python_semantic/src/semantic_index/use_def/bitset.rs +++ b/crates/red_knot_python_semantic/src/semantic_index/use_def/bitset.rs @@ -32,17 +32,26 @@ impl BitSet { bitset } + #[allow(unused)] + pub(super) fn is_empty(&self) -> bool { + self.blocks().iter().all(|&b| b == 0) + } + /// Convert from Inline to Heap, if needed, and resize the Heap vector, if needed. fn resize(&mut self, value: u32) { let num_blocks_needed = (value / 64) + 1; + self.resize_blocks(num_blocks_needed as usize); + } + + fn resize_blocks(&mut self, num_blocks_needed: usize) { match self { Self::Inline(blocks) => { let mut vec = blocks.to_vec(); - vec.resize(num_blocks_needed as usize, 0); + vec.resize(num_blocks_needed, 0); *self = Self::Heap(vec); } Self::Heap(vec) => { - vec.resize(num_blocks_needed as usize, 0); + vec.resize(num_blocks_needed, 0); } } } @@ -89,6 +98,20 @@ impl BitSet { } } + /// Union in-place with another [`BitSet`]. + #[allow(unused)] + pub(super) fn union(&mut self, other: &BitSet) { + let mut max_len = self.blocks().len(); + let other_len = other.blocks().len(); + if other_len > max_len { + max_len = other_len; + self.resize_blocks(max_len); + } + for (my_block, other_block) in self.blocks_mut().iter_mut().zip(other.blocks()) { + *my_block |= other_block; + } + } + /// Return an iterator over the values (in ascending order) in this [`BitSet`]. pub(super) fn iter(&self) -> BitSetIterator<'_, B> { let blocks = self.blocks(); @@ -218,6 +241,59 @@ mod tests { assert_bitset(&b1, &[89]); } + #[test] + fn union() { + let mut b1 = BitSet::<1>::with(2); + let b2 = BitSet::<1>::with(4); + + b1.union(&b2); + assert_bitset(&b1, &[2, 4]); + } + + #[test] + fn union_mixed_1() { + let mut b1 = BitSet::<1>::with(4); + let mut b2 = BitSet::<1>::with(4); + b1.insert(89); + b2.insert(5); + + b1.union(&b2); + assert_bitset(&b1, &[4, 5, 89]); + } + + #[test] + fn union_mixed_2() { + let mut b1 = BitSet::<1>::with(4); + let mut b2 = BitSet::<1>::with(4); + b1.insert(23); + b2.insert(89); + + b1.union(&b2); + assert_bitset(&b1, &[4, 23, 89]); + } + + #[test] + fn union_heap() { + let mut b1 = BitSet::<1>::with(4); + let mut b2 = BitSet::<1>::with(4); + b1.insert(89); + b2.insert(90); + + b1.union(&b2); + assert_bitset(&b1, &[4, 89, 90]); + } + + #[test] + fn union_heap_2() { + let mut b1 = BitSet::<1>::with(89); + let mut b2 = BitSet::<1>::with(89); + b1.insert(91); + b2.insert(90); + + b1.union(&b2); + assert_bitset(&b1, &[89, 90, 91]); + } + #[test] fn multiple_blocks() { let mut b = BitSet::<2>::with(120); @@ -225,4 +301,11 @@ mod tests { assert!(matches!(b, BitSet::Inline(_))); assert_bitset(&b, &[45, 120]); } + + #[test] + fn empty() { + let b = BitSet::<1>::default(); + + assert!(b.is_empty()); + } }