1#![deny(missing_docs)]
6#![allow(clippy::too_many_arguments, clippy::type_complexity)]
7#![cfg_attr(docsrs, feature(doc_cfg))]
8#![cfg_attr(docsrs, allow(unused_attributes))]
9mod bbloom;
10mod cache;
11mod error;
12mod histogram;
13mod metrics;
14#[allow(dead_code)]
23mod policy;
24mod ring;
25mod sketch;
26mod store;
27mod ttl;
28pub(crate) mod utils;
29
30extern crate atomic;
31
32#[cfg(feature = "log")]
33extern crate log;
34
35#[cfg(feature = "serde")]
36extern crate serde;
37
38#[cfg(feature = "async")]
39#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
40pub(crate) mod axync {
41 pub(crate) use async_channel::{bounded, unbounded, Receiver, RecvError, Sender};
42 pub(crate) use futures::select;
43 pub(crate) type WaitGroup = wg::AsyncWaitGroup;
44 pub(crate) fn stop_channel() -> (Sender<()>, Receiver<()>) {
45 bounded(1)
46 }
47}
48#[cfg(feature = "async")]
49#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
50pub use cache::{AsyncCache, AsyncCacheBuilder};
51
52#[cfg(feature = "sync")]
53#[cfg_attr(docsrs, doc(cfg(feature = "sync")))]
54pub(crate) mod sync {
55 pub(crate) use crossbeam_channel::{bounded, select, unbounded, Receiver, Sender};
56 pub(crate) use std::thread::{spawn, JoinHandle};
57 pub(crate) use std::time::Instant;
58
59 pub(crate) type UnboundedSender<T> = Sender<T>;
60 pub(crate) type UnboundedReceiver<T> = Receiver<T>;
61 pub(crate) type WaitGroup = wg::WaitGroup;
62
63 pub(crate) fn stop_channel() -> (Sender<()>, Receiver<()>) {
64 bounded(0)
65 }
66}
67
68#[cfg(feature = "sync")]
69#[cfg_attr(docsrs, doc(cfg(feature = "sync")))]
70pub use cache::{Cache, CacheBuilder};
71
72pub use error::CacheError;
73pub use histogram::Histogram;
74pub use metrics::{MetricType, Metrics};
75pub use utils::{ValueRef, ValueRefMut};
76
77use crate::ttl::Time;
78use seahash::SeaHasher;
79use std::fmt::{Debug, Formatter};
80use std::hash::{BuildHasher, BuildHasherDefault, Hash, Hasher};
81use std::marker::PhantomData;
82
83pub struct Item<V> {
85 pub val: Option<V>,
87
88 pub index: u64,
92
93 pub conflict: u64,
97
98 pub cost: i64,
100
101 pub exp: Time,
103}
104
105impl<V> Item<V> {
106 pub(crate) fn new(index: u64, conflict: u64, cost: i64, val: Option<V>, ttl: Time) -> Self {
107 Self {
108 val,
109 index,
110 conflict,
111 cost,
112 exp: ttl,
113 }
114 }
115}
116
117impl<V: Clone> Clone for Item<V> {
118 fn clone(&self) -> Self {
119 Self {
120 val: self.val.clone(),
121 index: self.index,
122 conflict: self.conflict,
123 cost: self.cost,
124 exp: self.exp,
125 }
126 }
127}
128
129impl<V: Copy> Copy for Item<V> {}
130
131impl<V: Debug> Debug for Item<V> {
132 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
133 f.debug_struct("Item")
134 .field("value", &self.val)
135 .field("cost", &self.cost)
136 .field("ttl", &self.exp)
137 .finish()
138 }
139}
140
141pub trait UpdateValidator: Send + Sync + 'static {
144 type Value: Send + Sync + 'static;
146
147 fn should_update(&self, prev: &Self::Value, curr: &Self::Value) -> bool;
149}
150
151#[doc(hidden)]
153pub struct DefaultUpdateValidator<V> {
154 _marker: PhantomData<fn(V)>,
155}
156
157impl<V: Send + Sync> Default for DefaultUpdateValidator<V> {
158 fn default() -> Self {
159 Self {
160 _marker: PhantomData::<fn(V)>,
161 }
162 }
163}
164
165impl<V: Send + Sync + 'static> UpdateValidator for DefaultUpdateValidator<V> {
166 type Value = V;
167
168 #[inline]
169 fn should_update(&self, _prev: &Self::Value, _curr: &Self::Value) -> bool {
170 true
171 }
172}
173
174pub trait CacheCallback: Send + Sync + 'static {
176 type Value: Send + Sync + 'static;
178
179 fn on_exit(&self, val: Option<Self::Value>);
183
184 fn on_evict(&self, item: Item<Self::Value>) {
187 self.on_exit(item.val)
188 }
189
190 fn on_reject(&self, item: Item<Self::Value>) {
192 self.on_exit(item.val)
193 }
194}
195
196#[derive(Clone, Debug)]
198#[doc(hidden)]
199pub struct DefaultCacheCallback<V> {
200 _marker: PhantomData<V>,
201}
202
203impl<V> Default for DefaultCacheCallback<V> {
204 fn default() -> Self {
205 Self {
206 _marker: Default::default(),
207 }
208 }
209}
210
211impl<V: Send + Sync + 'static> CacheCallback for DefaultCacheCallback<V> {
212 type Value = V;
213
214 fn on_exit(&self, _val: Option<Self::Value>) {}
215}
216
217pub trait Coster: Send + Sync + 'static {
227 type Value: Send + Sync + 'static;
229
230 fn cost(&self, val: &Self::Value) -> i64;
234}
235
236#[doc(hidden)]
238pub struct DefaultCoster<V> {
239 _marker: PhantomData<fn(V)>,
240}
241
242impl<V> Default for DefaultCoster<V> {
243 fn default() -> Self {
244 Self {
245 _marker: Default::default(),
246 }
247 }
248}
249
250impl<V: Send + Sync + 'static> Coster for DefaultCoster<V> {
251 type Value = V;
252
253 #[inline]
254 fn cost(&self, _val: &V) -> i64 {
255 0
256 }
257}
258
259pub trait KeyBuilder {
274 type Key: Hash + Eq + ?Sized;
276
277 fn hash_index<Q>(&self, key: &Q) -> u64
279 where
280 Self::Key: core::borrow::Borrow<Q>,
281 Q: core::hash::Hash + Eq + ?Sized;
282
283 fn hash_conflict<Q>(&self, key: &Q) -> u64
286 where
287 Self::Key: core::borrow::Borrow<Q>,
288 Q: core::hash::Hash + Eq + ?Sized,
289 {
290 let _ = key;
291 0
292 }
293
294 fn build_key<Q>(&self, k: &Q) -> (u64, u64)
296 where
297 Self::Key: core::borrow::Borrow<Q>,
298 Q: core::hash::Hash + Eq + ?Sized,
299 {
300 (self.hash_index(k), self.hash_conflict(k))
301 }
302}
303
304pub struct DefaultKeyBuilder<K> {
315 xx: xxhash_rust::xxh64::Xxh64Builder,
316 sea: BuildHasherDefault<SeaHasher>,
317 _marker: PhantomData<K>,
318}
319
320impl<K> Debug for DefaultKeyBuilder<K> {
321 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
322 f.debug_struct("DefaultKeyBuilder").finish()
323 }
324}
325
326impl<K> Default for DefaultKeyBuilder<K> {
327 fn default() -> Self {
328 use rand::{thread_rng, Rng};
329 let mut rng = thread_rng();
330 let seed = rng.gen::<u64>();
331 Self {
332 xx: xxhash_rust::xxh64::Xxh64Builder::new(seed),
333 sea: Default::default(),
334 _marker: Default::default(),
335 }
336 }
337}
338
339impl<K: Hash + Eq> KeyBuilder for DefaultKeyBuilder<K> {
340 type Key = K;
341
342 #[inline]
343 fn hash_index<Q>(&self, key: &Q) -> u64
344 where
345 Self::Key: core::borrow::Borrow<Q>,
346 Q: core::hash::Hash + Eq + ?Sized,
347 {
348 self.sea.hash_one(key)
349 }
350
351 #[inline]
352 fn hash_conflict<Q>(&self, key: &Q) -> u64
353 where
354 Self::Key: core::borrow::Borrow<Q>,
355 Q: core::hash::Hash + Eq + ?Sized,
356 {
357 self.xx.hash_one(key)
358 }
359}
360
361#[derive(Default, Copy, Clone, Eq, PartialEq, Debug)]
363#[repr(transparent)]
364pub struct TransparentHasher {
365 data: u64,
366}
367
368impl Hasher for TransparentHasher {
369 #[inline]
370 fn finish(&self) -> u64 {
371 self.data
372 }
373
374 #[inline]
375 fn write(&mut self, bytes: &[u8]) {
376 let mut data = [0u8; core::mem::size_of::<u64>()];
377 if bytes.len() > core::mem::size_of::<u64>() {
378 data.copy_from_slice(&bytes[..core::mem::size_of::<u64>()]);
379 } else {
380 data[..bytes.len()].copy_from_slice(bytes);
381 }
382 self.data = u64::from_ne_bytes(data);
383 }
384
385 fn write_u8(&mut self, i: u8) {
386 self.data = i as u64;
387 }
388
389 fn write_u16(&mut self, i: u16) {
390 self.data = i as u64;
391 }
392
393 fn write_u32(&mut self, i: u32) {
394 self.data = i as u64;
395 }
396
397 fn write_u64(&mut self, i: u64) {
398 self.data = i;
399 }
400
401 fn write_u128(&mut self, i: u128) {
402 self.data = i as u64;
403 }
404
405 fn write_usize(&mut self, i: usize) {
406 self.data = i as u64;
407 }
408
409 fn write_i8(&mut self, i: i8) {
410 self.data = i as u64;
411 }
412
413 fn write_i16(&mut self, i: i16) {
414 self.data = i as u64;
415 }
416
417 fn write_i32(&mut self, i: i32) {
418 self.data = i as u64;
419 }
420
421 fn write_i64(&mut self, i: i64) {
422 self.data = i as u64;
423 }
424
425 fn write_i128(&mut self, i: i128) {
426 self.data = i as u64;
427 }
428
429 fn write_isize(&mut self, i: isize) {
430 self.data = i as u64;
431 }
432}
433
434pub trait TransparentKey: Hash + Eq {
443 fn to_u64(&self) -> u64;
445}
446
447#[derive(Default, Clone, Eq, PartialEq, Debug)]
454pub struct TransparentKeyBuilder<K: TransparentKey> {
455 _marker: PhantomData<K>,
457}
458
459impl<K: TransparentKey> KeyBuilder for TransparentKeyBuilder<K> {
460 type Key = K;
461
462 #[inline]
463 fn hash_index<Q>(&self, key: &Q) -> u64
464 where
465 Self::Key: core::borrow::Borrow<Q>,
466 Q: core::hash::Hash + Eq + ?Sized,
467 {
468 let mut hasher = TransparentHasher { data: 0 };
469 key.hash(&mut hasher);
470 hasher.finish()
471 }
472
473 #[inline]
474 fn hash_conflict<Q>(&self, _key: &Q) -> u64
475 where
476 Self::Key: core::borrow::Borrow<Q>,
477 Q: core::hash::Hash + Eq + ?Sized,
478 {
479 0
480 }
481}
482
483macro_rules! impl_transparent_key {
484 ($($t:ty),*) => {
485 $(
486 impl TransparentKey for $t {
487 fn to_u64(&self) -> u64 {
488 *self as u64
489 }
490 }
491 )*
492 }
493}
494
495impl_transparent_key! {
496 bool,
497 u8,
498 u16,
499 u32,
500 u64,
501 usize,
502 i8,
503 i16,
504 i32,
505 i64,
506 isize
507}