@@ -337,6 +337,10 @@ impl<T: Idx> SparseBitSet<T> {
337
337
self . 0 . len ( )
338
338
}
339
339
340
+ fn is_empty ( & self ) -> bool {
341
+ self . 0 . len ( ) == 0
342
+ }
343
+
340
344
fn contains ( & self , elem : T ) -> bool {
341
345
self . 0 . contains ( & elem)
342
346
}
@@ -417,15 +421,28 @@ pub enum HybridBitSet<T: Idx> {
417
421
}
418
422
419
423
impl < T : Idx > HybridBitSet < T > {
424
+ // FIXME: This function is used in conjunction with `mem::replace()` in
425
+ // several pieces of awful code below. I can't work out how else to appease
426
+ // the borrow checker.
427
+ fn dummy ( ) -> Self {
428
+ // The cheapest HybridBitSet to construct, which is only used to get
429
+ // around the borrow checker.
430
+ HybridBitSet :: Sparse ( SparseBitSet :: new_empty ( ) , 0 )
431
+ }
432
+
420
433
pub fn new_empty ( domain_size : usize ) -> Self {
421
434
HybridBitSet :: Sparse ( SparseBitSet :: new_empty ( ) , domain_size)
422
435
}
423
436
424
- pub fn clear ( & mut self ) {
425
- let domain_size = match * self {
437
+ pub fn domain_size ( & self ) -> usize {
438
+ match * self {
426
439
HybridBitSet :: Sparse ( _, size) => size,
427
440
HybridBitSet :: Dense ( _, size) => size,
428
- } ;
441
+ }
442
+ }
443
+
444
+ pub fn clear ( & mut self ) {
445
+ let domain_size = self . domain_size ( ) ;
429
446
* self = HybridBitSet :: new_empty ( domain_size) ;
430
447
}
431
448
@@ -436,6 +453,22 @@ impl<T: Idx> HybridBitSet<T> {
436
453
}
437
454
}
438
455
456
+ pub fn superset ( & self , other : & HybridBitSet < T > ) -> bool {
457
+ match ( self , other) {
458
+ ( HybridBitSet :: Dense ( self_dense, _) , HybridBitSet :: Dense ( other_dense, _) ) => {
459
+ self_dense. superset ( other_dense)
460
+ }
461
+ _ => other. iter ( ) . all ( |elem| self . contains ( elem) ) ,
462
+ }
463
+ }
464
+
465
+ pub fn is_empty ( & self ) -> bool {
466
+ match self {
467
+ HybridBitSet :: Sparse ( sparse, _) => sparse. is_empty ( ) ,
468
+ HybridBitSet :: Dense ( dense, _) => dense. is_empty ( ) ,
469
+ }
470
+ }
471
+
439
472
pub fn insert ( & mut self , elem : T ) -> bool {
440
473
match self {
441
474
HybridBitSet :: Sparse ( sparse, _) if sparse. len ( ) < SPARSE_MAX => {
@@ -449,26 +482,33 @@ impl<T: Idx> HybridBitSet<T> {
449
482
}
450
483
HybridBitSet :: Sparse ( _, _) => {
451
484
// The set is sparse and full. Convert to a dense set.
452
- //
453
- // FIXME: This code is awful, but I can't work out how else to
454
- // appease the borrow checker.
455
- let dummy = HybridBitSet :: Sparse ( SparseBitSet :: new_empty ( ) , 0 ) ;
456
- match mem:: replace ( self , dummy) {
485
+ match mem:: replace ( self , HybridBitSet :: dummy ( ) ) {
457
486
HybridBitSet :: Sparse ( sparse, domain_size) => {
458
487
let mut dense = sparse. to_dense ( domain_size) ;
459
488
let changed = dense. insert ( elem) ;
460
489
assert ! ( changed) ;
461
- mem :: replace ( self , HybridBitSet :: Dense ( dense, domain_size) ) ;
490
+ * self = HybridBitSet :: Dense ( dense, domain_size) ;
462
491
changed
463
492
}
464
- _ => panic ! ( "impossible" ) ,
493
+ _ => unreachable ! ( )
465
494
}
466
495
}
467
496
468
497
HybridBitSet :: Dense ( dense, _) => dense. insert ( elem) ,
469
498
}
470
499
}
471
500
501
+ pub fn insert_all ( & mut self ) {
502
+ let domain_size = self . domain_size ( ) ;
503
+ match self {
504
+ HybridBitSet :: Sparse ( _, _) => {
505
+ let dense = BitSet :: new_filled ( domain_size) ;
506
+ * self = HybridBitSet :: Dense ( dense, domain_size) ;
507
+ }
508
+ HybridBitSet :: Dense ( dense, _) => dense. insert_all ( ) ,
509
+ }
510
+ }
511
+
472
512
pub fn remove ( & mut self , elem : T ) -> bool {
473
513
// Note: we currently don't bother going from Dense back to Sparse.
474
514
match self {
@@ -477,6 +517,42 @@ impl<T: Idx> HybridBitSet<T> {
477
517
}
478
518
}
479
519
520
+ pub fn union ( & mut self , other : & HybridBitSet < T > ) -> bool {
521
+ match self {
522
+ HybridBitSet :: Sparse ( _, _) => {
523
+ match other {
524
+ HybridBitSet :: Sparse ( other_sparse, _) => {
525
+ // Both sets are sparse. Add the elements in
526
+ // `other_sparse` to `self_hybrid` one at a time. This
527
+ // may or may not cause `self_hybrid` to be densified.
528
+ let mut self_hybrid = mem:: replace ( self , HybridBitSet :: dummy ( ) ) ;
529
+ let mut changed = false ;
530
+ for elem in other_sparse. iter ( ) {
531
+ changed |= self_hybrid. insert ( * elem) ;
532
+ }
533
+ * self = self_hybrid;
534
+ changed
535
+ }
536
+ HybridBitSet :: Dense ( other_dense, _) => {
537
+ // `self` is sparse and `other` is dense. Densify
538
+ // `self` and then do the bitwise union.
539
+ match mem:: replace ( self , HybridBitSet :: dummy ( ) ) {
540
+ HybridBitSet :: Sparse ( self_sparse, self_domain_size) => {
541
+ let mut new_dense = self_sparse. to_dense ( self_domain_size) ;
542
+ let changed = new_dense. union ( other_dense) ;
543
+ * self = HybridBitSet :: Dense ( new_dense, self_domain_size) ;
544
+ changed
545
+ }
546
+ _ => unreachable ! ( )
547
+ }
548
+ }
549
+ }
550
+ }
551
+
552
+ HybridBitSet :: Dense ( self_dense, _) => self_dense. union ( other) ,
553
+ }
554
+ }
555
+
480
556
/// Converts to a dense set, consuming itself in the process.
481
557
pub fn to_dense ( self ) -> BitSet < T > {
482
558
match self {
@@ -687,11 +763,10 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
687
763
/// sparse representation.
688
764
///
689
765
/// Initially, every row has no explicit representation. If any bit within a
690
- /// row is set, the entire row is instantiated as
691
- /// `Some(<full-column-width-BitSet>)`. Furthermore, any previously
692
- /// uninstantiated rows prior to it will be instantiated as `None`. Those prior
693
- /// rows may themselves become fully instantiated later on if any of their bits
694
- /// are set.
766
+ /// row is set, the entire row is instantiated as `Some(<HybridBitSet>)`.
767
+ /// Furthermore, any previously uninstantiated rows prior to it will be
768
+ /// instantiated as `None`. Those prior rows may themselves become fully
769
+ /// instantiated later on if any of their bits are set.
695
770
///
696
771
/// `R` and `C` are index types used to identify rows and columns respectively;
697
772
/// typically newtyped `usize` wrappers, but they can also just be `usize`.
@@ -702,7 +777,7 @@ where
702
777
C : Idx ,
703
778
{
704
779
num_columns : usize ,
705
- rows : IndexVec < R , Option < BitSet < C > > > ,
780
+ rows : IndexVec < R , Option < HybridBitSet < C > > > ,
706
781
}
707
782
708
783
impl < R : Idx , C : Idx > SparseBitMatrix < R , C > {
@@ -714,14 +789,14 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
714
789
}
715
790
}
716
791
717
- fn ensure_row ( & mut self , row : R ) -> & mut BitSet < C > {
792
+ fn ensure_row ( & mut self , row : R ) -> & mut HybridBitSet < C > {
718
793
// Instantiate any missing rows up to and including row `row` with an
719
- // empty BitSet .
794
+ // empty HybridBitSet .
720
795
self . rows . ensure_contains_elem ( row, || None ) ;
721
796
722
- // Then replace row `row` with a full BitSet if necessary.
797
+ // Then replace row `row` with a full HybridBitSet if necessary.
723
798
let num_columns = self . num_columns ;
724
- self . rows [ row] . get_or_insert_with ( || BitSet :: new_empty ( num_columns) )
799
+ self . rows [ row] . get_or_insert_with ( || HybridBitSet :: new_empty ( num_columns) )
725
800
}
726
801
727
802
/// Sets the cell at `(row, column)` to true. Put another way, insert
@@ -760,8 +835,8 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
760
835
}
761
836
}
762
837
763
- /// Merge a row, `from`, into the `into` row.
764
- pub fn union_into_row ( & mut self , into : R , from : & BitSet < C > ) -> bool {
838
+ /// Union a row, `from`, into the `into` row.
839
+ pub fn union_into_row ( & mut self , into : R , from : & HybridBitSet < C > ) -> bool {
765
840
self . ensure_row ( into) . union ( from)
766
841
}
767
842
@@ -780,7 +855,7 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
780
855
self . row ( row) . into_iter ( ) . flat_map ( |r| r. iter ( ) )
781
856
}
782
857
783
- pub fn row ( & self , row : R ) -> Option < & BitSet < C > > {
858
+ pub fn row ( & self , row : R ) -> Option < & HybridBitSet < C > > {
784
859
if let Some ( Some ( row) ) = self . rows . get ( row) {
785
860
Some ( row)
786
861
} else {
@@ -871,7 +946,7 @@ fn bitset_iter_works_2() {
871
946
}
872
947
873
948
#[ test]
874
- fn union_two_vecs ( ) {
949
+ fn union_two_sets ( ) {
875
950
let mut set1: BitSet < usize > = BitSet :: new_empty ( 65 ) ;
876
951
let mut set2: BitSet < usize > = BitSet :: new_empty ( 65 ) ;
877
952
assert ! ( set1. insert( 3 ) ) ;
@@ -887,6 +962,74 @@ fn union_two_vecs() {
887
962
assert ! ( set1. contains( 64 ) ) ;
888
963
}
889
964
965
+ #[ test]
966
+ fn hybrid_bitset ( ) {
967
+ let mut sparse038: HybridBitSet < usize > = HybridBitSet :: new_empty ( 256 ) ;
968
+ assert ! ( sparse038. is_empty( ) ) ;
969
+ assert ! ( sparse038. insert( 0 ) ) ;
970
+ assert ! ( sparse038. insert( 1 ) ) ;
971
+ assert ! ( sparse038. insert( 8 ) ) ;
972
+ assert ! ( sparse038. insert( 3 ) ) ;
973
+ assert ! ( !sparse038. insert( 3 ) ) ;
974
+ assert ! ( sparse038. remove( 1 ) ) ;
975
+ assert ! ( !sparse038. is_empty( ) ) ;
976
+ assert_eq ! ( sparse038. iter( ) . collect:: <Vec <_>>( ) , [ 0 , 3 , 8 ] ) ;
977
+
978
+ for i in 0 ..256 {
979
+ if i == 0 || i == 3 || i == 8 {
980
+ assert ! ( sparse038. contains( i) ) ;
981
+ } else {
982
+ assert ! ( !sparse038. contains( i) ) ;
983
+ }
984
+ }
985
+
986
+ let mut sparse01358 = sparse038. clone ( ) ;
987
+ assert ! ( sparse01358. insert( 1 ) ) ;
988
+ assert ! ( sparse01358. insert( 5 ) ) ;
989
+ assert_eq ! ( sparse01358. iter( ) . collect:: <Vec <_>>( ) , [ 0 , 1 , 3 , 5 , 8 ] ) ;
990
+
991
+ let mut dense10 = HybridBitSet :: new_empty ( 256 ) ;
992
+ for i in 0 ..10 {
993
+ assert ! ( dense10. insert( i) ) ;
994
+ }
995
+ assert ! ( !dense10. is_empty( ) ) ;
996
+ assert_eq ! ( dense10. iter( ) . collect:: <Vec <_>>( ) , [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] ) ;
997
+
998
+ let mut dense256 = HybridBitSet :: new_empty ( 256 ) ;
999
+ assert ! ( dense256. is_empty( ) ) ;
1000
+ dense256. insert_all ( ) ;
1001
+ assert ! ( !dense256. is_empty( ) ) ;
1002
+ for i in 0 ..256 {
1003
+ assert ! ( dense256. contains( i) ) ;
1004
+ }
1005
+
1006
+ assert ! ( sparse038. superset( & sparse038) ) ; // sparse + sparse (self)
1007
+ assert ! ( sparse01358. superset( & sparse038) ) ; // sparse + sparse
1008
+ assert ! ( dense10. superset( & sparse038) ) ; // dense + sparse
1009
+ assert ! ( dense10. superset( & dense10) ) ; // dense + dense (self)
1010
+ assert ! ( dense256. superset( & dense10) ) ; // dense + dense
1011
+
1012
+ let mut hybrid = sparse038;
1013
+ assert ! ( !sparse01358. union ( & hybrid) ) ; // no change
1014
+ assert ! ( hybrid. union ( & sparse01358) ) ;
1015
+ assert ! ( hybrid. superset( & sparse01358) && sparse01358. superset( & hybrid) ) ;
1016
+ assert ! ( !dense10. union ( & sparse01358) ) ;
1017
+ assert ! ( !dense256. union ( & dense10) ) ;
1018
+ let mut dense = dense10;
1019
+ assert ! ( dense. union ( & dense256) ) ;
1020
+ assert ! ( dense. superset( & dense256) && dense256. superset( & dense) ) ;
1021
+ assert ! ( hybrid. union ( & dense256) ) ;
1022
+ assert ! ( hybrid. superset( & dense256) && dense256. superset( & hybrid) ) ;
1023
+
1024
+ assert_eq ! ( dense256. iter( ) . count( ) , 256 ) ;
1025
+ let mut dense0 = dense256;
1026
+ for i in 0 ..256 {
1027
+ assert ! ( dense0. remove( i) ) ;
1028
+ }
1029
+ assert ! ( !dense0. remove( 0 ) ) ;
1030
+ assert ! ( dense0. is_empty( ) ) ;
1031
+ }
1032
+
890
1033
#[ test]
891
1034
fn grow ( ) {
892
1035
let mut set: GrowableBitSet < usize > = GrowableBitSet :: with_capacity ( 65 ) ;
0 commit comments