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 for item in *self {
26 state.write_u8(*item);
27 }
28 }
29}
30
31impl<const N: usize> KeyBase for [u8; N] {
32 fn len(&self) -> usize {
33 N
34 }
35
36 fn is_empty(&self) -> bool {
37 N > 0
38 }
39
40 fn hash<H: Hasher>(&self, state: &mut H) {
41 for item in self {
42 state.write_u8(*item);
43 }
44 }
45}
46
47impl KeyBase for Vec<u8> {
48 fn len(&self) -> usize {
49 self.len()
50 }
51
52 fn is_empty(&self) -> bool {
53 self.is_empty()
54 }
55
56 fn hash<H: Hasher>(&self, state: &mut H) {
57 for item in self {
58 state.write_u8(*item);
59 }
60 }
61}
62
63impl KeyBase for u8 {
64 fn len(&self) -> usize {
65 1
66 }
67
68 fn is_empty(&self) -> bool {
69 false
70 }
71
72 fn hash<H: Hasher>(&self, state: &mut H) {
73 state.write_u8(*self);
74 }
75}
76
77impl<A: KeyBase, B: KeyBase> KeyBase for (A, B) {
78 fn len(&self) -> usize {
79 let (a, b) = self;
80 a.len() + b.len()
81 }
82
83 fn is_empty(&self) -> bool {
84 let (a, b) = self;
85 a.is_empty() && b.is_empty()
86 }
87
88 fn hash<H: Hasher>(&self, state: &mut H) {
89 let (a, b) = self;
90 KeyBase::hash(a, state);
91 KeyBase::hash(b, state);
92 }
93}
94
95impl<T: KeyBase> KeyBase for &'_ T {
96 fn len(&self) -> usize {
97 (*self).len()
98 }
99
100 fn is_empty(&self) -> bool {
101 (*self).is_empty()
102 }
103
104 fn hash<H: Hasher>(&self, state: &mut H) {
105 (*self).hash(state)
106 }
107}
108
109pub trait QueryKey: KeyBase {
112 fn cmp(&self, key: &[u8]) -> std::cmp::Ordering;
113}
114
115impl QueryKey for &'_ [u8] {
116 fn cmp(&self, key: &[u8]) -> std::cmp::Ordering {
117 Ord::cmp(self, &key)
118 }
119}
120
121impl<const N: usize> QueryKey for [u8; N] {
122 fn cmp(&self, key: &[u8]) -> std::cmp::Ordering {
123 Ord::cmp(&self[..], key)
124 }
125}
126
127impl QueryKey for Vec<u8> {
128 fn cmp(&self, key: &[u8]) -> std::cmp::Ordering {
129 Ord::cmp(&**self, key)
130 }
131}
132
133impl QueryKey for u8 {
134 fn cmp(&self, key: &[u8]) -> std::cmp::Ordering {
135 Ord::cmp(&[*self][..], key)
136 }
137}
138
139impl<A: QueryKey, B: QueryKey> QueryKey for (A, B) {
140 fn cmp(&self, mut key: &[u8]) -> std::cmp::Ordering {
141 let (a, b) = self;
142 let len = a.len();
143 let key_len = key.len();
144 let key_part = &key[..min(key_len, len)];
145 match a.cmp(key_part) {
146 std::cmp::Ordering::Equal => {
147 key = &key[len..];
148 b.cmp(key)
149 }
150 ord => ord,
151 }
152 }
153}
154
155impl<T: QueryKey> QueryKey for &'_ T {
156 fn cmp(&self, key: &[u8]) -> std::cmp::Ordering {
157 (*self).cmp(key)
158 }
159}
160
161pub trait StoreKey: KeyBase + Ord {
163 fn write_to(&self, buf: &mut Vec<u8>);
164}
165
166impl<const N: usize> StoreKey for [u8; N] {
167 fn write_to(&self, buf: &mut Vec<u8>) {
168 buf.extend_from_slice(&self[..]);
169 }
170}
171
172impl StoreKey for Vec<u8> {
173 fn write_to(&self, buf: &mut Vec<u8>) {
174 buf.extend_from_slice(self);
175 }
176}
177
178impl StoreKey for &'_ [u8] {
179 fn write_to(&self, buf: &mut Vec<u8>) {
180 buf.extend_from_slice(self);
181 }
182}
183
184impl StoreKey for u8 {
185 fn write_to(&self, buf: &mut Vec<u8>) {
186 buf.push(*self);
187 }
188}
189
190impl<A: StoreKey, B: StoreKey> StoreKey for (A, B) {
191 fn write_to(&self, buf: &mut Vec<u8>) {
192 self.0.write_to(buf);
193 self.1.write_to(buf);
194 }
195}
196
197impl<T: StoreKey> StoreKey for &'_ T {
198 fn write_to(&self, buf: &mut Vec<u8>) {
199 (*self).write_to(buf);
200 }
201}
202
203pub fn hash_key(key: &impl KeyBase) -> u64 {
205 let mut hasher = twox_hash::XxHash64::with_seed(0);
206 key.hash(&mut hasher);
207 hasher.finish()
208}
209
210#[cfg(test)]
211mod tests {
212 use std::cmp::Ordering;
213
214 use crate::{QueryKey, key::hash_key};
215
216 #[test]
217 fn tuple() {
218 let key = (&[1, 2], &[3, 4]);
219 assert_eq!(QueryKey::cmp(&key, &[1, 2, 3, 4]), Ordering::Equal);
220 assert_eq!(QueryKey::cmp(&key, &[1, 2, 3, 3]), Ordering::Greater);
221 assert_eq!(QueryKey::cmp(&key, &[1, 2, 3, 5]), Ordering::Less);
222 assert_eq!(QueryKey::cmp(&key, &[0, 2, 3, 4]), Ordering::Greater);
223 assert_eq!(QueryKey::cmp(&key, &[2, 2, 3, 4]), Ordering::Less);
224 assert_eq!(QueryKey::cmp(&key, &[1, 2, 3, 4, 5]), Ordering::Less);
225 assert_eq!(QueryKey::cmp(&key, &[1, 2, 3]), Ordering::Greater);
226 assert_eq!(QueryKey::cmp(&key, &[1, 2]), Ordering::Greater);
227 assert_eq!(QueryKey::cmp(&key, &[1]), Ordering::Greater);
228 assert_eq!(QueryKey::cmp(&key, &[]), Ordering::Greater);
229 }
230
231 #[test]
232 fn hash() {
233 let h1 = hash_key(&[1, 2, 3, 4]);
234 let h2 = hash_key(&(&[1, 2], &[3, 4]));
235 let h3 = hash_key(&(vec![1, 2, 3], 4u8));
236 assert_eq!(h2, h1);
237 assert_eq!(h3, h1);
238 }
239}