arctic/raw/key/sized/
unsigned.rs1use 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 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
238pub(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);