@@ -281,10 +281,10 @@ where
281281}
282282
283283impl < R : Idx , C : Idx > SparseBitMatrix < R , C > {
284- /// Create a new `rows x columns` matrix, initially empty .
285- pub fn new ( rows : R , _columns : C ) -> SparseBitMatrix < R , C > {
286- SparseBitMatrix {
287- vector : IndexVec :: from_elem_n ( SparseBitSet :: new ( ) , rows . index ( ) ) ,
284+ /// Create a new empty sparse bit matrix with no rows or columns .
285+ pub fn new ( ) -> Self {
286+ Self {
287+ vector : IndexVec :: new ( ) ,
288288 }
289289 }
290290
@@ -293,6 +293,14 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
293293 ///
294294 /// Returns true if this changed the matrix, and false otherwise.
295295 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+ ) ;
302+ self . vector
303+ . ensure_contains_elem ( row, || SparseBitSet :: new ( ) ) ;
296304 self . vector [ row] . insert ( column)
297305 }
298306
@@ -301,7 +309,7 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
301309 /// if the matrix represents (transitive) reachability, can
302310 /// `row` reach `column`?
303311 pub fn contains ( & self , row : R , column : C ) -> bool {
304- self . vector [ row] . contains ( column)
312+ self . vector . get ( row) . map_or ( false , |r| r . contains ( column) )
305313 }
306314
307315 /// Add the bits from row `read` to the bits from row `write`,
@@ -315,16 +323,27 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
315323 let mut changed = false ;
316324
317325 if read != write {
318- let ( bit_set_read, bit_set_write) = self . vector . pick2_mut ( 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) ;
319330
320- for read_chunk in bit_set_read. chunks ( ) {
321- changed = changed | bit_set_write. insert_chunk ( read_chunk) . any ( ) ;
331+ for read_chunk in bit_set_read. chunks ( ) {
332+ changed = changed | bit_set_write. insert_chunk ( read_chunk) . any ( ) ;
333+ }
322334 }
323335 }
324336
325337 changed
326338 }
327339
340+ /// Merge a row, `from`, into the `into` row.
341+ pub fn merge_into ( & mut self , into : R , from : & SparseBitSet < C > ) -> bool {
342+ self . vector
343+ . ensure_contains_elem ( into, || SparseBitSet :: new ( ) ) ;
344+ self . vector [ into] . insert_from ( from)
345+ }
346+
328347 /// True if `sub` is a subset of `sup`
329348 pub fn is_subset ( & self , sub : R , sup : R ) -> bool {
330349 sub == sup || {
@@ -336,10 +355,20 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
336355 }
337356 }
338357
358+ /// Number of elements in the matrix.
359+ pub fn len ( & self ) -> usize {
360+ self . vector . len ( )
361+ }
362+
339363 /// Iterates through all the columns set to true in a given row of
340364 /// the matrix.
341365 pub fn iter < ' a > ( & ' a self , row : R ) -> impl Iterator < Item = C > + ' a {
342- self . vector [ row] . iter ( )
366+ self . vector . get ( row) . into_iter ( ) . flat_map ( |r| r. iter ( ) )
367+ }
368+
369+ /// 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 {
371+ self . vector . iter_enumerated ( )
343372 }
344373}
345374
@@ -445,6 +474,15 @@ impl<I: Idx> SparseBitSet<I> {
445474 }
446475 }
447476
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+
448486 pub fn remove_chunk ( & mut self , chunk : SparseChunk < I > ) -> SparseChunk < I > {
449487 if chunk. bits == 0 {
450488 return chunk;
0 commit comments