@@ -613,6 +613,18 @@ impl<T: Idx> ChunkedBitSet<T> {
613613 }
614614 }
615615
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+
616628 bit_relations_inherent_impls ! { }
617629}
618630
@@ -900,78 +912,44 @@ impl<T> Clone for ChunkedBitSet<T> {
900912}
901913
902914pub struct ChunkedBitIter < ' a , T : Idx > {
903- index : usize ,
904915 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 > ,
905922}
906923
907924impl < ' a , T : Idx > ChunkedBitIter < ' a , T > {
908925 #[ inline]
909926 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 ) }
911928 }
912929}
913930
914931impl < ' a , T : Idx > Iterator for ChunkedBitIter < ' a , T > {
915932 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- }
943933
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 ) ) ;
964941 }
965942 }
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+ }
971947 }
948+ ChunkIter :: Finished => return None ,
972949 }
950+ self . chunk_index += 1 ;
951+ self . chunk_iter = self . bit_set . chunk_iter ( self . chunk_index ) ;
973952 }
974- init
975953 }
976954}
977955
@@ -1023,6 +1001,13 @@ impl Chunk {
10231001 }
10241002}
10251003
1004+ enum ChunkIter < ' a > {
1005+ Zeros ,
1006+ Ones ( Range < usize > ) ,
1007+ Mixed ( BitIter < ' a , usize > ) ,
1008+ Finished ,
1009+ }
1010+
10261011// Applies a function to mutate a bitset, and returns true if any
10271012// of the applications return true
10281013fn sequential_update < T : Idx > (
0 commit comments