1+ use std:: hash:: { Hash , Hasher } ;
12use std:: marker:: PhantomData ;
23use std:: ops:: { Bound , Range , RangeBounds } ;
34use std:: rc:: Rc ;
@@ -112,10 +113,10 @@ macro_rules! bit_relations_inherent_impls {
112113/// will panic if the bitsets have differing domain sizes.
113114///
114115#[ cfg_attr( feature = "nightly" , derive( Decodable_NoContext , Encodable_NoContext ) ) ]
115- #[ derive( Eq , PartialEq , Hash ) ]
116116pub struct DenseBitSet < T > {
117117 domain_size : usize ,
118- words : Vec < Word > ,
118+ // Lazily allocated. `None` represents a full set of zero words.
119+ words : Option < Vec < Word > > ,
119120 marker : PhantomData < T > ,
120121}
121122
@@ -124,61 +125,90 @@ impl<T> DenseBitSet<T> {
124125 pub fn domain_size ( & self ) -> usize {
125126 self . domain_size
126127 }
128+
129+ #[ inline]
130+ fn num_words ( & self ) -> usize {
131+ num_words ( self . domain_size )
132+ }
133+
134+ #[ inline]
135+ fn words ( & self ) -> & [ Word ] {
136+ self . words . as_deref ( ) . unwrap_or ( & [ ] )
137+ }
138+
139+ #[ inline]
140+ fn ensure_words ( & mut self ) -> & mut Vec < Word > {
141+ let num_words = self . num_words ( ) ;
142+ self . words . get_or_insert_with ( || vec ! [ 0 ; num_words] )
143+ }
144+
145+ #[ inline]
146+ fn word ( & self , word_index : usize ) -> Word {
147+ self . words ( ) . get ( word_index) . copied ( ) . unwrap_or ( 0 )
148+ }
127149}
128150
129151impl < T : Idx > DenseBitSet < T > {
130152 /// Creates a new, empty bitset with a given `domain_size`.
131153 #[ inline]
132154 pub fn new_empty ( domain_size : usize ) -> DenseBitSet < T > {
133- let num_words = num_words ( domain_size) ;
134- DenseBitSet { domain_size, words : vec ! [ 0 ; num_words] , marker : PhantomData }
155+ DenseBitSet { domain_size, words : None , marker : PhantomData }
135156 }
136157
137158 /// Creates a new, filled bitset with a given `domain_size`.
138159 #[ inline]
139160 pub fn new_filled ( domain_size : usize ) -> DenseBitSet < T > {
140161 let num_words = num_words ( domain_size) ;
141- let mut result =
142- DenseBitSet { domain_size, words : vec ! [ ! 0 ; num_words ] , marker : PhantomData } ;
162+ let words = if num_words == 0 { None } else { Some ( vec ! [ ! 0 ; num_words ] ) } ;
163+ let mut result = DenseBitSet { domain_size, words, marker : PhantomData } ;
143164 result. clear_excess_bits ( ) ;
144165 result
145166 }
146167
147168 /// Clear all elements.
148169 #[ inline]
149170 pub fn clear ( & mut self ) {
150- self . words . fill ( 0 ) ;
171+ if let Some ( words) = & mut self . words {
172+ words. fill ( 0 ) ;
173+ }
151174 }
152175
153176 /// Clear excess bits in the final word.
154177 fn clear_excess_bits ( & mut self ) {
155- clear_excess_bits_in_final_word ( self . domain_size , & mut self . words ) ;
178+ if let Some ( words) = & mut self . words {
179+ clear_excess_bits_in_final_word ( self . domain_size , words) ;
180+ }
156181 }
157182
158183 /// Count the number of set bits in the set.
159184 pub fn count ( & self ) -> usize {
160- count_ones ( & self . words )
185+ count_ones ( self . words ( ) )
161186 }
162187
163188 /// Returns `true` if `self` contains `elem`.
164189 #[ inline]
165190 pub fn contains ( & self , elem : T ) -> bool {
166191 assert ! ( elem. index( ) < self . domain_size) ;
167192 let ( word_index, mask) = word_index_and_mask ( elem) ;
168- ( self . words [ word_index] & mask) != 0
193+ ( self . word ( word_index) & mask) != 0
169194 }
170195
171196 /// Is `self` is a (non-strict) superset of `other`?
172197 #[ inline]
173198 pub fn superset ( & self , other : & DenseBitSet < T > ) -> bool {
174199 assert_eq ! ( self . domain_size, other. domain_size) ;
175- self . words . iter ( ) . zip ( & other. words ) . all ( |( a, b) | ( a & b) == * b)
200+ match ( & self . words , & other. words ) {
201+ ( _, None ) => true ,
202+ ( None , Some ( other_words) ) => other_words. iter ( ) . all ( |& word| word == 0 ) ,
203+ ( Some ( _) , Some ( _) ) => ( 0 ..self . num_words ( ) )
204+ . all ( |index| ( self . word ( index) & other. word ( index) ) == other. word ( index) ) ,
205+ }
176206 }
177207
178208 /// Is the set empty?
179209 #[ inline]
180210 pub fn is_empty ( & self ) -> bool {
181- self . words . iter ( ) . all ( |a| * a == 0 )
211+ self . words ( ) . iter ( ) . all ( |a| * a == 0 )
182212 }
183213
184214 /// Insert `elem`. Returns whether the set has changed.
@@ -191,7 +221,7 @@ impl<T: Idx> DenseBitSet<T> {
191221 self . domain_size,
192222 ) ;
193223 let ( word_index, mask) = word_index_and_mask ( elem) ;
194- let word_ref = & mut self . words [ word_index] ;
224+ let word_ref = & mut self . ensure_words ( ) [ word_index] ;
195225 let word = * word_ref;
196226 let new_word = word | mask;
197227 * word_ref = new_word;
@@ -206,28 +236,32 @@ impl<T: Idx> DenseBitSet<T> {
206236
207237 let ( start_word_index, start_mask) = word_index_and_mask ( start) ;
208238 let ( end_word_index, end_mask) = word_index_and_mask ( end) ;
239+ let words = self . ensure_words ( ) ;
209240
210241 // Set all words in between start and end (exclusively of both).
211242 for word_index in ( start_word_index + 1 ) ..end_word_index {
212- self . words [ word_index] = !0 ;
243+ words[ word_index] = !0 ;
213244 }
214245
215246 if start_word_index != end_word_index {
216247 // Start and end are in different words, so we handle each in turn.
217248 //
218249 // We set all leading bits. This includes the start_mask bit.
219- self . words [ start_word_index] |= !( start_mask - 1 ) ;
250+ words[ start_word_index] |= !( start_mask - 1 ) ;
220251 // And all trailing bits (i.e. from 0..=end) in the end word,
221252 // including the end.
222- self . words [ end_word_index] |= end_mask | ( end_mask - 1 ) ;
253+ words[ end_word_index] |= end_mask | ( end_mask - 1 ) ;
223254 } else {
224- self . words [ start_word_index] |= end_mask | ( end_mask - start_mask) ;
255+ words[ start_word_index] |= end_mask | ( end_mask - start_mask) ;
225256 }
226257 }
227258
228259 /// Sets all bits to true.
229260 pub fn insert_all ( & mut self ) {
230- self . words . fill ( !0 ) ;
261+ if self . domain_size == 0 {
262+ return ;
263+ }
264+ self . ensure_words ( ) . fill ( !0 ) ;
231265 self . clear_excess_bits ( ) ;
232266 }
233267
@@ -241,16 +275,16 @@ impl<T: Idx> DenseBitSet<T> {
241275 let ( end_word_index, end_mask) = word_index_and_mask ( end) ;
242276
243277 if start_word_index == end_word_index {
244- self . words [ start_word_index] & ( end_mask | ( end_mask - start_mask) ) != 0
278+ self . word ( start_word_index) & ( end_mask | ( end_mask - start_mask) ) != 0
245279 } else {
246- if self . words [ start_word_index] & !( start_mask - 1 ) != 0 {
280+ if self . word ( start_word_index) & !( start_mask - 1 ) != 0 {
247281 return true ;
248282 }
249283
250284 let remaining = start_word_index + 1 ..end_word_index;
251285 if remaining. start <= remaining. end {
252- self . words [ remaining] . iter ( ) . any ( |& w| w != 0 )
253- || self . words [ end_word_index] & ( end_mask | ( end_mask - 1 ) ) != 0
286+ self . words ( ) . get ( remaining) . is_some_and ( |words| words . iter ( ) . any ( |& w| w != 0 ) )
287+ || self . word ( end_word_index) & ( end_mask | ( end_mask - 1 ) ) != 0
254288 } else {
255289 false
256290 }
@@ -261,8 +295,11 @@ impl<T: Idx> DenseBitSet<T> {
261295 #[ inline]
262296 pub fn remove ( & mut self , elem : T ) -> bool {
263297 assert ! ( elem. index( ) < self . domain_size) ;
298+ let Some ( words) = & mut self . words else {
299+ return false ;
300+ } ;
264301 let ( word_index, mask) = word_index_and_mask ( elem) ;
265- let word_ref = & mut self . words [ word_index] ;
302+ let word_ref = & mut words[ word_index] ;
266303 let word = * word_ref;
267304 let new_word = word & !mask;
268305 * word_ref = new_word;
@@ -272,15 +309,18 @@ impl<T: Idx> DenseBitSet<T> {
272309 /// Iterates over the indices of set bits in a sorted order.
273310 #[ inline]
274311 pub fn iter ( & self ) -> BitIter < ' _ , T > {
275- BitIter :: new ( & self . words )
312+ BitIter :: new ( self . words ( ) )
276313 }
277314
278315 pub fn last_set_in ( & self , range : impl RangeBounds < T > ) -> Option < T > {
279316 let ( start, end) = inclusive_start_end ( range, self . domain_size ) ?;
317+ let Some ( words) = & self . words else {
318+ return None ;
319+ } ;
280320 let ( start_word_index, _) = word_index_and_mask ( start) ;
281321 let ( end_word_index, end_mask) = word_index_and_mask ( end) ;
282322
283- let end_word = self . words [ end_word_index] & ( end_mask | ( end_mask - 1 ) ) ;
323+ let end_word = words[ end_word_index] & ( end_mask | ( end_mask - 1 ) ) ;
284324 if end_word != 0 {
285325 let pos = max_bit ( end_word) + WORD_BITS * end_word_index;
286326 if start <= pos {
@@ -291,11 +331,10 @@ impl<T: Idx> DenseBitSet<T> {
291331 // We exclude end_word_index from the range here, because we don't want
292332 // to limit ourselves to *just* the last word: the bits set it in may be
293333 // after `end`, so it may not work out.
294- if let Some ( offset) =
295- self . words [ start_word_index..end_word_index] . iter ( ) . rposition ( |& w| w != 0 )
334+ if let Some ( offset) = words[ start_word_index..end_word_index] . iter ( ) . rposition ( |& w| w != 0 )
296335 {
297336 let word_idx = start_word_index + offset;
298- let start_word = self . words [ word_idx] ;
337+ let start_word = words[ word_idx] ;
299338 let pos = max_bit ( start_word) + WORD_BITS * word_idx;
300339 if start <= pos {
301340 return Some ( T :: new ( pos) ) ;
@@ -319,7 +358,13 @@ impl<T: Idx> DenseBitSet<T> {
319358 // quickly and accurately detect whether the update changed anything.
320359 // But that's only worth doing if there's an actual use-case.
321360
322- update_words ( & mut self . words , & other. words , |a, b| a | !b) ;
361+ let other_words = other. words ( ) ;
362+ let words = self . ensure_words ( ) ;
363+ if other_words. is_empty ( ) {
364+ words. fill ( !0 ) ;
365+ } else {
366+ update_words ( words, other_words, |a, b| a | !b) ;
367+ }
323368 // The bitwise update `a | !b` can result in the last word containing
324369 // out-of-domain bits, so we need to clear them.
325370 self . clear_excess_bits ( ) ;
@@ -330,17 +375,38 @@ impl<T: Idx> DenseBitSet<T> {
330375impl < T : Idx > BitRelations < DenseBitSet < T > > for DenseBitSet < T > {
331376 fn union ( & mut self , other : & DenseBitSet < T > ) -> bool {
332377 assert_eq ! ( self . domain_size, other. domain_size) ;
333- update_words ( & mut self . words , & other. words , |a, b| a | b)
378+ let Some ( other_words) = & other. words else {
379+ return false ;
380+ } ;
381+ let Some ( words) = & mut self . words else {
382+ if other_words. iter ( ) . all ( |& word| word == 0 ) {
383+ return false ;
384+ }
385+ self . words = Some ( other_words. clone ( ) ) ;
386+ return true ;
387+ } ;
388+ update_words ( words, other_words, |a, b| a | b)
334389 }
335390
336391 fn subtract ( & mut self , other : & DenseBitSet < T > ) -> bool {
337392 assert_eq ! ( self . domain_size, other. domain_size) ;
338- update_words ( & mut self . words , & other. words , |a, b| a & !b)
393+ let ( Some ( words) , Some ( other_words) ) = ( & mut self . words , & other. words ) else {
394+ return false ;
395+ } ;
396+ update_words ( words, other_words, |a, b| a & !b)
339397 }
340398
341399 fn intersect ( & mut self , other : & DenseBitSet < T > ) -> bool {
342400 assert_eq ! ( self . domain_size, other. domain_size) ;
343- update_words ( & mut self . words , & other. words , |a, b| a & b)
401+ let Some ( words) = & mut self . words else {
402+ return false ;
403+ } ;
404+ let Some ( other_words) = & other. words else {
405+ let changed = words. iter ( ) . any ( |& word| word != 0 ) ;
406+ words. fill ( 0 ) ;
407+ return changed;
408+ } ;
409+ update_words ( words, other_words, |a, b| a & b)
344410 }
345411}
346412
@@ -365,6 +431,27 @@ impl<T> Clone for DenseBitSet<T> {
365431 }
366432}
367433
434+ impl < T > PartialEq for DenseBitSet < T > {
435+ fn eq ( & self , other : & Self ) -> bool {
436+ self . domain_size == other. domain_size
437+ && ( 0 ..self . num_words ( ) ) . all ( |index| self . word ( index) == other. word ( index) )
438+ }
439+ }
440+
441+ impl < T > Eq for DenseBitSet < T > { }
442+
443+ impl < T > Hash for DenseBitSet < T > {
444+ fn hash < H : Hasher > ( & self , state : & mut H ) {
445+ self . domain_size . hash ( state) ;
446+
447+ let num_words = self . num_words ( ) ;
448+ num_words. hash ( state) ;
449+ for index in 0 ..num_words {
450+ self . word ( index) . hash ( state) ;
451+ }
452+ }
453+ }
454+
368455impl < T : Idx > fmt:: Debug for DenseBitSet < T > {
369456 fn fmt ( & self , w : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
370457 w. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
@@ -380,8 +467,8 @@ impl<T: Idx> ToString for DenseBitSet<T> {
380467
381468 // i tracks how many bits we have printed so far.
382469 let mut i = 0 ;
383- for word in & self . words {
384- let mut word = * word;
470+ for word_index in 0 .. self . num_words ( ) {
471+ let mut word = self . word ( word_index ) ;
385472 for _ in 0 ..WORD_BYTES {
386473 // for each byte in `word`:
387474 let remain = self . domain_size - i;
@@ -1306,8 +1393,10 @@ impl<T: Idx> GrowableBitSet<T> {
13061393 }
13071394
13081395 let min_num_words = num_words ( min_domain_size) ;
1309- if self . bit_set . words . len ( ) < min_num_words {
1310- self . bit_set . words . resize ( min_num_words, 0 )
1396+ if let Some ( words) = & mut self . bit_set . words {
1397+ if words. len ( ) < min_num_words {
1398+ words. resize ( min_num_words, 0 )
1399+ }
13111400 }
13121401 }
13131402
@@ -1357,7 +1446,7 @@ impl<T: Idx> GrowableBitSet<T> {
13571446 #[ inline]
13581447 pub fn contains ( & self , elem : T ) -> bool {
13591448 let ( word_index, mask) = word_index_and_mask ( elem) ;
1360- self . bit_set . words . get ( word_index) . is_some_and ( |word| ( word & mask) != 0 )
1449+ self . bit_set . words ( ) . get ( word_index) . is_some_and ( |word| ( word & mask) != 0 )
13611450 }
13621451
13631452 #[ inline]
@@ -1419,13 +1508,16 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
14191508 pub fn from_row_n ( row : & DenseBitSet < C > , num_rows : usize ) -> BitMatrix < R , C > {
14201509 let num_columns = row. domain_size ( ) ;
14211510 let words_per_row = num_words ( num_columns) ;
1422- assert_eq ! ( words_per_row, row. words. len( ) ) ;
1423- BitMatrix {
1424- num_rows,
1425- num_columns,
1426- words : iter:: repeat_n ( & row. words , num_rows) . flatten ( ) . cloned ( ) . collect ( ) ,
1427- marker : PhantomData ,
1511+ let mut words = vec ! [ 0 ; num_rows * words_per_row] ;
1512+ if let Some ( row_words) = & row. words {
1513+ assert_eq ! ( words_per_row, row_words. len( ) ) ;
1514+ if words_per_row > 0 {
1515+ for matrix_row in words. chunks_exact_mut ( words_per_row) {
1516+ matrix_row. copy_from_slice ( row_words) ;
1517+ }
1518+ }
14281519 }
1520+ BitMatrix { num_rows, num_columns, words, marker : PhantomData }
14291521 }
14301522
14311523 pub fn rows ( & self ) -> impl Iterator < Item = R > {
@@ -1517,8 +1609,11 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
15171609 pub fn union_row_with ( & mut self , with : & DenseBitSet < C > , write : R ) -> bool {
15181610 assert ! ( write. index( ) < self . num_rows) ;
15191611 assert_eq ! ( with. domain_size( ) , self . num_columns) ;
1612+ let Some ( with_words) = & with. words else {
1613+ return false ;
1614+ } ;
15201615 let ( write_start, write_end) = self . range ( write) ;
1521- update_words ( & mut self . words [ write_start..write_end] , & with . words , |a, b| a | b)
1616+ update_words ( & mut self . words [ write_start..write_end] , with_words , |a, b| a | b)
15221617 }
15231618
15241619 /// Sets every cell in `row` to true.
0 commit comments