@@ -1622,17 +1622,39 @@ impl<A: Allocator + Clone> RawTableInner<A> {
1622
1622
}
1623
1623
}
1624
1624
1625
- /// Searches for an element in the table. This uses dynamic dispatch to reduce the amount of
1626
- /// code generated, but it is eliminated by LLVM optimizations.
1625
+ /// Searches for an element in a table, returning the `index` of the found element.
1626
+ /// This uses dynamic dispatch to reduce the amount of code generated, but it is
1627
+ /// eliminated by LLVM optimizations.
1628
+ ///
1629
+ /// This function does not make any changes to the `data` part of the table, or any
1630
+ /// changes to the `items` or `growth_left` field of the table.
1631
+ ///
1632
+ /// The table must have at least 1 empty `bucket`, otherwise, if the
1633
+ /// `eq: &mut dyn FnMut(usize) -> bool` function does not return `true`,
1634
+ /// this function will also never return (will go into an infinite loop).
1627
1635
#[ inline( always) ]
1628
1636
fn find_inner ( & self , hash : u64 , eq : & mut dyn FnMut ( usize ) -> bool ) -> Option < usize > {
1629
1637
let h2_hash = h2 ( hash) ;
1630
1638
let mut probe_seq = self . probe_seq ( hash) ;
1631
1639
1632
1640
loop {
1641
+ // SAFETY:
1642
+ // * `ProbeSeq.pos` cannot be greater than `self.bucket_mask = self.buckets() - 1`
1643
+ // of the table due to masking with `self.bucket_mask`.
1644
+ //
1645
+ // * Even if `ProbeSeq.pos` returns `position == self.bucket_mask`, it is safe to
1646
+ // call `Group::load` due to the extended control bytes range, which is
1647
+ // `self.bucket_mask + 1 + Group::WIDTH` (in fact, this means that the last control
1648
+ // byte will never be read for the allocated table);
1649
+ //
1650
+ // * Also, even if `RawTableInner` is not already allocated, `ProbeSeq.pos` will
1651
+ // always return "0" (zero), so Group::load will read unaligned `Group::static_empty()`
1652
+ // bytes, which is safe (see RawTableInner::new_in).
1633
1653
let group = unsafe { Group :: load ( self . ctrl ( probe_seq. pos ) ) } ;
1634
1654
1635
1655
for bit in group. match_byte ( h2_hash) {
1656
+ // This is the same as `(probe_seq.pos + bit) % self.buckets()` because the number
1657
+ // of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
1636
1658
let index = ( probe_seq. pos + bit) & self . bucket_mask ;
1637
1659
1638
1660
if likely ( eq ( index) ) {
0 commit comments