Skip to content

Commit 43a5922

Browse files
carljmAlexWaygood
andauthored
[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 <[email protected]>
1 parent 175d067 commit 43a5922

File tree

1 file changed

+85
-2
lines changed
  • crates/red_knot_python_semantic/src/semantic_index/use_def

1 file changed

+85
-2
lines changed

crates/red_knot_python_semantic/src/semantic_index/use_def/bitset.rs

+85-2
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,26 @@ impl<const B: usize> BitSet<B> {
3232
bitset
3333
}
3434

35+
#[allow(unused)]
36+
pub(super) fn is_empty(&self) -> bool {
37+
self.blocks().iter().all(|&b| b == 0)
38+
}
39+
3540
/// Convert from Inline to Heap, if needed, and resize the Heap vector, if needed.
3641
fn resize(&mut self, value: u32) {
3742
let num_blocks_needed = (value / 64) + 1;
43+
self.resize_blocks(num_blocks_needed as usize);
44+
}
45+
46+
fn resize_blocks(&mut self, num_blocks_needed: usize) {
3847
match self {
3948
Self::Inline(blocks) => {
4049
let mut vec = blocks.to_vec();
41-
vec.resize(num_blocks_needed as usize, 0);
50+
vec.resize(num_blocks_needed, 0);
4251
*self = Self::Heap(vec);
4352
}
4453
Self::Heap(vec) => {
45-
vec.resize(num_blocks_needed as usize, 0);
54+
vec.resize(num_blocks_needed, 0);
4655
}
4756
}
4857
}
@@ -89,6 +98,20 @@ impl<const B: usize> BitSet<B> {
8998
}
9099
}
91100

101+
/// Union in-place with another [`BitSet`].
102+
#[allow(unused)]
103+
pub(super) fn union(&mut self, other: &BitSet<B>) {
104+
let mut max_len = self.blocks().len();
105+
let other_len = other.blocks().len();
106+
if other_len > max_len {
107+
max_len = other_len;
108+
self.resize_blocks(max_len);
109+
}
110+
for (my_block, other_block) in self.blocks_mut().iter_mut().zip(other.blocks()) {
111+
*my_block |= other_block;
112+
}
113+
}
114+
92115
/// Return an iterator over the values (in ascending order) in this [`BitSet`].
93116
pub(super) fn iter(&self) -> BitSetIterator<'_, B> {
94117
let blocks = self.blocks();
@@ -218,11 +241,71 @@ mod tests {
218241
assert_bitset(&b1, &[89]);
219242
}
220243

244+
#[test]
245+
fn union() {
246+
let mut b1 = BitSet::<1>::with(2);
247+
let b2 = BitSet::<1>::with(4);
248+
249+
b1.union(&b2);
250+
assert_bitset(&b1, &[2, 4]);
251+
}
252+
253+
#[test]
254+
fn union_mixed_1() {
255+
let mut b1 = BitSet::<1>::with(4);
256+
let mut b2 = BitSet::<1>::with(4);
257+
b1.insert(89);
258+
b2.insert(5);
259+
260+
b1.union(&b2);
261+
assert_bitset(&b1, &[4, 5, 89]);
262+
}
263+
264+
#[test]
265+
fn union_mixed_2() {
266+
let mut b1 = BitSet::<1>::with(4);
267+
let mut b2 = BitSet::<1>::with(4);
268+
b1.insert(23);
269+
b2.insert(89);
270+
271+
b1.union(&b2);
272+
assert_bitset(&b1, &[4, 23, 89]);
273+
}
274+
275+
#[test]
276+
fn union_heap() {
277+
let mut b1 = BitSet::<1>::with(4);
278+
let mut b2 = BitSet::<1>::with(4);
279+
b1.insert(89);
280+
b2.insert(90);
281+
282+
b1.union(&b2);
283+
assert_bitset(&b1, &[4, 89, 90]);
284+
}
285+
286+
#[test]
287+
fn union_heap_2() {
288+
let mut b1 = BitSet::<1>::with(89);
289+
let mut b2 = BitSet::<1>::with(89);
290+
b1.insert(91);
291+
b2.insert(90);
292+
293+
b1.union(&b2);
294+
assert_bitset(&b1, &[89, 90, 91]);
295+
}
296+
221297
#[test]
222298
fn multiple_blocks() {
223299
let mut b = BitSet::<2>::with(120);
224300
b.insert(45);
225301
assert!(matches!(b, BitSet::Inline(_)));
226302
assert_bitset(&b, &[45, 120]);
227303
}
304+
305+
#[test]
306+
fn empty() {
307+
let b = BitSet::<1>::default();
308+
309+
assert!(b.is_empty());
310+
}
228311
}

0 commit comments

Comments
 (0)