@@ -145,27 +145,22 @@ fn h2(hash: u64) -> u8 {
145
145
/// Proof that the probe will visit every group in the table:
146
146
/// <https://fgiesen.wordpress.com/2015/02/22/triangular-numbers-mod-2n/>
147
147
struct ProbeSeq {
148
- bucket_mask : usize ,
149
148
pos : usize ,
150
149
stride : usize ,
151
150
}
152
151
153
- impl Iterator for ProbeSeq {
154
- type Item = usize ;
155
-
152
+ impl ProbeSeq {
156
153
#[ inline]
157
- fn next ( & mut self ) -> Option < usize > {
154
+ fn move_next ( & mut self , bucket_mask : usize ) {
158
155
// We should have found an empty bucket by now and ended the probe.
159
156
debug_assert ! (
160
- self . stride <= self . bucket_mask,
157
+ self . stride <= bucket_mask,
161
158
"Went past end of probe sequence"
162
159
) ;
163
160
164
- let result = self . pos ;
165
161
self . stride += Group :: WIDTH ;
166
162
self . pos += self . stride ;
167
- self . pos &= self . bucket_mask ;
168
- Some ( result)
163
+ self . pos &= bucket_mask;
169
164
}
170
165
}
171
166
@@ -578,15 +573,14 @@ impl<T> RawTable<T> {
578
573
}
579
574
}
580
575
581
- /// Returns an iterator for a probe sequence on the table.
576
+ /// Returns an iterator-like object for a probe sequence on the table.
582
577
///
583
578
/// This iterator never terminates, but is guaranteed to visit each bucket
584
579
/// group exactly once. The loop using `probe_seq` must terminate upon
585
580
/// reaching a group containing an empty bucket.
586
581
#[ cfg_attr( feature = "inline-more" , inline) ]
587
582
fn probe_seq ( & self , hash : u64 ) -> ProbeSeq {
588
583
ProbeSeq {
589
- bucket_mask : self . bucket_mask ,
590
584
pos : h1 ( hash) & self . bucket_mask ,
591
585
stride : 0 ,
592
586
}
@@ -626,11 +620,12 @@ impl<T> RawTable<T> {
626
620
/// There must be at least 1 empty bucket in the table.
627
621
#[ cfg_attr( feature = "inline-more" , inline) ]
628
622
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 {
630
625
unsafe {
631
- let group = Group :: load ( self . ctrl ( pos) ) ;
626
+ let group = Group :: load ( self . ctrl ( probe_seq . pos ) ) ;
632
627
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 ;
634
629
635
630
// In tables smaller than the group width, trailing control
636
631
// bytes outside the range of the table are filled with
@@ -643,7 +638,7 @@ impl<T> RawTable<T> {
643
638
// control bytes (containing EMPTY).
644
639
if unlikely ( is_full ( * self . ctrl ( result) ) ) {
645
640
debug_assert ! ( self . bucket_mask < Group :: WIDTH ) ;
646
- debug_assert_ne ! ( pos, 0 ) ;
641
+ debug_assert_ne ! ( probe_seq . pos, 0 ) ;
647
642
return Group :: load_aligned ( self . ctrl ( 0 ) )
648
643
. match_empty_or_deleted ( )
649
644
. lowest_set_bit_nonzero ( ) ;
@@ -652,10 +647,8 @@ impl<T> RawTable<T> {
652
647
}
653
648
}
654
649
}
650
+ probe_seq. move_next ( self . bucket_mask ) ;
655
651
}
656
-
657
- // probe_seq never returns.
658
- unreachable ! ( ) ;
659
652
}
660
653
661
654
/// Marks all table buckets as empty without dropping their contents.
@@ -1872,8 +1865,6 @@ pub struct RawIterHash<'a, T> {
1872
1865
// The sequence of groups to probe in the search.
1873
1866
probe_seq : ProbeSeq ,
1874
1867
1875
- // The current group and its position.
1876
- pos : usize ,
1877
1868
group : Group ,
1878
1869
1879
1870
// The elements within the group with a matching h2-hash.
@@ -1884,16 +1875,14 @@ impl<'a, T> RawIterHash<'a, T> {
1884
1875
fn new ( table : & ' a RawTable < T > , hash : u64 ) -> Self {
1885
1876
unsafe {
1886
1877
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 ) ) ;
1890
1880
let bitmask = group. match_byte ( h2_hash) . into_iter ( ) ;
1891
1881
1892
1882
RawIterHash {
1893
1883
table,
1894
1884
h2_hash,
1895
1885
probe_seq,
1896
- pos,
1897
1886
group,
1898
1887
bitmask,
1899
1888
}
@@ -1908,15 +1897,15 @@ impl<'a, T> Iterator for RawIterHash<'a, T> {
1908
1897
unsafe {
1909
1898
loop {
1910
1899
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 ;
1912
1901
let bucket = self . table . bucket ( index) ;
1913
1902
return Some ( bucket) ;
1914
1903
}
1915
1904
if likely ( self . group . match_empty ( ) . any_bit_set ( ) ) {
1916
1905
return None ;
1917
1906
}
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 ) ) ;
1920
1909
self . bitmask = self . group . match_byte ( self . h2_hash ) . into_iter ( ) ;
1921
1910
}
1922
1911
}
0 commit comments