@@ -613,6 +613,18 @@ impl<T: Idx> ChunkedBitSet<T> {
613
613
}
614
614
}
615
615
616
+ fn chunk_iter ( & self , chunk_index : usize ) -> ChunkIter < ' _ > {
617
+ match self . chunks . get ( chunk_index) {
618
+ Some ( Zeros ( _chunk_domain_size) ) => ChunkIter :: Zeros ,
619
+ Some ( Ones ( chunk_domain_size) ) => ChunkIter :: Ones ( 0 ..* chunk_domain_size as usize ) ,
620
+ Some ( Mixed ( chunk_domain_size, _, ref words) ) => {
621
+ let num_words = num_words ( * chunk_domain_size as usize ) ;
622
+ ChunkIter :: Mixed ( BitIter :: new ( & words[ 0 ..num_words] ) )
623
+ }
624
+ None => ChunkIter :: Finished ,
625
+ }
626
+ }
627
+
616
628
bit_relations_inherent_impls ! { }
617
629
}
618
630
@@ -675,6 +687,7 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
675
687
changed
676
688
}
677
689
690
+ // njn: add test for this
678
691
fn subtract ( & mut self , other : & ChunkedBitSet < T > ) -> bool {
679
692
assert_eq ! ( self . domain_size, other. domain_size) ;
680
693
debug_assert_eq ! ( self . chunks. len( ) , other. chunks. len( ) ) ;
@@ -755,6 +768,7 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
755
768
changed
756
769
}
757
770
771
+ // njn: add test for this
758
772
fn intersect ( & mut self , other : & ChunkedBitSet < T > ) -> bool {
759
773
assert_eq ! ( self . domain_size, other. domain_size) ;
760
774
debug_assert_eq ! ( self . chunks. len( ) , other. chunks. len( ) ) ;
@@ -900,78 +914,44 @@ impl<T> Clone for ChunkedBitSet<T> {
900
914
}
901
915
902
916
pub struct ChunkedBitIter < ' a , T : Idx > {
903
- index : usize ,
904
917
bit_set : & ' a ChunkedBitSet < T > ,
918
+
919
+ // The index of the current chunk.
920
+ chunk_index : usize ,
921
+
922
+ // The sub-iterator for the current chunk.
923
+ chunk_iter : ChunkIter < ' a > ,
905
924
}
906
925
907
926
impl < ' a , T : Idx > ChunkedBitIter < ' a , T > {
908
927
#[ inline]
909
928
fn new ( bit_set : & ' a ChunkedBitSet < T > ) -> ChunkedBitIter < ' a , T > {
910
- ChunkedBitIter { index : 0 , bit_set }
929
+ ChunkedBitIter { bit_set , chunk_index : 0 , chunk_iter : bit_set. chunk_iter ( 0 ) }
911
930
}
912
931
}
913
932
914
933
impl < ' a , T : Idx > Iterator for ChunkedBitIter < ' a , T > {
915
934
type Item = T ;
916
- fn next ( & mut self ) -> Option < T > {
917
- while self . index < self . bit_set . domain_size ( ) {
918
- let elem = T :: new ( self . index ) ;
919
- let chunk = & self . bit_set . chunks [ chunk_index ( elem) ] ;
920
- match & chunk {
921
- Zeros ( chunk_domain_size) => {
922
- self . index += * chunk_domain_size as usize ;
923
- }
924
- Ones ( _chunk_domain_size) => {
925
- self . index += 1 ;
926
- return Some ( elem) ;
927
- }
928
- Mixed ( _chunk_domain_size, _, words) => loop {
929
- let elem = T :: new ( self . index ) ;
930
- self . index += 1 ;
931
- let ( word_index, mask) = chunk_word_index_and_mask ( elem) ;
932
- if ( words[ word_index] & mask) != 0 {
933
- return Some ( elem) ;
934
- }
935
- if self . index % CHUNK_BITS == 0 {
936
- break ;
937
- }
938
- } ,
939
- }
940
- }
941
- None
942
- }
943
935
944
- fn fold < B , F > ( mut self , mut init : B , mut f : F ) -> B
945
- where
946
- F : FnMut ( B , Self :: Item ) -> B ,
947
- {
948
- // If `next` has already been called, we may not be at the start of a chunk, so we first
949
- // advance the iterator to the start of the next chunk, before proceeding in chunk sized
950
- // steps.
951
- while self . index % CHUNK_BITS != 0 {
952
- let Some ( item) = self . next ( ) else { return init } ;
953
- init = f ( init, item) ;
954
- }
955
- let start_chunk = self . index / CHUNK_BITS ;
956
- let chunks = & self . bit_set . chunks [ start_chunk..] ;
957
- for ( i, chunk) in chunks. iter ( ) . enumerate ( ) {
958
- let base = ( start_chunk + i) * CHUNK_BITS ;
959
- match chunk {
960
- Zeros ( _) => ( ) ,
961
- Ones ( limit) => {
962
- for j in 0 ..( * limit as usize ) {
963
- init = f ( init, T :: new ( base + j) ) ;
936
+ fn next ( & mut self ) -> Option < T > {
937
+ loop {
938
+ match & mut self . chunk_iter {
939
+ ChunkIter :: Zeros => { }
940
+ ChunkIter :: Ones ( iter) => {
941
+ if let Some ( next) = iter. next ( ) {
942
+ return Some ( T :: new ( next + self . chunk_index * CHUNK_BITS ) ) ;
964
943
}
965
944
}
966
- Mixed ( _, _, words) => {
967
- init = BitIter :: new ( & * * words) . fold ( init, |val, mut item : T | {
968
- item. increment_by ( base) ;
969
- f ( val, item)
970
- } ) ;
945
+ ChunkIter :: Mixed ( iter) => {
946
+ if let Some ( next) = iter. next ( ) {
947
+ return Some ( T :: new ( next + self . chunk_index * CHUNK_BITS ) ) ;
948
+ }
971
949
}
950
+ ChunkIter :: Finished => return None ,
972
951
}
952
+ self . chunk_index += 1 ;
953
+ self . chunk_iter = self . bit_set . chunk_iter ( self . chunk_index ) ;
973
954
}
974
- init
975
955
}
976
956
}
977
957
@@ -1023,6 +1003,13 @@ impl Chunk {
1023
1003
}
1024
1004
}
1025
1005
1006
+ enum ChunkIter < ' a > {
1007
+ Zeros ,
1008
+ Ones ( Range < usize > ) ,
1009
+ Mixed ( BitIter < ' a , usize > ) ,
1010
+ Finished ,
1011
+ }
1012
+
1026
1013
// Applies a function to mutate a bitset, and returns true if any
1027
1014
// of the applications return true
1028
1015
fn sequential_update < T : Idx > (
0 commit comments