From 3f23715e64aa28bcf41a6126cfabaa90bd74dc59 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 17 Oct 2025 15:21:57 +1100 Subject: [PATCH] Store `chunk_domain_size` explicitly in `Chunk`. Currently we compute it on demand, but it's a little simpler and slightly faster to store it. --- compiler/rustc_index/src/bit_set.rs | 226 +++++++++------------- compiler/rustc_index/src/bit_set/tests.rs | 56 +++--- 2 files changed, 114 insertions(+), 168 deletions(-) diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index 96e85fdb10a6e..e6696f685346a 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -490,15 +490,15 @@ pub struct ChunkedBitSet { marker: PhantomData, } -// NOTE: The chunk size is computed on-the-fly on each manipulation of a chunk. -// This avoids storing it, as it's almost always CHUNK_BITS except for the last one. +// NOTE: The chunk domain size is stored in each variant because it keeps the +// size of `Chunk` smaller than if it were stored outside the variants. #[derive(Clone, Debug, PartialEq, Eq)] enum Chunk { /// A chunk that is all zeros; we don't represent the zeros explicitly. - Zeros, + Zeros(ChunkSize), /// A chunk that is all ones; we don't represent the ones explicitly. - Ones, + Ones(ChunkSize), /// A chunk that has a mix of zeros and ones, which are represented /// explicitly and densely. It never has all zeros or all ones. @@ -516,7 +516,7 @@ enum Chunk { /// duplicate an entire chunk, e.g. in `ChunkedBitSet::clone_from()`, or /// when a `Mixed` chunk is union'd into a `Zeros` chunk. When we do need /// to modify a chunk we use `Rc::make_mut`. - Mixed(ChunkSize, Rc<[Word; CHUNK_WORDS]>), + Mixed(ChunkSize, ChunkSize, Rc<[Word; CHUNK_WORDS]>), } // This type is used a lot. Make sure it doesn't unintentionally get bigger. @@ -528,22 +528,6 @@ impl ChunkedBitSet { self.domain_size } - #[inline] - fn last_chunk_size(&self) -> ChunkSize { - let n = self.domain_size % CHUNK_BITS; - if n == 0 { CHUNK_BITS as ChunkSize } else { n as ChunkSize } - } - - /// All the chunks have a chunk_domain_size of `CHUNK_BITS` except the final one. - #[inline] - fn chunk_domain_size(&self, chunk: usize) -> ChunkSize { - if chunk == self.chunks.len() - 1 { - self.last_chunk_size() - } else { - CHUNK_BITS as ChunkSize - } - } - #[cfg(test)] fn assert_valid(&self) { if self.domain_size == 0 { @@ -553,9 +537,8 @@ impl ChunkedBitSet { assert!((self.chunks.len() - 1) * CHUNK_BITS <= self.domain_size); assert!(self.chunks.len() * CHUNK_BITS >= self.domain_size); - for (chunk_index, chunk) in self.chunks.iter().enumerate() { - let chunk_domain_size = self.chunk_domain_size(chunk_index); - chunk.assert_valid(chunk_domain_size); + for chunk in self.chunks.iter() { + chunk.assert_valid(); } } } @@ -566,7 +549,22 @@ impl ChunkedBitSet { let chunks = if domain_size == 0 { Box::new([]) } else { - vec![if is_empty { Zeros } else { Ones }; num_chunks(domain_size)].into_boxed_slice() + let num_chunks = domain_size.index().div_ceil(CHUNK_BITS); + let mut last_chunk_domain_size = domain_size % CHUNK_BITS; + if last_chunk_domain_size == 0 { + last_chunk_domain_size = CHUNK_BITS; + }; + + // All the chunks are the same except the last one which might have a different + // `chunk_domain_size`. + let (normal_chunk, final_chunk) = if is_empty { + (Zeros(CHUNK_BITS as ChunkSize), Zeros(last_chunk_domain_size as ChunkSize)) + } else { + (Ones(CHUNK_BITS as ChunkSize), Ones(last_chunk_domain_size as ChunkSize)) + }; + let mut chunks = vec![normal_chunk; num_chunks].into_boxed_slice(); + *chunks.as_mut().last_mut().unwrap() = final_chunk; + chunks }; ChunkedBitSet { domain_size, chunks, marker: PhantomData } } @@ -584,7 +582,8 @@ impl ChunkedBitSet { } pub fn clear(&mut self) { - self.chunks.fill_with(|| Chunk::Zeros); + // Not the most efficient implementation, but this function isn't hot. + *self = ChunkedBitSet::new_empty(self.domain_size); } #[cfg(test)] @@ -594,15 +593,11 @@ impl ChunkedBitSet { /// Count the number of bits in the set. pub fn count(&self) -> usize { - self.chunks - .iter() - .enumerate() - .map(|(index, chunk)| chunk.count(self.chunk_domain_size(index))) - .sum() + self.chunks.iter().map(|chunk| chunk.count()).sum() } pub fn is_empty(&self) -> bool { - self.chunks.iter().all(|chunk| matches!(chunk, Zeros)) + self.chunks.iter().all(|chunk| matches!(chunk, Zeros(_))) } /// Returns `true` if `self` contains `elem`. @@ -611,9 +606,9 @@ impl ChunkedBitSet { assert!(elem.index() < self.domain_size); let chunk = &self.chunks[chunk_index(elem)]; match &chunk { - Zeros => false, - Ones => true, - Mixed(_, words) => { + Zeros(_) => false, + Ones(_) => true, + Mixed(_, _, words) => { let (word_index, mask) = chunk_word_index_and_mask(elem); (words[word_index] & mask) != 0 } @@ -629,10 +624,9 @@ impl ChunkedBitSet { pub fn insert(&mut self, elem: T) -> bool { assert!(elem.index() < self.domain_size); let chunk_index = chunk_index(elem); - let chunk_domain_size = self.chunk_domain_size(chunk_index); let chunk = &mut self.chunks[chunk_index]; match *chunk { - Zeros => { + Zeros(chunk_domain_size) => { if chunk_domain_size > 1 { #[cfg(feature = "nightly")] let mut words = { @@ -654,14 +648,14 @@ impl ChunkedBitSet { let (word_index, mask) = chunk_word_index_and_mask(elem); words_ref[word_index] |= mask; - *chunk = Mixed(1, words); + *chunk = Mixed(chunk_domain_size, 1, words); } else { - *chunk = Ones; + *chunk = Ones(chunk_domain_size); } true } - Ones => false, - Mixed(ref mut count, ref mut words) => { + Ones(_) => false, + Mixed(chunk_domain_size, ref mut count, ref mut words) => { // We skip all the work if the bit is already set. let (word_index, mask) = chunk_word_index_and_mask(elem); if (words[word_index] & mask) == 0 { @@ -670,7 +664,7 @@ impl ChunkedBitSet { let words = Rc::make_mut(words); words[word_index] |= mask; } else { - *chunk = Ones; + *chunk = Ones(chunk_domain_size); } true } else { @@ -682,18 +676,18 @@ impl ChunkedBitSet { /// Sets all bits to true. pub fn insert_all(&mut self) { - self.chunks.fill_with(|| Chunk::Ones); + // Not the most efficient implementation, but this function isn't hot. + *self = ChunkedBitSet::new_filled(self.domain_size); } /// Returns `true` if the set has changed. pub fn remove(&mut self, elem: T) -> bool { assert!(elem.index() < self.domain_size); let chunk_index = chunk_index(elem); - let chunk_domain_size = self.chunk_domain_size(chunk_index); let chunk = &mut self.chunks[chunk_index]; match *chunk { - Zeros => false, - Ones => { + Zeros(_) => false, + Ones(chunk_domain_size) => { if chunk_domain_size > 1 { #[cfg(feature = "nightly")] let mut words = { @@ -722,13 +716,13 @@ impl ChunkedBitSet { ); let (word_index, mask) = chunk_word_index_and_mask(elem); words_ref[word_index] &= !mask; - *chunk = Mixed(chunk_domain_size - 1, words); + *chunk = Mixed(chunk_domain_size, chunk_domain_size - 1, words); } else { - *chunk = Zeros; + *chunk = Zeros(chunk_domain_size); } true } - Mixed(ref mut count, ref mut words) => { + Mixed(chunk_domain_size, ref mut count, ref mut words) => { // We skip all the work if the bit is already clear. let (word_index, mask) = chunk_word_index_and_mask(elem); if (words[word_index] & mask) != 0 { @@ -737,7 +731,7 @@ impl ChunkedBitSet { let words = Rc::make_mut(words); words[word_index] &= !mask; } else { - *chunk = Zeros + *chunk = Zeros(chunk_domain_size) } true } else { @@ -748,12 +742,11 @@ impl ChunkedBitSet { } fn chunk_iter(&self, chunk_index: usize) -> ChunkIter<'_> { - let chunk_domain_size = self.chunk_domain_size(chunk_index); match self.chunks.get(chunk_index) { - Some(Zeros) => ChunkIter::Zeros, - Some(Ones) => ChunkIter::Ones(0..chunk_domain_size as usize), - Some(Mixed(_, words)) => { - let num_words = num_words(chunk_domain_size as usize); + Some(Zeros(_)) => ChunkIter::Zeros, + Some(Ones(chunk_domain_size)) => ChunkIter::Ones(0..*chunk_domain_size as usize), + Some(Mixed(chunk_domain_size, _, words)) => { + let num_words = num_words(*chunk_domain_size as usize); ChunkIter::Mixed(BitIter::new(&words[0..num_words])) } None => ChunkIter::Finished, @@ -767,39 +760,25 @@ impl BitRelations> for ChunkedBitSet { fn union(&mut self, other: &ChunkedBitSet) -> bool { assert_eq!(self.domain_size, other.domain_size); - let num_chunks = self.chunks.len(); - debug_assert_eq!(num_chunks, other.chunks.len()); - - let last_chunk_size = self.last_chunk_size(); - debug_assert_eq!(last_chunk_size, other.last_chunk_size()); - let mut changed = false; - for (chunk_index, (mut self_chunk, other_chunk)) in - self.chunks.iter_mut().zip(other.chunks.iter()).enumerate() - { - let chunk_domain_size = if chunk_index + 1 == num_chunks { - last_chunk_size - } else { - CHUNK_BITS as ChunkSize - }; - + for (mut self_chunk, other_chunk) in self.chunks.iter_mut().zip(other.chunks.iter()) { match (&mut self_chunk, &other_chunk) { - (_, Zeros) | (Ones, _) => {} - (Zeros, _) | (Mixed(..), Ones) => { + (_, Zeros(_)) | (Ones(_), _) => {} + (Zeros(_), _) | (Mixed(..), Ones(_)) => { // `other_chunk` fully overwrites `self_chunk` *self_chunk = other_chunk.clone(); changed = true; } ( - Mixed(self_chunk_count, self_chunk_words), - Mixed(_other_chunk_count, other_chunk_words), + Mixed(chunk_domain_size, self_chunk_count, self_chunk_words), + Mixed(_, _, other_chunk_words), ) => { // First check if the operation would change // `self_chunk.words`. If not, we can avoid allocating some // words, and this happens often enough that it's a // performance win. Also, we only need to operate on the // in-use words, hence the slicing. - let num_words = num_words(chunk_domain_size as usize); + let num_words = num_words(*chunk_domain_size as usize); // If both sides are the same, nothing will change. This // case is very common and it's a pretty fast check, so @@ -828,8 +807,8 @@ impl BitRelations> for ChunkedBitSet { ); debug_assert!(has_changed); *self_chunk_count = count_ones(&self_chunk_words[0..num_words]) as ChunkSize; - if *self_chunk_count == chunk_domain_size { - *self_chunk = Ones; + if *self_chunk_count == *chunk_domain_size { + *self_chunk = Ones(*chunk_domain_size); } changed = true; } @@ -841,52 +820,39 @@ impl BitRelations> for ChunkedBitSet { fn subtract(&mut self, other: &ChunkedBitSet) -> bool { assert_eq!(self.domain_size, other.domain_size); - let num_chunks = self.chunks.len(); - debug_assert_eq!(num_chunks, other.chunks.len()); - - let last_chunk_size = self.last_chunk_size(); - debug_assert_eq!(last_chunk_size, other.last_chunk_size()); - let mut changed = false; - for (chunk_index, (mut self_chunk, other_chunk)) in - self.chunks.iter_mut().zip(other.chunks.iter()).enumerate() - { - let chunk_domain_size = if chunk_index + 1 == num_chunks { - last_chunk_size - } else { - CHUNK_BITS as ChunkSize - }; - + for (mut self_chunk, other_chunk) in self.chunks.iter_mut().zip(other.chunks.iter()) { match (&mut self_chunk, &other_chunk) { - (Zeros, _) | (_, Zeros) => {} - (Ones | Mixed(..), Ones) => { + (Zeros(_), _) | (_, Zeros(_)) => {} + (Ones(chunk_domain_size) | Mixed(chunk_domain_size, ..), Ones(_)) => { changed = true; - *self_chunk = Zeros; + *self_chunk = Zeros(*chunk_domain_size); } - (Ones, Mixed(other_chunk_count, other_chunk_words)) => { + (Ones(chunk_domain_size), Mixed(_, other_chunk_count, other_chunk_words)) => { changed = true; - let num_words = num_words(chunk_domain_size as usize); + let num_words = num_words(*chunk_domain_size as usize); debug_assert!(num_words > 0 && num_words <= CHUNK_WORDS); let mut tail_mask = - 1 << (chunk_domain_size - ((num_words - 1) * WORD_BITS) as u16) - 1; + 1 << (*chunk_domain_size - ((num_words - 1) * WORD_BITS) as u16) - 1; let mut self_chunk_words = **other_chunk_words; for word in self_chunk_words[0..num_words].iter_mut().rev() { *word = !*word & tail_mask; tail_mask = Word::MAX; } - let self_chunk_count = chunk_domain_size - *other_chunk_count; + let self_chunk_count = *chunk_domain_size - *other_chunk_count; debug_assert_eq!( self_chunk_count, count_ones(&self_chunk_words[0..num_words]) as ChunkSize ); - *self_chunk = Mixed(self_chunk_count, Rc::new(self_chunk_words)); + *self_chunk = + Mixed(*chunk_domain_size, self_chunk_count, Rc::new(self_chunk_words)); } ( - Mixed(self_chunk_count, self_chunk_words), - Mixed(_other_chunk_count, other_chunk_words), + Mixed(chunk_domain_size, self_chunk_count, self_chunk_words), + Mixed(_, _, other_chunk_words), ) => { // See `ChunkedBitSet::union` for details on what is happening here. - let num_words = num_words(chunk_domain_size as usize); + let num_words = num_words(*chunk_domain_size as usize); let op = |a: Word, b: Word| a & !b; if !bitwise_changes( &self_chunk_words[0..num_words], @@ -905,7 +871,7 @@ impl BitRelations> for ChunkedBitSet { debug_assert!(has_changed); *self_chunk_count = count_ones(&self_chunk_words[0..num_words]) as ChunkSize; if *self_chunk_count == 0 { - *self_chunk = Zeros; + *self_chunk = Zeros(*chunk_domain_size); } changed = true; } @@ -917,34 +883,20 @@ impl BitRelations> for ChunkedBitSet { fn intersect(&mut self, other: &ChunkedBitSet) -> bool { assert_eq!(self.domain_size, other.domain_size); - let num_chunks = self.chunks.len(); - debug_assert_eq!(num_chunks, other.chunks.len()); - - let last_chunk_size = self.last_chunk_size(); - debug_assert_eq!(last_chunk_size, other.last_chunk_size()); - let mut changed = false; - for (chunk_index, (mut self_chunk, other_chunk)) in - self.chunks.iter_mut().zip(other.chunks.iter()).enumerate() - { - let chunk_domain_size = if chunk_index + 1 == num_chunks { - last_chunk_size - } else { - CHUNK_BITS as ChunkSize - }; - + for (mut self_chunk, other_chunk) in self.chunks.iter_mut().zip(other.chunks.iter()) { match (&mut self_chunk, &other_chunk) { - (Zeros, _) | (_, Ones) => {} - (Ones, Zeros | Mixed(..)) | (Mixed(..), Zeros) => { + (Zeros(_), _) | (_, Ones(_)) => {} + (Ones(_), Zeros(_) | Mixed(..)) | (Mixed(..), Zeros(_)) => { changed = true; *self_chunk = other_chunk.clone(); } ( - Mixed(self_chunk_count, self_chunk_words), - Mixed(_other_chunk_count, other_chunk_words), + Mixed(chunk_domain_size, self_chunk_count, self_chunk_words), + Mixed(_, _, other_chunk_words), ) => { // See `ChunkedBitSet::union` for details on what is happening here. - let num_words = num_words(chunk_domain_size as usize); + let num_words = num_words(*chunk_domain_size as usize); let op = |a, b| a & b; if !bitwise_changes( &self_chunk_words[0..num_words], @@ -963,7 +915,7 @@ impl BitRelations> for ChunkedBitSet { debug_assert!(has_changed); *self_chunk_count = count_ones(&self_chunk_words[0..num_words]) as ChunkSize; if *self_chunk_count == 0 { - *self_chunk = Zeros; + *self_chunk = Zeros(*chunk_domain_size); } changed = true; } @@ -1039,11 +991,13 @@ impl<'a, T: Idx> Iterator for ChunkedBitIter<'a, T> { impl Chunk { #[cfg(test)] - fn assert_valid(&self, chunk_domain_size: ChunkSize) { - assert!(chunk_domain_size as usize <= CHUNK_BITS); + fn assert_valid(&self) { match *self { - Zeros | Ones => {} - Mixed(count, ref words) => { + Zeros(chunk_domain_size) | Ones(chunk_domain_size) => { + assert!(chunk_domain_size as usize <= CHUNK_BITS); + } + Mixed(chunk_domain_size, count, ref words) => { + assert!(chunk_domain_size as usize <= CHUNK_BITS); assert!(0 < count && count < chunk_domain_size); // Check the number of set bits matches `count`. @@ -1059,11 +1013,11 @@ impl Chunk { } /// Count the number of 1s in the chunk. - fn count(&self, chunk_domain_size: ChunkSize) -> usize { + fn count(&self) -> usize { match *self { - Zeros => 0, - Ones => chunk_domain_size as usize, - Mixed(count, _) => count as usize, + Zeros(_) => 0, + Ones(chunk_domain_size) => chunk_domain_size as usize, + Mixed(_, count, _) => count as usize, } } } @@ -1707,12 +1661,6 @@ fn num_words(domain_size: T) -> usize { domain_size.index().div_ceil(WORD_BITS) } -#[inline] -fn num_chunks(domain_size: T) -> usize { - assert!(domain_size.index() > 0); - domain_size.index().div_ceil(CHUNK_BITS) -} - #[inline] fn word_index_and_mask(elem: T) -> (usize, Word) { let elem = elem.index(); diff --git a/compiler/rustc_index/src/bit_set/tests.rs b/compiler/rustc_index/src/bit_set/tests.rs index 341e0622df75e..45056771ecf14 100644 --- a/compiler/rustc_index/src/bit_set/tests.rs +++ b/compiler/rustc_index/src/bit_set/tests.rs @@ -120,9 +120,8 @@ fn chunked_bitset() { let mut b1 = ChunkedBitSet::::new_empty(1); assert_eq!( b1, - ChunkedBitSet { domain_size: 1, chunks: Box::new([Zeros]), marker: PhantomData } + ChunkedBitSet { domain_size: 1, chunks: Box::new([Zeros(1)]), marker: PhantomData } ); - assert_eq!(b1.chunk_domain_size(0), 1); b1.assert_valid(); assert!(!b1.contains(0)); @@ -130,12 +129,12 @@ fn chunked_bitset() { assert!(b1.insert(0)); assert!(b1.contains(0)); assert_eq!(b1.count(), 1); - assert_eq!(b1.chunks(), [Ones]); + assert_eq!(b1.chunks(), [Ones(1)]); assert!(!b1.insert(0)); assert!(b1.remove(0)); assert!(!b1.contains(0)); assert_eq!(b1.count(), 0); - assert_eq!(b1.chunks(), [Zeros]); + assert_eq!(b1.chunks(), [Zeros(1)]); b1.assert_valid(); //----------------------------------------------------------------------- @@ -143,9 +142,8 @@ fn chunked_bitset() { let mut b100 = ChunkedBitSet::::new_filled(100); assert_eq!( b100, - ChunkedBitSet { domain_size: 100, chunks: Box::new([Ones]), marker: PhantomData } + ChunkedBitSet { domain_size: 100, chunks: Box::new([Ones(100)]), marker: PhantomData } ); - assert_eq!(b100.chunk_domain_size(0), 100); b100.assert_valid(); for i in 0..100 { @@ -154,7 +152,7 @@ fn chunked_bitset() { assert_eq!(b100.count(), 100); assert!(b100.remove(3)); assert!(b100.insert(3)); - assert_eq!(b100.chunks(), vec![Ones]); + assert_eq!(b100.chunks(), vec![Ones(100)]); assert!( b100.remove(20) && b100.remove(30) && b100.remove(40) && b100.remove(99) && b100.insert(30) ); @@ -163,6 +161,7 @@ fn chunked_bitset() { assert_eq!( b100.chunks(), vec![Mixed( + 100, 97, #[rustfmt::skip] Rc::new([ @@ -181,7 +180,7 @@ fn chunked_bitset() { } } assert_eq!(num_removed, 97); - assert_eq!(b100.chunks(), vec![Zeros]); + assert_eq!(b100.chunks(), vec![Zeros(100)]); b100.assert_valid(); //----------------------------------------------------------------------- @@ -189,21 +188,23 @@ fn chunked_bitset() { let mut b2548 = ChunkedBitSet::::new_empty(2548); assert_eq!( b2548, - ChunkedBitSet { domain_size: 2548, chunks: Box::new([Zeros, Zeros]), marker: PhantomData } + ChunkedBitSet { + domain_size: 2548, + chunks: Box::new([Zeros(2048), Zeros(500)]), + marker: PhantomData + } ); - assert_eq!(b2548.chunk_domain_size(0), 2048); - assert_eq!(b2548.chunk_domain_size(1), 500); b2548.assert_valid(); b2548.insert(14); b2548.remove(14); - assert_eq!(b2548.chunks(), vec![Zeros, Zeros]); + assert_eq!(b2548.chunks(), vec![Zeros(2048), Zeros(500)]); b2548.insert_all(); for i in 0..2548 { assert!(b2548.contains(i)); } assert_eq!(b2548.count(), 2548); - assert_eq!(b2548.chunks(), vec![Ones, Ones]); + assert_eq!(b2548.chunks(), vec![Ones(2048), Ones(500)]); b2548.assert_valid(); //----------------------------------------------------------------------- @@ -211,10 +212,12 @@ fn chunked_bitset() { let mut b4096 = ChunkedBitSet::::new_empty(4096); assert_eq!( b4096, - ChunkedBitSet { domain_size: 4096, chunks: Box::new([Zeros, Zeros]), marker: PhantomData } + ChunkedBitSet { + domain_size: 4096, + chunks: Box::new([Zeros(2048), Zeros(2048)]), + marker: PhantomData + } ); - assert_eq!(b4096.chunk_domain_size(0), 2048); - assert_eq!(b4096.chunk_domain_size(1), 2048); b4096.assert_valid(); for i in 0..4096 { @@ -228,11 +231,11 @@ fn chunked_bitset() { b4096.chunks(), #[rustfmt::skip] vec![ - Mixed(1, Rc::new([ + Mixed(2048, 1, Rc::new([ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ])), - Mixed(1, Rc::new([ + Mixed(2048, 1, Rc::new([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x8000_0000_0000_0000 ])), @@ -248,15 +251,10 @@ fn chunked_bitset() { b10000, ChunkedBitSet { domain_size: 10000, - chunks: Box::new([Zeros, Zeros, Zeros, Zeros, Zeros,]), + chunks: Box::new([Zeros(2048), Zeros(2048), Zeros(2048), Zeros(2048), Zeros(1808)]), marker: PhantomData, } ); - assert_eq!(b10000.chunk_domain_size(0), 2048); - assert_eq!(b10000.chunk_domain_size(1), 2048); - assert_eq!(b10000.chunk_domain_size(2), 2048); - assert_eq!(b10000.chunk_domain_size(3), 2048); - assert_eq!(b10000.chunk_domain_size(4), 1808); b10000.assert_valid(); assert!(b10000.insert(3000) && b10000.insert(5000)); @@ -264,17 +262,17 @@ fn chunked_bitset() { b10000.chunks(), #[rustfmt::skip] vec![ - Zeros, - Mixed(1, Rc::new([ + Zeros(2048), + Mixed(2048, 1, Rc::new([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0100_0000_0000_0000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ])), - Mixed(1, Rc::new([ + Mixed(2048, 1, Rc::new([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ])), - Zeros, - Zeros, + Zeros(2048), + Zeros(1808), ], ); let mut b10000b = ChunkedBitSet::::new_empty(10000);