99// except according to those terms.
1010
1111use indexed_vec:: { Idx , IndexVec } ;
12- use std:: collections:: btree_map:: Entry ;
13- use std:: collections:: BTreeMap ;
1412use std:: iter:: FromIterator ;
1513use std:: marker:: PhantomData ;
1614
@@ -72,7 +70,7 @@ impl BitVector {
7270 }
7371
7472 #[ inline]
75- pub fn insert_all ( & mut self , all : & BitVector ) -> bool {
73+ pub fn merge ( & mut self , all : & BitVector ) -> bool {
7674 assert ! ( self . data. len( ) == all. data. len( ) ) ;
7775 let mut changed = false ;
7876 for ( i, j) in self . data . iter_mut ( ) . zip ( & all. data ) {
@@ -271,20 +269,26 @@ impl BitMatrix {
271269 }
272270}
273271
272+ /// A moderately sparse bit matrix: rows are appended lazily, but columns
273+ /// within appended rows are instantiated fully upon creation.
274274#[ derive( Clone , Debug ) ]
275275pub struct SparseBitMatrix < R , C >
276276where
277277 R : Idx ,
278278 C : Idx ,
279279{
280- vector : IndexVec < R , SparseBitSet < C > > ,
280+ columns : usize ,
281+ vector : IndexVec < R , BitVector > ,
282+ marker : PhantomData < C > ,
281283}
282284
283285impl < R : Idx , C : Idx > SparseBitMatrix < R , C > {
284286 /// Create a new empty sparse bit matrix with no rows or columns.
285- pub fn new ( ) -> Self {
287+ pub fn new ( columns : usize ) -> Self {
286288 Self {
289+ columns,
287290 vector : IndexVec :: new ( ) ,
291+ marker : PhantomData ,
288292 }
289293 }
290294
@@ -293,23 +297,18 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
293297 ///
294298 /// Returns true if this changed the matrix, and false otherwise.
295299 pub fn add ( & mut self , row : R , column : C ) -> bool {
296- debug ! (
297- "add(row={:?}, column={:?}, current_len={})" ,
298- row,
299- column,
300- self . vector. len( )
301- ) ;
300+ let columns = self . columns ;
302301 self . vector
303- . ensure_contains_elem ( row, || SparseBitSet :: new ( ) ) ;
304- self . vector [ row] . insert ( column)
302+ . ensure_contains_elem ( row, || BitVector :: new ( columns ) ) ;
303+ self . vector [ row] . insert ( column. index ( ) )
305304 }
306305
307306 /// Do the bits from `row` contain `column`? Put another way, is
308307 /// the matrix cell at `(row, column)` true? Put yet another way,
309308 /// if the matrix represents (transitive) reachability, can
310309 /// `row` reach `column`?
311310 pub fn contains ( & self , row : R , column : C ) -> bool {
312- self . vector . get ( row) . map_or ( false , |r| r. contains ( column) )
311+ self . vector . get ( row) . map_or ( false , |r| r. contains ( column. index ( ) ) )
313312 }
314313
315314 /// Add the bits from row `read` to the bits from row `write`,
@@ -320,39 +319,23 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
320319 /// `write` can reach everything that `read` can (and
321320 /// potentially more).
322321 pub fn merge ( & mut self , read : R , write : R ) -> bool {
323- let mut changed = false ;
324-
325- if read != write {
326- if self . vector . get ( read) . is_some ( ) {
327- self . vector
328- . ensure_contains_elem ( write, || SparseBitSet :: new ( ) ) ;
329- let ( bit_set_read, bit_set_write) = self . vector . pick2_mut ( read, write) ;
330-
331- for read_chunk in bit_set_read. chunks ( ) {
332- changed = changed | bit_set_write. insert_chunk ( read_chunk) . any ( ) ;
333- }
334- }
322+ if read == write || self . vector . get ( read) . is_none ( ) {
323+ return false ;
335324 }
336325
337- changed
326+ let columns = self . columns ;
327+ self . vector
328+ . ensure_contains_elem ( write, || BitVector :: new ( columns) ) ;
329+ let ( bitvec_read, bitvec_write) = self . vector . pick2_mut ( read, write) ;
330+ bitvec_write. merge ( bitvec_read)
338331 }
339332
340333 /// Merge a row, `from`, into the `into` row.
341- pub fn merge_into ( & mut self , into : R , from : & SparseBitSet < C > ) -> bool {
334+ pub fn merge_into ( & mut self , into : R , from : & BitVector ) -> bool {
335+ let columns = self . columns ;
342336 self . vector
343- . ensure_contains_elem ( into, || SparseBitSet :: new ( ) ) ;
344- self . vector [ into] . insert_from ( from)
345- }
346-
347- /// True if `sub` is a subset of `sup`
348- pub fn is_subset ( & self , sub : R , sup : R ) -> bool {
349- sub == sup || {
350- let bit_set_sub = & self . vector [ sub] ;
351- let bit_set_sup = & self . vector [ sup] ;
352- bit_set_sub
353- . chunks ( )
354- . all ( |read_chunk| read_chunk. bits_eq ( bit_set_sup. contains_chunk ( read_chunk) ) )
355- }
337+ . ensure_contains_elem ( into, || BitVector :: new ( columns) ) ;
338+ self . vector [ into] . merge ( from)
356339 }
357340
358341 /// Number of elements in the matrix.
@@ -363,178 +346,15 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
363346 /// Iterates through all the columns set to true in a given row of
364347 /// the matrix.
365348 pub fn iter < ' a > ( & ' a self , row : R ) -> impl Iterator < Item = C > + ' a {
366- self . vector . get ( row) . into_iter ( ) . flat_map ( |r| r. iter ( ) )
349+ self . vector . get ( row) . into_iter ( ) . flat_map ( |r| r. iter ( ) . map ( |n| C :: new ( n ) ) )
367350 }
368351
369352 /// Iterates through each row and the accompanying bit set.
370- pub fn iter_enumerated < ' a > ( & ' a self ) -> impl Iterator < Item = ( R , & ' a SparseBitSet < C > ) > + ' a {
353+ pub fn iter_enumerated < ' a > ( & ' a self ) -> impl Iterator < Item = ( R , & ' a BitVector ) > + ' a {
371354 self . vector . iter_enumerated ( )
372355 }
373356}
374357
375- #[ derive( Clone , Debug ) ]
376- pub struct SparseBitSet < I : Idx > {
377- chunk_bits : BTreeMap < u32 , Word > ,
378- _marker : PhantomData < I > ,
379- }
380-
381- #[ derive( Copy , Clone ) ]
382- pub struct SparseChunk < I > {
383- key : u32 ,
384- bits : Word ,
385- _marker : PhantomData < I > ,
386- }
387-
388- impl < I : Idx > SparseChunk < I > {
389- #[ inline]
390- pub fn one ( index : I ) -> Self {
391- let index = index. index ( ) ;
392- let key_usize = index / 128 ;
393- let key = key_usize as u32 ;
394- assert_eq ! ( key as usize , key_usize) ;
395- SparseChunk {
396- key,
397- bits : 1 << ( index % 128 ) ,
398- _marker : PhantomData ,
399- }
400- }
401-
402- #[ inline]
403- pub fn any ( & self ) -> bool {
404- self . bits != 0
405- }
406-
407- #[ inline]
408- pub fn bits_eq ( & self , other : SparseChunk < I > ) -> bool {
409- self . bits == other. bits
410- }
411-
412- pub fn iter ( & self ) -> impl Iterator < Item = I > {
413- let base = self . key as usize * 128 ;
414- let mut bits = self . bits ;
415- ( 0 ..128 )
416- . map ( move |i| {
417- let current_bits = bits;
418- bits >>= 1 ;
419- ( i, current_bits)
420- } )
421- . take_while ( |& ( _, bits) | bits != 0 )
422- . filter_map ( move |( i, bits) | {
423- if ( bits & 1 ) != 0 {
424- Some ( I :: new ( base + i) )
425- } else {
426- None
427- }
428- } )
429- }
430- }
431-
432- impl < I : Idx > SparseBitSet < I > {
433- pub fn new ( ) -> Self {
434- SparseBitSet {
435- chunk_bits : BTreeMap :: new ( ) ,
436- _marker : PhantomData ,
437- }
438- }
439-
440- pub fn capacity ( & self ) -> usize {
441- self . chunk_bits . len ( ) * 128
442- }
443-
444- /// Returns a chunk containing only those bits that are already
445- /// present. You can test therefore if `self` contains all the
446- /// bits in chunk already by doing `chunk ==
447- /// self.contains_chunk(chunk)`.
448- pub fn contains_chunk ( & self , chunk : SparseChunk < I > ) -> SparseChunk < I > {
449- SparseChunk {
450- bits : self . chunk_bits
451- . get ( & chunk. key )
452- . map_or ( 0 , |bits| bits & chunk. bits ) ,
453- ..chunk
454- }
455- }
456-
457- /// Modifies `self` to contain all the bits from `chunk` (in
458- /// addition to any pre-existing bits); returns a new chunk that
459- /// contains only those bits that were newly added. You can test
460- /// if anything was inserted by invoking `any()` on the returned
461- /// value.
462- pub fn insert_chunk ( & mut self , chunk : SparseChunk < I > ) -> SparseChunk < I > {
463- if chunk. bits == 0 {
464- return chunk;
465- }
466- let bits = self . chunk_bits . entry ( chunk. key ) . or_insert ( 0 ) ;
467- let old_bits = * bits;
468- let new_bits = old_bits | chunk. bits ;
469- * bits = new_bits;
470- let changed = new_bits ^ old_bits;
471- SparseChunk {
472- bits : changed,
473- ..chunk
474- }
475- }
476-
477- /// Insert into bit set from another bit set.
478- pub fn insert_from ( & mut self , from : & SparseBitSet < I > ) -> bool {
479- let mut changed = false ;
480- for read_chunk in from. chunks ( ) {
481- changed = changed | self . insert_chunk ( read_chunk) . any ( ) ;
482- }
483- changed
484- }
485-
486- pub fn remove_chunk ( & mut self , chunk : SparseChunk < I > ) -> SparseChunk < I > {
487- if chunk. bits == 0 {
488- return chunk;
489- }
490- let changed = match self . chunk_bits . entry ( chunk. key ) {
491- Entry :: Occupied ( mut bits) => {
492- let old_bits = * bits. get ( ) ;
493- let new_bits = old_bits & !chunk. bits ;
494- if new_bits == 0 {
495- bits. remove ( ) ;
496- } else {
497- bits. insert ( new_bits) ;
498- }
499- new_bits ^ old_bits
500- }
501- Entry :: Vacant ( _) => 0 ,
502- } ;
503- SparseChunk {
504- bits : changed,
505- ..chunk
506- }
507- }
508-
509- pub fn clear ( & mut self ) {
510- self . chunk_bits . clear ( ) ;
511- }
512-
513- pub fn chunks < ' a > ( & ' a self ) -> impl Iterator < Item = SparseChunk < I > > + ' a {
514- self . chunk_bits . iter ( ) . map ( |( & key, & bits) | SparseChunk {
515- key,
516- bits,
517- _marker : PhantomData ,
518- } )
519- }
520-
521- pub fn contains ( & self , index : I ) -> bool {
522- self . contains_chunk ( SparseChunk :: one ( index) ) . any ( )
523- }
524-
525- pub fn insert ( & mut self , index : I ) -> bool {
526- self . insert_chunk ( SparseChunk :: one ( index) ) . any ( )
527- }
528-
529- pub fn remove ( & mut self , index : I ) -> bool {
530- self . remove_chunk ( SparseChunk :: one ( index) ) . any ( )
531- }
532-
533- pub fn iter < ' a > ( & ' a self ) -> impl Iterator < Item = I > + ' a {
534- self . chunks ( ) . flat_map ( |chunk| chunk. iter ( ) )
535- }
536- }
537-
538358#[ inline]
539359fn words ( elements : usize ) -> usize {
540360 ( elements + WORD_BITS - 1 ) / WORD_BITS
@@ -584,8 +404,8 @@ fn union_two_vecs() {
584404 assert ! ( !vec1. insert( 3 ) ) ;
585405 assert ! ( vec2. insert( 5 ) ) ;
586406 assert ! ( vec2. insert( 64 ) ) ;
587- assert ! ( vec1. insert_all ( & vec2) ) ;
588- assert ! ( !vec1. insert_all ( & vec2) ) ;
407+ assert ! ( vec1. merge ( & vec2) ) ;
408+ assert ! ( !vec1. merge ( & vec2) ) ;
589409 assert ! ( vec1. contains( 3 ) ) ;
590410 assert ! ( !vec1. contains( 4 ) ) ;
591411 assert ! ( vec1. contains( 5 ) ) ;
0 commit comments