osom_lib_hash_tables/bytell/
hash_to_index.rs1use osom_lib_macros::debug_check_or_release_hint;
4use osom_lib_primitives::power_of_two::PowerOfTwo32;
5use osom_lib_reprc::macros::reprc;
6
7pub trait HashToIndex: Default + Clone {
9 fn hash_to_index(&self, hash_value: u64, table_capacity: PowerOfTwo32) -> usize;
11
12 fn update_for_new_table_capacity(&mut self, table_capacity: PowerOfTwo32);
14}
15
16#[derive(Default, Clone, Copy)]
18#[reprc]
19#[repr(transparent)]
20pub struct FibonacciHashToIndex {
21 shift: u8,
22}
23
24impl HashToIndex for FibonacciHashToIndex {
25 #[inline]
26 fn hash_to_index(&self, hash_value: u64, table_capacity: PowerOfTwo32) -> usize {
27 let value = table_capacity.value();
28 debug_check_or_release_hint!(value.is_power_of_two(), "table_size not a power of two");
29 let shift = self.shift;
30 let mut result = hash_value;
31 result ^= result >> shift;
32 result = result.wrapping_mul(11400714819323198485) >> shift;
33 debug_check_or_release_hint!(result < u64::from(u32::MAX), "hash_to_index beyond u32::MAX");
34
35 #[allow(clippy::cast_possible_truncation)]
36 {
37 result as usize
38 }
39 }
40
41 fn update_for_new_table_capacity(&mut self, table_capacity: PowerOfTwo32) {
42 #[allow(clippy::cast_possible_truncation)]
43 {
44 self.shift = (64 - table_capacity.value().trailing_zeros()) as u8;
45 }
46 }
47}
48
49#[derive(Default, Clone, Copy)]
52#[reprc]
53#[repr(transparent)]
54pub struct PowerOfTwoHashToIndex;
55
56impl HashToIndex for PowerOfTwoHashToIndex {
57 #[inline(always)]
58 fn hash_to_index(&self, hash_value: u64, table_capacity: PowerOfTwo32) -> usize {
59 #[allow(clippy::cast_possible_truncation)]
60 let hash_value = hash_value as u32;
61 (hash_value & (table_capacity.value() - 1)) as usize
62 }
63
64 #[inline(always)]
65 fn update_for_new_table_capacity(&mut self, _: PowerOfTwo32) {}
66}