@@ -145,27 +145,21 @@ 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
-
156
- #[ inline]
157
- fn next ( & mut self ) -> Option < usize > {
152
+ impl ProbeSeq {
153
+ fn move_next ( & mut self , bucket_mask : usize ) {
158
154
// We should have found an empty bucket by now and ended the probe.
159
155
debug_assert ! (
160
- self . stride <= self . bucket_mask,
156
+ self . stride <= bucket_mask,
161
157
"Went past end of probe sequence"
162
158
) ;
163
159
164
- let result = self . pos ;
165
160
self . stride += Group :: WIDTH ;
166
161
self . pos += self . stride ;
167
- self . pos &= self . bucket_mask ;
168
- Some ( result)
162
+ self . pos &= bucket_mask;
169
163
}
170
164
}
171
165
@@ -578,15 +572,14 @@ impl<T> RawTable<T> {
578
572
}
579
573
}
580
574
581
- /// Returns an iterator for a probe sequence on the table.
575
+ /// Returns an iterator-like object for a probe sequence on the table.
582
576
///
583
577
/// This iterator never terminates, but is guaranteed to visit each bucket
584
578
/// group exactly once. The loop using `probe_seq` must terminate upon
585
579
/// reaching a group containing an empty bucket.
586
580
#[ cfg_attr( feature = "inline-more" , inline) ]
587
581
fn probe_seq ( & self , hash : u64 ) -> ProbeSeq {
588
582
ProbeSeq {
589
- bucket_mask : self . bucket_mask ,
590
583
pos : h1 ( hash) & self . bucket_mask ,
591
584
stride : 0 ,
592
585
}
@@ -626,7 +619,9 @@ impl<T> RawTable<T> {
626
619
/// There must be at least 1 empty bucket in the table.
627
620
#[ cfg_attr( feature = "inline-more" , inline) ]
628
621
fn find_insert_slot ( & self , hash : u64 ) -> usize {
629
- for pos in self . probe_seq ( hash) {
622
+ let mut probe_seq = self . probe_seq ( hash) ;
623
+ loop {
624
+ let pos = probe_seq. pos ;
630
625
unsafe {
631
626
let group = Group :: load ( self . ctrl ( pos) ) ;
632
627
if let Some ( bit) = group. match_empty_or_deleted ( ) . lowest_set_bit ( ) {
@@ -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