Skip to main content

arctic/raw/key/sized/
unsigned.rs

1//! Support for unsigned integer keys.
2
3use ribbit::u6;
4
5use crate::raw::Key;
6use crate::raw::edge;
7use crate::raw::edge::Meta as _;
8use crate::raw::key;
9use crate::raw::key::Bit;
10use crate::raw::key::Len as _;
11use crate::raw::key::Read as _;
12
13macro_rules! impl_key {
14    ($($ty:ty),* $(,)?) => {
15        $(
16            impl Key for $ty {
17                type Read<'k> = Reader<$ty>;
18                type Write = Writer<$ty>;
19                type Borrowed = Self;
20                type Insert<'k> = Self;
21
22                type Edge = edge::Be;
23                type Len = Bit;
24
25                #[inline]
26                fn as_insert(&self) -> Self::Insert<'_> {
27                    *self
28                }
29
30                #[inline]
31                fn insert_as_read<'k>(insert: Self::Insert<'k>) -> Self::Read<'k>
32                where
33                    Self: 'k,
34                {
35                    Reader::from(insert)
36                }
37
38                fn insert_to_key<'k>(insert: Self::Insert<'k>) -> Self
39                where
40                    Self: 'k,
41                {
42                    insert
43                }
44
45                #[inline]
46                unsafe fn write_as_insert<'k>(writer: &'k Self::Write) -> Self::Insert<'k> where Self: 'k{
47                    writer.0
48                }
49            }
50
51            impl key::Split for $ty {
52                #[inline]
53                fn split_last<'k>(key: &'k Self::Borrowed) -> (Self::Read<'k>, u8) {
54                    let reader = Reader::from(key);
55                    (
56                        Reader {
57                            buffer: reader.buffer,
58                            len: reader.len.0.checked_sub(Self::Len::BYTE.0).map(Bit).expect("Non-empty"),
59                        },
60                        reader.buffer.least_significant_u8(),
61                    )
62                }
63            }
64
65            impl From<$ty> for Reader<$ty> {
66                #[inline]
67                fn from(value: $ty) -> Self {
68                    Self {
69                        buffer: value,
70                        len: Bit(<$ty as Native>::BITS),
71                    }
72                }
73            }
74
75            impl<'k> From<&'k $ty> for Reader<$ty> {
76                #[inline]
77                fn from(value: &'k $ty) -> Self {
78                    Self::from(*value)
79                }
80            }
81
82            impl<'k> From<&'k [u8]> for Reader<$ty> {
83                #[inline]
84                fn from(prefix: &'k [u8]) -> Self {
85                    Self {
86                        buffer: Native::from_be_bytes(prefix),
87                        len: Bit(((prefix.len() << 3) as u8).min(<$ty as Native>::BITS)),
88                    }
89                }
90            }
91
92            impl<'k> From<&'k str> for Reader<$ty> {
93                #[inline]
94                fn from(prefix: &'k str) -> Self {
95                    Self::from(prefix.as_bytes())
96                }
97            }
98
99            impl<'k, const N: usize> From<&'k [u8; N]> for Reader<$ty> {
100                #[inline]
101                fn from(prefix: &'k [u8; N]) -> Self {
102                    Self::from(prefix.as_slice())
103                }
104            }
105        )*
106    };
107}
108
109impl_key!(u16, u32, u128);
110
111#[cfg(not(feature = "opt-no-int"))]
112impl_key!(u64);
113
114#[doc(hidden)]
115#[derive(Copy, Clone, Default, PartialEq, Eq)]
116pub struct Reader<N> {
117    // NOTE: `buffer` is allowed to contain arbitrary bytes beyond
118    // the most significant `len` bytes, but must clear them to
119    // zero when (a) creating an edge to insert into the tree,
120    // or (b) when creating a writer.
121    pub(crate) buffer: N,
122    len: Bit,
123}
124
125impl<N: Native> key::Read for Reader<N> {
126    const LEN: Option<Self::Len> = Some(Bit(N::BITS));
127
128    type Edge = edge::Be;
129    type Len = Bit;
130
131    #[inline]
132    fn len(&self) -> Self::Len {
133        self.len
134    }
135
136    #[inline]
137    fn get_edge(
138        &self,
139        len: <ribbit::Packed<Self::Edge> as edge::Meta>::Len,
140    ) -> ribbit::Packed<Self::Edge> {
141        let len = u6::new(self.len.min(len.into()).0);
142        edge::Be::new(self.buffer.most_significant_u64(), len)
143    }
144
145    #[inline]
146    fn get_byte(&self, index: u6) -> Option<u8> {
147        (self.len > index.into()).then(|| self.buffer.get_u8(index.value()))
148    }
149
150    #[inline]
151    unsafe fn get_byte_unchecked(&self, index: u6) -> u8 {
152        self.buffer.get_u8(index.value())
153    }
154
155    #[inline]
156    fn match_prefix(&self, edge: <Self::Edge as ribbit::Pack>::Packed) -> Self::Len {
157        Bit((edge.raw() ^ self.buffer.most_significant_u64()).leading_zeros() as u8)
158    }
159
160    #[inline]
161    fn prefix(self, end: Self::Len) -> Self {
162        validate!(end <= self.len());
163
164        Self {
165            buffer: self.buffer,
166            len: end,
167        }
168    }
169
170    #[inline]
171    fn suffix(self, start: Self::Len) -> Self {
172        validate!(start <= self.len());
173
174        Self {
175            buffer: self.buffer.unbounded_shl(start.0),
176            len: self.len - start,
177        }
178    }
179
180    #[inline]
181    fn common_prefix(self, other: Self) -> Self {
182        let max = self.len.min(other.len).0;
183        let len = Bit((self.buffer ^ other.buffer).leading_zeros().min(max) & !0b111);
184        Self {
185            buffer: self.buffer,
186            len,
187        }
188    }
189}
190
191impl<N: Native> core::fmt::Debug for Reader<N> {
192    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
193        let bytes = self.len().bytes();
194        self.buffer
195            .with_be_bytes(|buffer| f.debug_list().entries(&buffer[..bytes]).finish())
196    }
197}
198
199#[doc(hidden)]
200#[repr(transparent)]
201#[derive(Default)]
202pub struct Writer<N>(N);
203
204impl<N: Native> key::Write<Reader<N>> for Writer<N> {
205    type Len = Bit;
206
207    #[inline]
208    fn new(prefix: Reader<N>, edge: ribbit::Packed<edge::Be>) -> (Self, Self::Len) {
209        let len = prefix.len() + edge.len().into();
210
211        validate!(len.0 <= N::BITS);
212
213        let writer = Self(
214            prefix.buffer.most_significant(prefix.len.0)
215                | N::from_most_significant_u64(edge.raw()).unbounded_shr(prefix.len.0),
216        );
217
218        (writer, len)
219    }
220
221    #[inline]
222    fn replace(&mut self, start: Self::Len, node: u8, edge: ribbit::Packed<edge::Be>) -> Self::Len {
223        self.0 = self.0.most_significant(start.0)
224            | (N::from_u8(node) >> start.0)
225            | (N::from_most_significant_u64(edge.raw()).unbounded_shr(8 + start.0));
226
227        start + Bit::BYTE + edge.len().into()
228    }
229}
230
231impl<N: Native> core::fmt::Debug for Writer<N> {
232    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
233        self.0
234            .with_be_bytes(|bytes| f.debug_list().entries(bytes).finish())
235    }
236}
237
238/// Abstraction over unsigned native integer types.
239pub(crate) trait Native:
240    'static
241    + Sized
242    + Copy
243    + Default
244    + core::fmt::Debug
245    + Ord
246    + Eq
247    + core::ops::Shl<u8, Output = Self>
248    + core::ops::ShlAssign<u8>
249    + core::ops::Shr<u8, Output = Self>
250    + core::ops::BitXor<Output = Self>
251    + core::ops::BitOr<Output = Self>
252    + core::ops::BitOrAssign
253    + core::ops::Not<Output = Self>
254    + core::ops::BitAnd<Output = Self>
255{
256    const MAX: Self;
257    const BITS: u8;
258
259    fn from_be_bytes(bytes: &[u8]) -> Self;
260
261    fn with_be_bytes<F: FnOnce(&[u8]) -> T, T>(self, apply: F) -> T;
262
263    fn most_significant_u64(self) -> u64;
264
265    fn get_u8(self, bits: u8) -> u8;
266
267    #[inline]
268    fn most_significant(self, bits: u8) -> Self {
269        Self::MAX.unbounded_shr(bits).not().bitand(self)
270    }
271
272    fn unbounded_shl(self, bits: u8) -> Self;
273    fn unbounded_shr(self, bits: u8) -> Self;
274    fn leading_zeros(self) -> u8;
275
276    fn from_most_significant_u64(value: u64) -> Self;
277    fn from_u8(value: u8) -> Self;
278
279    fn least_significant_u8(self) -> u8;
280}
281
282macro_rules! impl_native {
283    ($($ty:ty: $bits:expr, $into_u64:expr, $from_u64:expr, $into_u128:expr),* $(,)?) => {
284        $(
285            impl Native for $ty {
286                const MAX: Self = <$ty>::MAX;
287                const BITS: u8 = <$ty>::BITS as u8;
288
289                #[inline]
290                fn from_be_bytes(bytes: &[u8]) -> Self {
291                    Self::from_be_bytes(core::array::from_fn(|i| bytes.get(i).copied().unwrap_or(0)))
292                }
293
294                #[inline]
295                fn with_be_bytes<F: FnOnce(&[u8]) -> T, T>(self, apply: F) -> T {
296                    apply(&self.to_be_bytes())
297                }
298
299                #[inline]
300                fn most_significant_u64(self) -> u64 {
301                    $into_u64(self)
302                }
303
304                #[inline]
305                fn get_u8(self, bits: u8) -> u8 {
306                    <$ty>::rotate_left(self, 8 + bits as u32) as u8
307                }
308
309                #[inline]
310                fn unbounded_shl(self, bits: u8) -> Self {
311                    <$ty>::unbounded_shl(self, bits as u32)
312                }
313
314                #[inline]
315                fn unbounded_shr(self, bits: u8) -> Self {
316                    <$ty>::unbounded_shr(self, bits as u32)
317                }
318
319                #[inline]
320                fn leading_zeros(self) -> u8 {
321                    <$ty>::leading_zeros(self) as u8
322                }
323
324                #[inline]
325                fn from_most_significant_u64(value: u64) -> Self {
326                    $from_u64(value)
327                }
328
329                #[inline]
330                fn from_u8(value: u8) -> Self {
331                    (value as $ty).rotate_right(8)
332                }
333
334                #[inline]
335                fn least_significant_u8(self) -> u8 {
336                    self as u8
337                }
338            }
339        )*
340    };
341}
342
343impl_native!(
344    u16: 16, |from: Self| {
345        (from as u64) << 48
346    }, |into: u64| {
347        (into >> 48) as Self
348    }, |from: Self| {
349        (from as u128) << 112
350    },
351
352    u32: 32, |from: Self| {
353        (from as u64) << 32
354    }, |into: u64| {
355        (into >> 32) as Self
356    }, |from: Self| {
357        (from as u128) << 96
358    },
359
360    u64: 64, core::convert::identity, core::convert::identity, |from: Self| {
361        (from as u128) << 64
362    },
363
364    u128: 128, |into: u128| {
365        (into >> 64) as u64
366    }, |from: u64| {
367        (from as u128) << 64
368    }, core::convert::identity,
369);