1use std::{cmp::min, hash::Hasher};
2
3pub trait KeyBase {
5 fn len(&self) -> usize;
7 fn is_empty(&self) -> bool {
8 self.len() == 0
9 }
10 fn hash<H: Hasher>(&self, state: &mut H);
13}
14
15impl KeyBase for &'_ [u8] {
16 fn len(&self) -> usize {
17 <[u8]>::len(self)
18 }
19
20 fn is_empty(&self) -> bool {
21 <[u8]>::is_empty(self)
22 }
23
24 fn hash<H: Hasher>(&self, state: &mut H) {
25 state.write(self);
26 }
27}
28
29impl<const N: usize> KeyBase for [u8; N] {
30 fn len(&self) -> usize {
31 N
32 }
33
34 fn is_empty(&self) -> bool {
35 N > 0
36 }
37
38 fn hash<H: Hasher>(&self, state: &mut H) {
39 state.write(self);
40 }
41}
42
43impl KeyBase for Vec<u8> {
44 fn len(&self) -> usize {
45 self.len()
46 }
47
48 fn is_empty(&self) -> bool {
49 self.is_empty()
50 }
51
52 fn hash<H: Hasher>(&self, state: &mut H) {
53 state.write(self);
54 }
55}
56
57impl KeyBase for Box<[u8]> {
58 fn len(&self) -> usize {
59 (**self).len()
60 }
61
62 fn is_empty(&self) -> bool {
63 (**self).is_empty()
64 }
65
66 fn hash<H: Hasher>(&self, state: &mut H) {
67 state.write(self);
68 }
69}
70
71impl KeyBase for u8 {
72 fn len(&self) -> usize {
73 1
74 }
75
76 fn is_empty(&self) -> bool {
77 false
78 }
79
80 fn hash<H: Hasher>(&self, state: &mut H) {
81 state.write_u8(*self);
82 }
83}
84
85impl<A: KeyBase, B: KeyBase> KeyBase for (A, B) {
86 fn len(&self) -> usize {
87 let (a, b) = self;
88 a.len() + b.len()
89 }
90
91 fn is_empty(&self) -> bool {
92 let (a, b) = self;
93 a.is_empty() && b.is_empty()
94 }
95
96 fn hash<H: Hasher>(&self, state: &mut H) {
97 let (a, b) = self;
98 KeyBase::hash(a, state);
99 KeyBase::hash(b, state);
100 }
101}
102
103impl<T: KeyBase> KeyBase for &'_ T {
104 fn len(&self) -> usize {
105 (*self).len()
106 }
107
108 fn is_empty(&self) -> bool {
109 (*self).is_empty()
110 }
111
112 fn hash<H: Hasher>(&self, state: &mut H) {
113 (*self).hash(state)
114 }
115}
116
117pub trait QueryKey: KeyBase {
120 fn cmp(&self, key: &[u8]) -> std::cmp::Ordering;
121 fn eq(&self, key: &[u8]) -> bool;
122}
123
124impl QueryKey for &'_ [u8] {
125 fn cmp(&self, key: &[u8]) -> std::cmp::Ordering {
126 Ord::cmp(self, &key)
127 }
128
129 fn eq(&self, key: &[u8]) -> bool {
130 PartialEq::eq(*self, key)
131 }
132}
133
134impl<const N: usize> QueryKey for [u8; N] {
135 fn cmp(&self, key: &[u8]) -> std::cmp::Ordering {
136 Ord::cmp(&self[..], key)
137 }
138 fn eq(&self, key: &[u8]) -> bool {
139 PartialEq::eq(self, key)
140 }
141}
142
143impl QueryKey for Vec<u8> {
144 fn cmp(&self, key: &[u8]) -> std::cmp::Ordering {
145 Ord::cmp(&**self, key)
146 }
147 fn eq(&self, key: &[u8]) -> bool {
148 PartialEq::eq(self.as_slice(), key)
149 }
150}
151
152impl QueryKey for Box<[u8]> {
153 fn cmp(&self, key: &[u8]) -> std::cmp::Ordering {
154 Ord::cmp(&**self, key)
155 }
156 fn eq(&self, key: &[u8]) -> bool {
157 PartialEq::eq(&**self, key)
158 }
159}
160
161impl QueryKey for u8 {
162 fn cmp(&self, key: &[u8]) -> std::cmp::Ordering {
163 Ord::cmp(&[*self][..], key)
164 }
165 fn eq(&self, key: &[u8]) -> bool {
166 PartialEq::eq(&[*self][..], key)
167 }
168}
169
170impl<A: QueryKey, B: QueryKey> QueryKey for (A, B) {
171 fn cmp(&self, key: &[u8]) -> std::cmp::Ordering {
172 let (a, b) = self;
173 let len = a.len();
174 let key_len = key.len();
175 let (key_part, value_part) = key.split_at(min(key_len, len));
176 a.cmp(key_part).then_with(|| b.cmp(value_part))
177 }
178 fn eq(&self, key: &[u8]) -> bool {
179 let (a, b) = self;
180 let len = a.len();
181 let key_len = key.len();
182 let (key_part, value_part) = &key.split_at(min(key_len, len));
183 a.eq(key_part) && b.eq(value_part)
184 }
185}
186
187impl<T: QueryKey> QueryKey for &'_ T {
188 fn cmp(&self, key: &[u8]) -> std::cmp::Ordering {
189 (*self).cmp(key)
190 }
191 fn eq(&self, key: &[u8]) -> bool {
192 (*self).eq(key)
193 }
194}
195
196pub trait StoreKey: KeyBase + Ord {
198 fn as_slice(&self) -> &[u8];
200
201 fn write_to(&self, buf: &mut Vec<u8>) {
202 buf.extend_from_slice(self.as_slice());
203 }
204}
205
206impl<const N: usize> StoreKey for [u8; N] {
207 fn as_slice(&self) -> &[u8] {
208 &self[..]
209 }
210}
211
212impl StoreKey for Vec<u8> {
213 fn as_slice(&self) -> &[u8] {
214 self
215 }
216}
217
218impl StoreKey for Box<[u8]> {
219 fn as_slice(&self) -> &[u8] {
220 self
221 }
222}
223
224impl StoreKey for &'_ [u8] {
225 fn as_slice(&self) -> &[u8] {
226 self
227 }
228}
229
230impl<T: StoreKey> StoreKey for &'_ T {
231 fn as_slice(&self) -> &[u8] {
232 (*self).as_slice()
233 }
234}
235
236pub fn hash_key(key: &impl KeyBase) -> u64 {
238 let mut hasher = xxhash_rust::xxh3::Xxh3Default::new();
239 key.hash(&mut hasher);
240 hasher.finish()
241}
242
243#[cfg(test)]
244mod tests {
245 use std::cmp::Ordering;
246
247 use crate::{QueryKey, key::hash_key};
248
249 #[test]
250 fn tuple() {
251 let key = (&[1, 2], &[3, 4]);
252 assert_eq!(QueryKey::cmp(&key, &[1, 2, 3, 4]), Ordering::Equal);
253 assert_eq!(QueryKey::cmp(&key, &[1, 2, 3, 3]), Ordering::Greater);
254 assert_eq!(QueryKey::cmp(&key, &[1, 2, 3, 5]), Ordering::Less);
255 assert_eq!(QueryKey::cmp(&key, &[0, 2, 3, 4]), Ordering::Greater);
256 assert_eq!(QueryKey::cmp(&key, &[2, 2, 3, 4]), Ordering::Less);
257 assert_eq!(QueryKey::cmp(&key, &[1, 2, 3, 4, 5]), Ordering::Less);
258 assert_eq!(QueryKey::cmp(&key, &[1, 2, 3]), Ordering::Greater);
259 assert_eq!(QueryKey::cmp(&key, &[1, 2]), Ordering::Greater);
260 assert_eq!(QueryKey::cmp(&key, &[1]), Ordering::Greater);
261 assert_eq!(QueryKey::cmp(&key, &[]), Ordering::Greater);
262 }
263
264 #[test]
265 fn hash() {
266 let h1 = hash_key(&[1, 2, 3, 4]);
267 let h2 = hash_key(&(&[1, 2], &[3, 4]));
268 let h3 = hash_key(&(vec![1, 2, 3], 4u8));
269 assert_eq!(h2, h1);
270 assert_eq!(h3, h1);
271 }
272}