@@ -318,16 +318,22 @@ 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
335
num_columns : usize ,
330
- rows : IndexVec < R , BitArray < C > > ,
336
+ rows : IndexVec < R , Option < BitArray < C > > > ,
331
337
}
332
338
333
339
impl < R : Idx , C : Idx > SparseBitMatrix < R , C > {
@@ -339,27 +345,30 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
339
345
}
340
346
}
341
347
342
- fn ensure_row ( & mut self , row : R ) {
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.
343
354
let num_columns = self . num_columns ;
344
- self . rows
345
- . ensure_contains_elem ( row, || BitArray :: new ( 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 . rows [ 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 . rows . 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,30 +379,26 @@ 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 . rows . 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 . rows . 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 . rows [ 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 . rows [ row] . insert_all ( ) ;
392
- }
393
-
394
- /// Number of elements in the matrix.
395
- pub fn len ( & self ) -> usize {
396
- self . rows . len ( )
401
+ self . ensure_row ( row) . insert_all ( ) ;
397
402
}
398
403
399
404
pub fn rows ( & self ) -> impl Iterator < Item = R > {
@@ -403,16 +408,15 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
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 . rows . 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 . rows . 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 . rows . 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