1use crate::bucket_array::mem::{self, BucketArrayMemory};
14use num_traits::{One, WrappingAdd, WrappingNeg, Zero};
15use std::marker::PhantomData;
16use std::ops::{BitAnd, Div, Mul, Not, Range, Rem, Shl, Shr, Sub};
17
18pub(crate) trait Shape<K: Key> {
20 const NUM_BUCKETS: usize;
22
23 fn item_range(&self, bucket: usize) -> Range<usize>;
25
26 #[inline(always)]
28 fn divisor(&self) -> K {
29 K::from_bucket_index(Self::NUM_BUCKETS)
30 }
31
32 #[inline(always)]
34 fn split_wide_key(&self, key: K) -> (usize, K) {
35 let divisor = self.divisor();
36 ((key % divisor).into_bucket_index(), (key / divisor))
37 }
38
39 #[inline(always)]
41 fn join_wide_key(&self, bucket: usize, remainder: K) -> K {
42 let divisor = self.divisor();
43 remainder * divisor + K::from_bucket_index(bucket)
44 }
45}
46
47pub(crate) trait Insert<K: Key, V: Copy> {
49 fn insert(&mut self, key: K, value: V) -> Result<(), ()>;
51}
52
53pub(crate) trait KeyLookup<S: KeyStorage<K>, K: Key> {
58 fn item_stored_key(&self, bucket: usize, item: usize) -> S;
60
61 fn item_full_key(&self, bucket: usize, item: usize) -> K;
63}
64
65pub(crate) trait ValueLookup<V: Copy> {
69 fn item_value(&self, bucket: usize, item: usize) -> V;
71}
72
73pub(crate) struct KeyValueBucketArray<
87 'k,
89 'v,
91 const N: usize,
93 const CAP: usize,
95 C: Count,
97 K: Key,
99 KS: KeyStorage<K>,
101 V: Copy,
103>(
104 mem::BucketArrayPair<'k, 'v, N, CAP, C, KS, V>,
105 PhantomData<K>,
106);
107
108impl<'k, 'v, const N: usize, const CAP: usize, C: Count, K: Key, KS: KeyStorage<K>, V: Copy>
109 KeyValueBucketArray<'k, 'v, N, CAP, C, K, KS, V>
110{
111 pub(crate) fn new(
114 key_mem: &'k mut BucketArrayMemory<N, CAP, KS>,
115 value_mem: &'v mut BucketArrayMemory<N, CAP, V>,
116 ) -> Self {
117 Self(mem::BucketArrayPair::new(key_mem, value_mem), PhantomData)
118 }
119
120 pub(crate) fn drop_key_storage(self) -> ValueBucketArray<'v, N, CAP, C, K, V> {
124 ValueBucketArray(self.0.drop_first(), self.1)
125 }
126}
127
128pub(crate) struct ValueBucketArray<
132 'v,
134 const N: usize,
136 const CAP: usize,
138 C: Count,
140 K: Key,
142 V: Copy,
144>(mem::BucketArray<'v, N, CAP, C, V>, PhantomData<K>);
145
146impl<'v, const N: usize, const CAP: usize, C: Count, K: Key, V: Copy>
147 ValueBucketArray<'v, N, CAP, C, K, V>
148{
149 pub(crate) fn new(value_mem: &'v mut BucketArrayMemory<N, CAP, V>) -> Self {
152 Self(mem::BucketArray::new(value_mem), PhantomData)
153 }
154}
155
156impl<'k, 'v, const N: usize, const CAP: usize, C: Count, K: Key, KS: KeyStorage<K>, V: Copy>
157 Shape<K> for KeyValueBucketArray<'k, 'v, N, CAP, C, K, KS, V>
158{
159 const NUM_BUCKETS: usize = N;
161
162 #[inline(always)]
163 fn item_range(&self, bucket: usize) -> Range<usize> {
164 self.0.item_range(bucket)
165 }
166}
167
168impl<'v, const N: usize, const CAP: usize, C: Count, K: Key, V: Copy> Shape<K>
169 for ValueBucketArray<'v, N, CAP, C, K, V>
170{
171 const NUM_BUCKETS: usize = N;
173
174 #[inline(always)]
175 fn item_range(&self, bucket: usize) -> Range<usize> {
176 self.0.item_range(bucket)
177 }
178}
179
180impl<'k, 'v, const N: usize, const CAP: usize, C: Count, K: Key, KS: KeyStorage<K>, V: Copy>
181 Insert<K, V> for KeyValueBucketArray<'k, 'v, N, CAP, C, K, KS, V>
182{
183 #[inline(always)]
184 fn insert(&mut self, key: K, value: V) -> Result<(), ()> {
185 let (bucket, key_remainder) = self.split_wide_key(key);
186 let key_storage = KS::from_key(key_remainder);
187 self.0.insert(bucket, key_storage, value)
188 }
189}
190
191impl<'v, const N: usize, const CAP: usize, C: Count, K: Key, V: Copy> Insert<K, V>
192 for ValueBucketArray<'v, N, CAP, C, K, V>
193{
194 #[inline(always)]
195 fn insert(&mut self, key: K, value: V) -> Result<(), ()> {
196 let (bucket, _) = self.split_wide_key(key);
197 self.0.insert(bucket, value)
198 }
199}
200
201impl<'k, 'v, const N: usize, const CAP: usize, C: Count, K: Key, KS: KeyStorage<K>, V: Copy>
202 KeyLookup<KS, K> for KeyValueBucketArray<'k, 'v, N, CAP, C, K, KS, V>
203{
204 #[inline(always)]
205 fn item_stored_key(&self, bucket: usize, item: usize) -> KS {
206 self.0.item_value_first(bucket, item)
207 }
208
209 #[inline(always)]
210 fn item_full_key(&self, bucket: usize, item: usize) -> K {
211 self.join_wide_key(bucket, self.item_stored_key(bucket, item).into_key())
212 }
213}
214
215impl<'k, 'v, const N: usize, const CAP: usize, C: Count, K: Key, KS: KeyStorage<K>, V: Copy>
216 ValueLookup<V> for KeyValueBucketArray<'k, 'v, N, CAP, C, K, KS, V>
217{
218 #[inline(always)]
219 fn item_value(&self, bucket: usize, item: usize) -> V {
220 self.0.item_value_second(bucket, item)
221 }
222}
223
224impl<'v, const N: usize, const CAP: usize, C: Count, K: Key, V: Copy> ValueLookup<V>
225 for ValueBucketArray<'v, N, CAP, C, K, V>
226{
227 #[inline(always)]
228 fn item_value(&self, bucket: usize, item: usize) -> V {
229 self.0.item_value(bucket, item)
230 }
231}
232
233pub(crate) trait Count: mem::Count + TryFrom<usize> {
239 #[inline(always)]
241 fn from_item_index(i: usize) -> Self {
242 i.try_into()
246 .map_err(|_| ())
247 .expect("Bucket count type is always wide enough for item index")
248 }
249}
250
251impl<T: mem::Count + TryFrom<usize>> Count for T {}
252
253pub(crate) trait Key:
255 Copy
256 + Zero
257 + One
258 + PartialEq<Self>
259 + TryFrom<usize>
260 + TryInto<usize>
261 + Shl<usize, Output = Self>
262 + Shr<usize, Output = Self>
263 + Div<Self, Output = Self>
264 + Rem<Self, Output = Self>
265 + Mul<Self, Output = Self>
266 + Not
267 + Sub<Self, Output = Self>
268 + BitAnd<Self, Output = Self>
269 + WrappingAdd
270 + WrappingNeg
271{
272 #[inline(always)]
276 fn from_bucket_index(i: usize) -> Self {
277 i.try_into()
278 .map_err(|_| ())
279 .expect("Key type is always wide enough for a bucket index")
280 }
281
282 #[inline(always)]
287 fn into_bucket_index(self) -> usize {
288 self.try_into()
289 .map_err(|_| ())
290 .expect("Key is a bucket index which always fits in a usize")
291 }
292
293 #[inline(always)]
295 fn low_bits_are_zero(self, num_bits: usize) -> bool {
296 (self & ((Self::one() << num_bits) - Self::one())) == Self::zero()
297 }
298}
299
300impl<
301 T: Copy
302 + Zero
303 + One
304 + PartialEq<Self>
305 + TryFrom<usize>
306 + TryInto<usize>
307 + Shl<usize, Output = Self>
308 + Shr<usize, Output = Self>
309 + Div<Self, Output = Self>
310 + Rem<Self, Output = Self>
311 + Mul<Self, Output = Self>
312 + Not
313 + Sub<Self, Output = Self>
314 + BitAnd<Self, Output = Self>
315 + WrappingAdd
316 + WrappingNeg,
317 > Key for T
318{
319}
320
321pub(crate) trait KeyStorage<K>:
325 Copy + Zero + Not<Output = Self> + TryFrom<K> + TryInto<K>
326where
327 K: Key,
328{
329 #[inline(always)]
334 fn from_key(k: K) -> Self {
335 let key_mask = (!Self::zero()).into_key();
336 <K as TryInto<Self>>::try_into(k & key_mask)
337 .map_err(|_| ())
338 .expect("masked Key type always fits in KeyStorage")
339 }
340
341 #[inline(always)]
344 fn into_key(self) -> K {
345 self.try_into()
346 .map_err(|_| ())
347 .expect("Key type is always wider than KeyStorage")
348 }
349}
350
351impl<T: Copy + Zero + Not<Output = Self> + TryFrom<K> + TryInto<K>, K: Key> KeyStorage<K> for T {}