@@ -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
@@ -675,6 +687,7 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
675687 changed
676688 }
677689
690+ // njn: add test for this
678691 fn subtract ( & mut self , other : & ChunkedBitSet < T > ) -> bool {
679692 assert_eq ! ( self . domain_size, other. domain_size) ;
680693 debug_assert_eq ! ( self . chunks. len( ) , other. chunks. len( ) ) ;
@@ -755,6 +768,7 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
755768 changed
756769 }
757770
771+ // njn: add test for this
758772 fn intersect ( & mut self , other : & ChunkedBitSet < T > ) -> bool {
759773 assert_eq ! ( self . domain_size, other. domain_size) ;
760774 debug_assert_eq ! ( self . chunks. len( ) , other. chunks. len( ) ) ;
@@ -900,78 +914,44 @@ impl<T> Clone for ChunkedBitSet<T> {
900914}
901915
902916pub struct ChunkedBitIter < ' a , T : Idx > {
903- index : usize ,
904917 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 > ,
905924}
906925
907926impl < ' a , T : Idx > ChunkedBitIter < ' a , T > {
908927 #[ inline]
909928 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 ) }
911930 }
912931}
913932
914933impl < ' a , T : Idx > Iterator for ChunkedBitIter < ' a , T > {
915934 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- }
943935
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 ) ) ;
964943 }
965944 }
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+ }
971949 }
950+ ChunkIter :: Finished => return None ,
972951 }
952+ self . chunk_index += 1 ;
953+ self . chunk_iter = self . bit_set . chunk_iter ( self . chunk_index ) ;
973954 }
974- init
975955 }
976956}
977957
@@ -1023,6 +1003,13 @@ impl Chunk {
10231003 }
10241004}
10251005
1006+ enum ChunkIter < ' a > {
1007+ Zeros ,
1008+ Ones ( Range < usize > ) ,
1009+ Mixed ( BitIter < ' a , usize > ) ,
1010+ Finished ,
1011+ }
1012+
10261013// Applies a function to mutate a bitset, and returns true if any
10271014// of the applications return true
10281015fn sequential_update < T : Idx > (
0 commit comments