1use core::sync::atomic;
2use core::sync::atomic::Ordering::{Acquire, Relaxed, Release};
3use siphasher::sip128::SipHasher24;
4use std::alloc::*;
5use std::ptr::addr_of;
6
7use super::*;
8
9#[derive(Debug)]
10#[repr(C)]
11pub(crate) struct Leaf<const KEY_LEN: usize> {
12 pub key: [u8; KEY_LEN],
13 pub hash: u128,
14 rc: atomic::AtomicU32,
15}
16
17impl<const KEY_LEN: usize> Body for Leaf<KEY_LEN> {
18 fn tag(_body: NonNull<Self>) -> HeadTag {
19 HeadTag::Leaf
20 }
21}
22
23impl<const KEY_LEN: usize> Leaf<KEY_LEN> {
24 pub(super) unsafe fn new(key: &[u8; KEY_LEN]) -> NonNull<Self> {
25 unsafe {
26 let layout = Layout::new::<Self>();
27 if let Some(ptr) = NonNull::new(alloc(layout) as *mut Self) {
28 let hash = SipHasher24::new_with_key(&*addr_of!(SIP_KEY))
29 .hash(&key[..])
30 .into();
31
32 ptr.write(Self {
33 key: *key,
34 hash,
35 rc: atomic::AtomicU32::new(1),
36 });
37
38 ptr
39 } else {
40 panic!("Allocation failed!");
41 }
42 }
43 }
44
45 pub(crate) unsafe fn rc_inc(leaf: NonNull<Self>) -> NonNull<Self> {
46 unsafe {
47 let leaf = leaf.as_ptr();
48 let mut current = (*leaf).rc.load(Relaxed);
49 loop {
50 if current == u32::MAX {
51 panic!("max refcount exceeded");
52 }
53 match (*leaf)
54 .rc
55 .compare_exchange(current, current + 1, Relaxed, Relaxed)
56 {
57 Ok(_) => return NonNull::new_unchecked(leaf),
58 Err(v) => current = v,
59 }
60 }
61 }
62 }
63
64 pub(crate) unsafe fn rc_dec(leaf: NonNull<Self>) {
65 unsafe {
66 let ptr = leaf.as_ptr();
67 let rc = (*ptr).rc.fetch_sub(1, Release);
68 if rc != 1 {
69 return;
70 }
71 (*ptr).rc.load(Acquire);
72
73 std::ptr::drop_in_place(ptr);
74
75 let layout = Layout::new::<Self>();
76 let ptr = ptr as *mut u8;
77 dealloc(ptr, layout);
78 }
79 }
80
81 pub(crate) fn infixes<
82 const PREFIX_LEN: usize,
83 const INFIX_LEN: usize,
84 O: KeyOrdering<KEY_LEN>,
85 S: KeySegmentation<KEY_LEN>,
86 F,
87 >(
88 leaf: NonNull<Self>,
89 prefix: &[u8; PREFIX_LEN],
90 at_depth: usize,
91 f: &mut F,
92 ) where
93 F: FnMut(&[u8; INFIX_LEN]),
94 {
95 let leaf = unsafe { leaf.as_ref() };
96 let leaf_key = (*leaf).key;
97 for depth in at_depth..PREFIX_LEN {
98 if leaf_key[O::key_index(depth)] != prefix[depth] {
99 return;
100 }
101 }
102
103 let infix: [u8; INFIX_LEN] =
104 core::array::from_fn(|i| (*leaf).key[O::key_index(PREFIX_LEN + i)]);
105 f(&infix);
106 }
107
108 pub(crate) fn has_prefix<O: KeyOrdering<KEY_LEN>, const PREFIX_LEN: usize>(
109 leaf: NonNull<Self>,
110 at_depth: usize,
111 prefix: &[u8; PREFIX_LEN],
112 ) -> bool {
113 let leaf_key: &[u8; KEY_LEN] = unsafe { &(*leaf.as_ptr()).key };
114 for depth in at_depth..PREFIX_LEN {
115 if leaf_key[O::key_index(depth)] != prefix[depth] {
116 return false;
117 }
118 }
119 return true;
120 }
121
122 pub(crate) fn segmented_len<O: KeyOrdering<KEY_LEN>, const PREFIX_LEN: usize>(
123 leaf: NonNull<Self>,
124 at_depth: usize,
125 prefix: &[u8; PREFIX_LEN],
126 ) -> u64 {
127 let leaf_key: &[u8; KEY_LEN] = unsafe { &(*leaf.as_ptr()).key };
128 for depth in at_depth..PREFIX_LEN {
129 let key_depth = O::key_index(depth);
130 if leaf_key[key_depth] != prefix[depth] {
131 return 0;
132 }
133 }
134 return 1;
135 }
136}