@@ -145,27 +145,22 @@ fn h2(hash: u64) -> u8 {
145145/// Proof that the probe will visit every group in the table:
146146/// <https://fgiesen.wordpress.com/2015/02/22/triangular-numbers-mod-2n/>
147147struct ProbeSeq {
148- bucket_mask : usize ,
149148 pos : usize ,
150149 stride : usize ,
151150}
152151
153- impl Iterator for ProbeSeq {
154- type Item = usize ;
155-
152+ impl ProbeSeq {
156153 #[ inline]
157- fn next ( & mut self ) -> Option < usize > {
154+ fn move_next ( & mut self , bucket_mask : usize ) {
158155 // We should have found an empty bucket by now and ended the probe.
159156 debug_assert ! (
160- self . stride <= self . bucket_mask,
157+ self . stride <= bucket_mask,
161158 "Went past end of probe sequence"
162159 ) ;
163160
164- let result = self . pos ;
165161 self . stride += Group :: WIDTH ;
166162 self . pos += self . stride ;
167- self . pos &= self . bucket_mask ;
168- Some ( result)
163+ self . pos &= bucket_mask;
169164 }
170165}
171166
@@ -578,15 +573,14 @@ impl<T> RawTable<T> {
578573 }
579574 }
580575
581- /// Returns an iterator for a probe sequence on the table.
576+ /// Returns an iterator-like object for a probe sequence on the table.
582577 ///
583578 /// This iterator never terminates, but is guaranteed to visit each bucket
584579 /// group exactly once. The loop using `probe_seq` must terminate upon
585580 /// reaching a group containing an empty bucket.
586581 #[ cfg_attr( feature = "inline-more" , inline) ]
587582 fn probe_seq ( & self , hash : u64 ) -> ProbeSeq {
588583 ProbeSeq {
589- bucket_mask : self . bucket_mask ,
590584 pos : h1 ( hash) & self . bucket_mask ,
591585 stride : 0 ,
592586 }
@@ -626,11 +620,12 @@ impl<T> RawTable<T> {
626620 /// There must be at least 1 empty bucket in the table.
627621 #[ cfg_attr( feature = "inline-more" , inline) ]
628622 fn find_insert_slot ( & self , hash : u64 ) -> usize {
629- for pos in self . probe_seq ( hash) {
623+ let mut probe_seq = self . probe_seq ( hash) ;
624+ loop {
630625 unsafe {
631- let group = Group :: load ( self . ctrl ( pos) ) ;
626+ let group = Group :: load ( self . ctrl ( probe_seq . pos ) ) ;
632627 if let Some ( bit) = group. match_empty_or_deleted ( ) . lowest_set_bit ( ) {
633- let result = ( pos + bit) & self . bucket_mask ;
628+ let result = ( probe_seq . pos + bit) & self . bucket_mask ;
634629
635630 // In tables smaller than the group width, trailing control
636631 // bytes outside the range of the table are filled with
@@ -643,7 +638,7 @@ impl<T> RawTable<T> {
643638 // control bytes (containing EMPTY).
644639 if unlikely ( is_full ( * self . ctrl ( result) ) ) {
645640 debug_assert ! ( self . bucket_mask < Group :: WIDTH ) ;
646- debug_assert_ne ! ( pos, 0 ) ;
641+ debug_assert_ne ! ( probe_seq . pos, 0 ) ;
647642 return Group :: load_aligned ( self . ctrl ( 0 ) )
648643 . match_empty_or_deleted ( )
649644 . lowest_set_bit_nonzero ( ) ;
@@ -652,10 +647,8 @@ impl<T> RawTable<T> {
652647 }
653648 }
654649 }
650+ probe_seq. move_next ( self . bucket_mask ) ;
655651 }
656-
657- // probe_seq never returns.
658- unreachable ! ( ) ;
659652 }
660653
661654 /// Marks all table buckets as empty without dropping their contents.
@@ -1872,8 +1865,6 @@ pub struct RawIterHash<'a, T> {
18721865 // The sequence of groups to probe in the search.
18731866 probe_seq : ProbeSeq ,
18741867
1875- // The current group and its position.
1876- pos : usize ,
18771868 group : Group ,
18781869
18791870 // The elements within the group with a matching h2-hash.
@@ -1884,16 +1875,14 @@ impl<'a, T> RawIterHash<'a, T> {
18841875 fn new ( table : & ' a RawTable < T > , hash : u64 ) -> Self {
18851876 unsafe {
18861877 let h2_hash = h2 ( hash) ;
1887- let mut probe_seq = table. probe_seq ( hash) ;
1888- let pos = probe_seq. next ( ) . unwrap ( ) ;
1889- let group = Group :: load ( table. ctrl ( pos) ) ;
1878+ let probe_seq = table. probe_seq ( hash) ;
1879+ let group = Group :: load ( table. ctrl ( probe_seq. pos ) ) ;
18901880 let bitmask = group. match_byte ( h2_hash) . into_iter ( ) ;
18911881
18921882 RawIterHash {
18931883 table,
18941884 h2_hash,
18951885 probe_seq,
1896- pos,
18971886 group,
18981887 bitmask,
18991888 }
@@ -1908,15 +1897,15 @@ impl<'a, T> Iterator for RawIterHash<'a, T> {
19081897 unsafe {
19091898 loop {
19101899 if let Some ( bit) = self . bitmask . next ( ) {
1911- let index = ( self . pos + bit) & self . table . bucket_mask ;
1900+ let index = ( self . probe_seq . pos + bit) & self . table . bucket_mask ;
19121901 let bucket = self . table . bucket ( index) ;
19131902 return Some ( bucket) ;
19141903 }
19151904 if likely ( self . group . match_empty ( ) . any_bit_set ( ) ) {
19161905 return None ;
19171906 }
1918- self . pos = self . probe_seq . next ( ) . unwrap ( ) ;
1919- self . group = Group :: load ( self . table . ctrl ( self . pos ) ) ;
1907+ self . probe_seq . move_next ( self . table . bucket_mask ) ;
1908+ self . group = Group :: load ( self . table . ctrl ( self . probe_seq . pos ) ) ;
19201909 self . bitmask = self . group . match_byte ( self . h2_hash ) . into_iter ( ) ;
19211910 }
19221911 }
0 commit comments