@@ -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
@@ -900,78 +912,44 @@ impl<T> Clone for ChunkedBitSet<T> {
900
912
}
901
913
902
914
pub struct ChunkedBitIter < ' a , T : Idx > {
903
- index : usize ,
904
915
bit_set : & ' a ChunkedBitSet < T > ,
916
+
917
+ // The index of the current chunk.
918
+ chunk_index : usize ,
919
+
920
+ // The sub-iterator for the current chunk.
921
+ chunk_iter : ChunkIter < ' a > ,
905
922
}
906
923
907
924
impl < ' a , T : Idx > ChunkedBitIter < ' a , T > {
908
925
#[ inline]
909
926
fn new ( bit_set : & ' a ChunkedBitSet < T > ) -> ChunkedBitIter < ' a , T > {
910
- ChunkedBitIter { index : 0 , bit_set }
927
+ ChunkedBitIter { bit_set , chunk_index : 0 , chunk_iter : bit_set. chunk_iter ( 0 ) }
911
928
}
912
929
}
913
930
914
931
impl < ' a , T : Idx > Iterator for ChunkedBitIter < ' a , T > {
915
932
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
933
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) ) ;
934
+ fn next ( & mut self ) -> Option < T > {
935
+ loop {
936
+ match & mut self . chunk_iter {
937
+ ChunkIter :: Zeros => { }
938
+ ChunkIter :: Ones ( iter) => {
939
+ if let Some ( next) = iter. next ( ) {
940
+ return Some ( T :: new ( next + self . chunk_index * CHUNK_BITS ) ) ;
964
941
}
965
942
}
966
- Mixed ( _, _, words) => {
967
- init = BitIter :: new ( & * * words) . fold ( init, |val, mut item : T | {
968
- item. increment_by ( base) ;
969
- f ( val, item)
970
- } ) ;
943
+ ChunkIter :: Mixed ( iter) => {
944
+ if let Some ( next) = iter. next ( ) {
945
+ return Some ( T :: new ( next + self . chunk_index * CHUNK_BITS ) ) ;
946
+ }
971
947
}
948
+ ChunkIter :: Finished => return None ,
972
949
}
950
+ self . chunk_index += 1 ;
951
+ self . chunk_iter = self . bit_set . chunk_iter ( self . chunk_index ) ;
973
952
}
974
- init
975
953
}
976
954
}
977
955
@@ -1023,6 +1001,13 @@ impl Chunk {
1023
1001
}
1024
1002
}
1025
1003
1004
+ enum ChunkIter < ' a > {
1005
+ Zeros ,
1006
+ Ones ( Range < usize > ) ,
1007
+ Mixed ( BitIter < ' a , usize > ) ,
1008
+ Finished ,
1009
+ }
1010
+
1026
1011
// Applies a function to mutate a bitset, and returns true if any
1027
1012
// of the applications return true
1028
1013
fn sequential_update < T : Idx > (
0 commit comments