Skip to content

Commit cb4a210

Browse files
committed
Optimize find for size
1 parent 4f87bdf commit cb4a210

File tree

1 file changed

+35
-8
lines changed

1 file changed

+35
-8
lines changed

src/raw/mod.rs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -921,14 +921,13 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
921921
/// Searches for an element in the table.
922922
#[inline]
923923
pub fn find(&self, hash: u64, mut eq: impl FnMut(&T) -> bool) -> Option<Bucket<T>> {
924-
unsafe {
925-
for bucket in self.iter_hash(hash) {
926-
let elm = bucket.as_ref();
927-
if likely(eq(elm)) {
928-
return Some(bucket);
929-
}
930-
}
931-
None
924+
let result = self.table.find_inner(hash, &mut |index| unsafe {
925+
eq(self.bucket(index).as_ref())
926+
});
927+
928+
match result {
929+
Some(index) => Some(unsafe { self.bucket(index) }),
930+
None => None,
932931
}
933932
}
934933

@@ -1054,6 +1053,7 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
10541053
/// `RawIterHash`. Because we cannot make the `next` method unsafe on the
10551054
/// `RawIterHash` struct, we have to make the `iter_hash` method unsafe.
10561055
#[cfg_attr(feature = "inline-more", inline)]
1056+
#[allow(dead_code)] // Used when the `raw` API is enabled
10571057
pub unsafe fn iter_hash(&self, hash: u64) -> RawIterHash<'_, T, A> {
10581058
RawIterHash::new(self, hash)
10591059
}
@@ -1255,6 +1255,33 @@ impl<A: Allocator + Clone> RawTableInner<A> {
12551255
}
12561256
}
12571257

1258+
/// Searches for an element in the table.
1259+
#[inline]
1260+
fn find_inner(&self, hash: u64, eq: &mut dyn FnMut(usize) -> bool) -> Option<usize> {
1261+
unsafe {
1262+
let h2_hash = h2(hash);
1263+
let mut probe_seq = self.probe_seq(hash);
1264+
1265+
loop {
1266+
let group = Group::load(self.ctrl(probe_seq.pos));
1267+
1268+
for bit in group.match_byte(h2_hash) {
1269+
let index = (probe_seq.pos + bit) & self.bucket_mask;
1270+
1271+
if likely(eq(index)) {
1272+
return Some(index);
1273+
}
1274+
}
1275+
1276+
if likely(group.match_empty().any_bit_set()) {
1277+
return None;
1278+
}
1279+
1280+
probe_seq.move_next(self.bucket_mask);
1281+
}
1282+
}
1283+
}
1284+
12581285
#[allow(clippy::mut_mut)]
12591286
#[inline]
12601287
unsafe fn prepare_rehash_in_place(&mut self) {

0 commit comments

Comments
 (0)