1#[cfg(not(feature = "std"))]
2use alloc::{boxed::Box, vec::Vec};
3
4use crate::sync::atomic::{AtomicPtr, Ordering};
5use core::ptr;
6use crate::storage::Node;
7
8pub struct T1<K, V> {
14 pub(crate) mask: usize,
15 pub(crate) slots: Box<[AtomicPtr<Node<K, V>>]>,
16}
17
18unsafe impl<K: Send, V: Send> Send for T1<K, V> {}
19unsafe impl<K: Send + Sync, V: Send + Sync> Sync for T1<K, V> {}
20
21impl<K, V> T1<K, V> {
22 pub fn new(slots_count: usize) -> Self {
23 let mut slots = Vec::with_capacity(slots_count);
24 for _ in 0..slots_count {
25 slots.push(AtomicPtr::new(ptr::null_mut()));
26 }
27 Self {
28 mask: slots_count - 1,
29 slots: slots.into_boxed_slice(),
30 }
31 }
32
33 #[inline(always)]
34 pub fn load_slot(&self, hash: u64) -> *mut Node<K, V> {
35 let idx = hash as usize & self.mask;
36 self.slots[idx].load(Ordering::Acquire)
37 }
38
39 #[inline(always)]
40 pub fn store_slot(&self, hash: u64, ptr: *mut Node<K, V>) {
41 let idx = hash as usize & self.mask;
42 self.slots[idx].store(ptr, Ordering::Release);
43 }
44
45 #[inline(always)]
47 pub fn get_node<'a>(&self, hash: u64) -> Option<&'a Node<K, V>> {
48 let ptr = self.load_slot(hash);
49 if ptr.is_null() {
50 None
51 } else {
52 Some(unsafe { &*ptr })
53 }
54 }
55
56 #[inline(always)]
57 pub fn clear_if_matches(&self, hash: u64, expected_ptr: *mut Node<K, V>) {
58 let idx = hash as usize & self.mask;
59 let _ = self.slots[idx].compare_exchange(
60 expected_ptr,
61 ptr::null_mut(),
62 Ordering::Release,
63 Ordering::Relaxed,
64 );
65 }
66
67 #[inline(always)]
68 pub fn clear_at(&self, idx: usize) {
69 self.slots[idx].store(ptr::null_mut(), Ordering::Relaxed);
70 }
71
72 #[inline(always)]
73 pub fn len(&self) -> usize {
74 self.slots.len()
75 }
76}
77
78pub struct T2<K, V> {
84 pub(crate) mask: usize,
85 pub(crate) slots: Box<[AtomicPtr<Node<K, V>>]>,
86}
87
88unsafe impl<K: Send, V: Send> Send for T2<K, V> {}
89unsafe impl<K: Send + Sync, V: Send + Sync> Sync for T2<K, V> {}
90
91impl<K, V> T2<K, V> {
92 pub fn new(slots_count: usize) -> Self {
93 let mut slots = Vec::with_capacity(slots_count);
94 for _ in 0..slots_count {
95 slots.push(AtomicPtr::new(ptr::null_mut()));
96 }
97 Self {
98 mask: slots_count - 1,
99 slots: slots.into_boxed_slice(),
100 }
101 }
102
103 #[inline(always)]
104 pub fn load_slot(&self, hash: u64) -> *mut Node<K, V> {
105 let idx = hash as usize & self.mask;
106 self.slots[idx].load(Ordering::Acquire)
107 }
108
109 #[inline(always)]
110 pub fn store_slot(&self, hash: u64, ptr: *mut Node<K, V>) {
111 let idx = hash as usize & self.mask;
112 self.slots[idx].store(ptr, Ordering::Release);
113 }
114
115 #[inline(always)]
117 pub fn get_node<'a>(&self, hash: u64) -> Option<&'a Node<K, V>> {
118 let ptr = self.load_slot(hash);
119 if ptr.is_null() {
120 None
121 } else {
122 Some(unsafe { &*ptr })
123 }
124 }
125
126 #[inline(always)]
127 pub fn clear_if_matches(&self, hash: u64, expected_ptr: *mut Node<K, V>) {
128 let idx = hash as usize & self.mask;
129 let _ = self.slots[idx].compare_exchange(
130 expected_ptr,
131 ptr::null_mut(),
132 Ordering::Release,
133 Ordering::Relaxed,
134 );
135 }
136
137 #[inline(always)]
138 pub fn clear_at(&self, idx: usize) {
139 self.slots[idx].store(ptr::null_mut(), Ordering::Relaxed);
140 }
141
142 #[inline(always)]
143 pub fn len(&self) -> usize {
144 self.slots.len()
145 }
146}