uv_cache_key/
cache_key.rs1use std::borrow::Cow;
2use std::collections::{BTreeMap, BTreeSet};
3use std::hash::{Hash, Hasher};
4use std::num::{
5 NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroU8, NonZeroU16, NonZeroU32,
6 NonZeroU64, NonZeroU128,
7};
8use std::path::{Path, PathBuf};
9
10use seahash::SeaHasher;
11use url::Url;
12
13pub trait CacheKey {
16 fn cache_key(&self, state: &mut CacheKeyHasher);
17
18 fn cache_key_slice(data: &[Self], state: &mut CacheKeyHasher)
19 where
20 Self: Sized,
21 {
22 for piece in data {
23 piece.cache_key(state);
24 }
25 }
26}
27
28impl CacheKey for bool {
29 #[inline]
30 fn cache_key(&self, state: &mut CacheKeyHasher) {
31 state.write_u8(u8::from(*self));
32 }
33}
34
35impl CacheKey for char {
36 #[inline]
37 fn cache_key(&self, state: &mut CacheKeyHasher) {
38 state.write_u32(*self as u32);
39 }
40}
41
42impl CacheKey for usize {
43 #[inline]
44 fn cache_key(&self, state: &mut CacheKeyHasher) {
45 state.write_usize(*self);
46 }
47}
48
49impl CacheKey for u128 {
50 #[inline]
51 fn cache_key(&self, state: &mut CacheKeyHasher) {
52 state.write_u128(*self);
53 }
54}
55
56impl CacheKey for u64 {
57 #[inline]
58 fn cache_key(&self, state: &mut CacheKeyHasher) {
59 state.write_u64(*self);
60 }
61}
62
63impl CacheKey for u32 {
64 #[inline]
65 fn cache_key(&self, state: &mut CacheKeyHasher) {
66 state.write_u32(*self);
67 }
68}
69
70impl CacheKey for u16 {
71 #[inline]
72 fn cache_key(&self, state: &mut CacheKeyHasher) {
73 state.write_u16(*self);
74 }
75}
76
77impl CacheKey for u8 {
78 #[inline]
79 fn cache_key(&self, state: &mut CacheKeyHasher) {
80 state.write_u8(*self);
81 }
82}
83
84impl CacheKey for isize {
85 #[inline]
86 fn cache_key(&self, state: &mut CacheKeyHasher) {
87 state.write_isize(*self);
88 }
89}
90
91impl CacheKey for i128 {
92 #[inline]
93 fn cache_key(&self, state: &mut CacheKeyHasher) {
94 state.write_i128(*self);
95 }
96}
97
98impl CacheKey for i64 {
99 #[inline]
100 fn cache_key(&self, state: &mut CacheKeyHasher) {
101 state.write_i64(*self);
102 }
103}
104
105impl CacheKey for i32 {
106 #[inline]
107 fn cache_key(&self, state: &mut CacheKeyHasher) {
108 state.write_i32(*self);
109 }
110}
111
112impl CacheKey for i16 {
113 #[inline]
114 fn cache_key(&self, state: &mut CacheKeyHasher) {
115 state.write_i16(*self);
116 }
117}
118
119impl CacheKey for i8 {
120 #[inline]
121 fn cache_key(&self, state: &mut CacheKeyHasher) {
122 state.write_i8(*self);
123 }
124}
125macro_rules! impl_cache_key_non_zero {
126 ($name:ident) => {
127 impl CacheKey for $name {
128 #[inline]
129 fn cache_key(&self, state: &mut CacheKeyHasher) {
130 self.get().cache_key(state)
131 }
132 }
133 };
134}
135
136impl_cache_key_non_zero!(NonZeroU8);
137impl_cache_key_non_zero!(NonZeroU16);
138impl_cache_key_non_zero!(NonZeroU32);
139impl_cache_key_non_zero!(NonZeroU64);
140impl_cache_key_non_zero!(NonZeroU128);
141
142impl_cache_key_non_zero!(NonZeroI8);
143impl_cache_key_non_zero!(NonZeroI16);
144impl_cache_key_non_zero!(NonZeroI32);
145impl_cache_key_non_zero!(NonZeroI64);
146impl_cache_key_non_zero!(NonZeroI128);
147
148macro_rules! impl_cache_key_tuple {
149 () => (
150 impl CacheKey for () {
151 #[inline]
152 fn cache_key(&self, _state: &mut CacheKeyHasher) {}
153 }
154 );
155
156 ( $($name:ident)+) => (
157 impl<$($name: CacheKey),+> CacheKey for ($($name,)+) where last_type!($($name,)+): ?Sized {
158 #[allow(non_snake_case)]
159 #[inline]
160 fn cache_key(&self, state: &mut CacheKeyHasher) {
161 let ($(ref $name,)+) = *self;
162 $($name.cache_key(state);)+
163 }
164 }
165 );
166}
167
168macro_rules! last_type {
169 ($a:ident,) => { $a };
170 ($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) };
171}
172
173impl_cache_key_tuple! {}
174impl_cache_key_tuple! { T }
175impl_cache_key_tuple! { T B }
176impl_cache_key_tuple! { T B C }
177impl_cache_key_tuple! { T B C D }
178impl_cache_key_tuple! { T B C D E }
179impl_cache_key_tuple! { T B C D E F }
180impl_cache_key_tuple! { T B C D E F G }
181impl_cache_key_tuple! { T B C D E F G H }
182impl_cache_key_tuple! { T B C D E F G H I }
183impl_cache_key_tuple! { T B C D E F G H I J }
184impl_cache_key_tuple! { T B C D E F G H I J K }
185impl_cache_key_tuple! { T B C D E F G H I J K L }
186
187impl CacheKey for str {
188 #[inline]
189 fn cache_key(&self, state: &mut CacheKeyHasher) {
190 self.hash(&mut *state);
191 }
192}
193
194impl CacheKey for String {
195 #[inline]
196 fn cache_key(&self, state: &mut CacheKeyHasher) {
197 self.hash(&mut *state);
198 }
199}
200
201impl CacheKey for Path {
202 #[inline]
203 fn cache_key(&self, state: &mut CacheKeyHasher) {
204 self.hash(&mut *state);
205 }
206}
207
208impl CacheKey for PathBuf {
209 #[inline]
210 fn cache_key(&self, state: &mut CacheKeyHasher) {
211 self.as_path().cache_key(state);
212 }
213}
214
215impl CacheKey for Url {
216 #[inline]
217 fn cache_key(&self, state: &mut CacheKeyHasher) {
218 self.as_str().cache_key(state);
219 }
220}
221
222impl<T: CacheKey> CacheKey for Option<T> {
223 #[inline]
224 fn cache_key(&self, state: &mut CacheKeyHasher) {
225 match self {
226 None => state.write_usize(0),
227 Some(value) => {
228 state.write_usize(1);
229 value.cache_key(state);
230 }
231 }
232 }
233}
234
235impl<T: CacheKey> CacheKey for [T] {
236 #[inline]
237 fn cache_key(&self, state: &mut CacheKeyHasher) {
238 state.write_usize(self.len());
239 CacheKey::cache_key_slice(self, state);
240 }
241}
242
243impl<T: ?Sized + CacheKey> CacheKey for &T {
244 #[inline]
245 fn cache_key(&self, state: &mut CacheKeyHasher) {
246 (**self).cache_key(state);
247 }
248}
249
250impl<T: ?Sized + CacheKey> CacheKey for &mut T {
251 #[inline]
252 fn cache_key(&self, state: &mut CacheKeyHasher) {
253 (**self).cache_key(state);
254 }
255}
256
257impl<T> CacheKey for Vec<T>
258where
259 T: CacheKey,
260{
261 fn cache_key(&self, state: &mut CacheKeyHasher) {
262 state.write_usize(self.len());
263 CacheKey::cache_key_slice(self, state);
264 }
265}
266
267impl<V: CacheKey> CacheKey for BTreeSet<V> {
268 fn cache_key(&self, state: &mut CacheKeyHasher) {
269 state.write_usize(self.len());
270 for item in self {
271 item.cache_key(state);
272 }
273 }
274}
275
276impl<K: CacheKey + Ord, V: CacheKey> CacheKey for BTreeMap<K, V> {
277 fn cache_key(&self, state: &mut CacheKeyHasher) {
278 state.write_usize(self.len());
279
280 for (key, value) in self {
281 key.cache_key(state);
282 value.cache_key(state);
283 }
284 }
285}
286
287impl<V: ?Sized> CacheKey for Cow<'_, V>
288where
289 V: CacheKey + ToOwned,
290{
291 fn cache_key(&self, state: &mut CacheKeyHasher) {
292 (**self).cache_key(state);
293 }
294}
295
296#[derive(Clone, Default)]
297pub struct CacheKeyHasher {
298 inner: SeaHasher,
299}
300
301impl CacheKeyHasher {
302 pub fn new() -> Self {
303 Self {
304 inner: SeaHasher::new(),
305 }
306 }
307}
308
309impl Hasher for CacheKeyHasher {
310 #[inline]
311 fn finish(&self) -> u64 {
312 self.inner.finish()
313 }
314
315 #[inline]
316 fn write(&mut self, bytes: &[u8]) {
317 self.inner.write(bytes);
318 }
319
320 #[inline]
321 fn write_u8(&mut self, i: u8) {
322 self.inner.write_u8(i);
323 }
324
325 #[inline]
326 fn write_u16(&mut self, i: u16) {
327 self.inner.write_u16(i);
328 }
329
330 #[inline]
331 fn write_u32(&mut self, i: u32) {
332 self.inner.write_u32(i);
333 }
334
335 #[inline]
336 fn write_u64(&mut self, i: u64) {
337 self.inner.write_u64(i);
338 }
339
340 #[inline]
341 fn write_u128(&mut self, i: u128) {
342 self.inner.write_u128(i);
343 }
344
345 #[inline]
346 fn write_usize(&mut self, i: usize) {
347 self.inner.write_usize(i);
348 }
349
350 #[inline]
351 fn write_i8(&mut self, i: i8) {
352 self.inner.write_i8(i);
353 }
354
355 #[inline]
356 fn write_i16(&mut self, i: i16) {
357 self.inner.write_i16(i);
358 }
359
360 #[inline]
361 fn write_i32(&mut self, i: i32) {
362 self.inner.write_i32(i);
363 }
364
365 #[inline]
366 fn write_i64(&mut self, i: i64) {
367 self.inner.write_i64(i);
368 }
369
370 #[inline]
371 fn write_i128(&mut self, i: i128) {
372 self.inner.write_i128(i);
373 }
374
375 #[inline]
376 fn write_isize(&mut self, i: isize) {
377 self.inner.write_isize(i);
378 }
379}