@@ -318,48 +318,57 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
318
318
}
319
319
}
320
320
321
- /// A moderately sparse bit matrix: rows are appended lazily, but columns
322
- /// within appended rows are instantiated fully upon creation.
321
+ /// A moderately sparse bit matrix, in which rows are instantiated lazily.
322
+ ///
323
+ /// Initially, every row has no explicit representation. If any bit within a
324
+ /// row is set, the entire row is instantiated as
325
+ /// `Some(<full-column-width-BitArray>)`. Furthermore, any previously
326
+ /// uninstantiated rows prior to it will be instantiated as `None`. Those prior
327
+ /// rows may themselves become fully instantiated later on if any of their bits
328
+ /// are set.
323
329
#[ derive( Clone , Debug ) ]
324
330
pub struct SparseBitMatrix < R , C >
325
331
where
326
332
R : Idx ,
327
333
C : Idx ,
328
334
{
329
- columns : usize ,
330
- vector : IndexVec < R , BitArray < C > > ,
335
+ num_columns : usize ,
336
+ rows : IndexVec < R , Option < BitArray < C > > > ,
331
337
}
332
338
333
339
impl < R : Idx , C : Idx > SparseBitMatrix < R , C > {
334
340
/// Create a new empty sparse bit matrix with no rows or columns.
335
- pub fn new ( columns : usize ) -> Self {
341
+ pub fn new ( num_columns : usize ) -> Self {
336
342
Self {
337
- columns ,
338
- vector : IndexVec :: new ( ) ,
343
+ num_columns ,
344
+ rows : IndexVec :: new ( ) ,
339
345
}
340
346
}
341
347
342
- fn ensure_row ( & mut self , row : R ) {
343
- let columns = self . columns ;
344
- self . vector
345
- . ensure_contains_elem ( row, || BitArray :: new ( columns) ) ;
348
+ fn ensure_row ( & mut self , row : R ) -> & mut BitArray < C > {
349
+ // Instantiate any missing rows up to and including row `row` with an
350
+ // empty BitArray.
351
+ self . rows . ensure_contains_elem ( row, || None ) ;
352
+
353
+ // Then replace row `row` with a full BitArray if necessary.
354
+ let num_columns = self . num_columns ;
355
+ self . rows [ row] . get_or_insert_with ( || BitArray :: new ( num_columns) )
346
356
}
347
357
348
358
/// Sets the cell at `(row, column)` to true. Put another way, insert
349
359
/// `column` to the bitset for `row`.
350
360
///
351
361
/// Returns true if this changed the matrix, and false otherwise.
352
362
pub fn add ( & mut self , row : R , column : C ) -> bool {
353
- self . ensure_row ( row) ;
354
- self . vector [ row] . insert ( column)
363
+ self . ensure_row ( row) . insert ( column)
355
364
}
356
365
357
366
/// Do the bits from `row` contain `column`? Put another way, is
358
367
/// the matrix cell at `(row, column)` true? Put yet another way,
359
368
/// if the matrix represents (transitive) reachability, can
360
369
/// `row` reach `column`?
361
370
pub fn contains ( & self , row : R , column : C ) -> bool {
362
- self . vector . get ( row) . map_or ( false , |r| r. contains ( column) )
371
+ self . row ( row) . map_or ( false , |r| r. contains ( column) )
363
372
}
364
373
365
374
/// Add the bits from row `read` to the bits from row `write`,
@@ -370,49 +379,44 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
370
379
/// `write` can reach everything that `read` can (and
371
380
/// potentially more).
372
381
pub fn merge ( & mut self , read : R , write : R ) -> bool {
373
- if read == write || self . vector . get ( read) . is_none ( ) {
382
+ if read == write || self . row ( read) . is_none ( ) {
374
383
return false ;
375
384
}
376
385
377
386
self . ensure_row ( write) ;
378
- let ( bitvec_read, bitvec_write) = self . vector . pick2_mut ( read, write) ;
379
- bitvec_write. merge ( bitvec_read)
387
+ if let ( Some ( bitvec_read) , Some ( bitvec_write) ) = self . rows . pick2_mut ( read, write) {
388
+ bitvec_write. merge ( bitvec_read)
389
+ } else {
390
+ unreachable ! ( )
391
+ }
380
392
}
381
393
382
394
/// Merge a row, `from`, into the `into` row.
383
395
pub fn merge_into ( & mut self , into : R , from : & BitArray < C > ) -> bool {
384
- self . ensure_row ( into) ;
385
- self . vector [ into] . merge ( from)
396
+ self . ensure_row ( into) . merge ( from)
386
397
}
387
398
388
399
/// Add all bits to the given row.
389
400
pub fn add_all ( & mut self , row : R ) {
390
- self . ensure_row ( row) ;
391
- self . vector [ row] . insert_all ( ) ;
392
- }
393
-
394
- /// Number of elements in the matrix.
395
- pub fn len ( & self ) -> usize {
396
- self . vector . len ( )
401
+ self . ensure_row ( row) . insert_all ( ) ;
397
402
}
398
403
399
404
pub fn rows ( & self ) -> impl Iterator < Item = R > {
400
- self . vector . indices ( )
405
+ self . rows . indices ( )
401
406
}
402
407
403
408
/// Iterates through all the columns set to true in a given row of
404
409
/// the matrix.
405
410
pub fn iter < ' a > ( & ' a self , row : R ) -> impl Iterator < Item = C > + ' a {
406
- self . vector . get ( row) . into_iter ( ) . flat_map ( |r| r. iter ( ) )
407
- }
408
-
409
- /// Iterates through each row and the accompanying bit set.
410
- pub fn iter_enumerated < ' a > ( & ' a self ) -> impl Iterator < Item = ( R , & ' a BitArray < C > ) > + ' a {
411
- self . vector . iter_enumerated ( )
411
+ self . row ( row) . into_iter ( ) . flat_map ( |r| r. iter ( ) )
412
412
}
413
413
414
414
pub fn row ( & self , row : R ) -> Option < & BitArray < C > > {
415
- self . vector . get ( row)
415
+ if let Some ( Some ( row) ) = self . rows . get ( row) {
416
+ Some ( row)
417
+ } else {
418
+ None
419
+ }
416
420
}
417
421
}
418
422
0 commit comments