9
9
// except according to those terms.
10
10
11
11
use indexed_vec:: { Idx , IndexVec } ;
12
- use std:: collections:: btree_map:: Entry ;
13
- use std:: collections:: BTreeMap ;
14
12
use std:: iter:: FromIterator ;
15
13
use std:: marker:: PhantomData ;
16
14
@@ -72,7 +70,7 @@ impl BitVector {
72
70
}
73
71
74
72
#[ inline]
75
- pub fn insert_all ( & mut self , all : & BitVector ) -> bool {
73
+ pub fn merge ( & mut self , all : & BitVector ) -> bool {
76
74
assert ! ( self . data. len( ) == all. data. len( ) ) ;
77
75
let mut changed = false ;
78
76
for ( i, j) in self . data . iter_mut ( ) . zip ( & all. data ) {
@@ -271,20 +269,26 @@ impl BitMatrix {
271
269
}
272
270
}
273
271
272
+ /// A moderately sparse bit matrix: rows are appended lazily, but columns
273
+ /// within appended rows are instantiated fully upon creation.
274
274
#[ derive( Clone , Debug ) ]
275
275
pub struct SparseBitMatrix < R , C >
276
276
where
277
277
R : Idx ,
278
278
C : Idx ,
279
279
{
280
- vector : IndexVec < R , SparseBitSet < C > > ,
280
+ columns : usize ,
281
+ vector : IndexVec < R , BitVector > ,
282
+ marker : PhantomData < C > ,
281
283
}
282
284
283
285
impl < R : Idx , C : Idx > SparseBitMatrix < R , C > {
284
286
/// Create a new empty sparse bit matrix with no rows or columns.
285
- pub fn new ( ) -> Self {
287
+ pub fn new ( columns : usize ) -> Self {
286
288
Self {
289
+ columns,
287
290
vector : IndexVec :: new ( ) ,
291
+ marker : PhantomData ,
288
292
}
289
293
}
290
294
@@ -293,23 +297,18 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
293
297
///
294
298
/// Returns true if this changed the matrix, and false otherwise.
295
299
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 ;
302
301
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 ( ) )
305
304
}
306
305
307
306
/// Do the bits from `row` contain `column`? Put another way, is
308
307
/// the matrix cell at `(row, column)` true? Put yet another way,
309
308
/// if the matrix represents (transitive) reachability, can
310
309
/// `row` reach `column`?
311
310
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 ( ) ) )
313
312
}
314
313
315
314
/// Add the bits from row `read` to the bits from row `write`,
@@ -320,39 +319,23 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
320
319
/// `write` can reach everything that `read` can (and
321
320
/// potentially more).
322
321
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 ;
335
324
}
336
325
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)
338
331
}
339
332
340
333
/// 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 ;
342
336
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)
356
339
}
357
340
358
341
/// Number of elements in the matrix.
@@ -363,178 +346,15 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
363
346
/// Iterates through all the columns set to true in a given row of
364
347
/// the matrix.
365
348
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 ) ) )
367
350
}
368
351
369
352
/// 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 {
371
354
self . vector . iter_enumerated ( )
372
355
}
373
356
}
374
357
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
-
538
358
#[ inline]
539
359
fn words ( elements : usize ) -> usize {
540
360
( elements + WORD_BITS - 1 ) / WORD_BITS
@@ -584,8 +404,8 @@ fn union_two_vecs() {
584
404
assert ! ( !vec1. insert( 3 ) ) ;
585
405
assert ! ( vec2. insert( 5 ) ) ;
586
406
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) ) ;
589
409
assert ! ( vec1. contains( 3 ) ) ;
590
410
assert ! ( !vec1. contains( 4 ) ) ;
591
411
assert ! ( vec1. contains( 5 ) ) ;
0 commit comments