1pub mod clock;
2pub mod core;
3pub mod metrics;
4pub mod s3fifo;
5
6use crate::core::backoff::BackoffConfig;
7use crate::core::engine::CacheEngine;
8use crate::core::entry::Entry;
9use crate::core::entry_ref::Ref;
10use crate::core::key::Key;
11use crate::core::request_quota::RequestQuota;
12use crate::core::thread_context::ThreadContext;
13use crate::metrics::MetricsSnapshot;
14pub use omega_cache_macros::cache;
15use std::borrow::Borrow;
16use std::hash::Hash;
17use std::marker::PhantomData;
18use std::time::Duration;
19use thread_local::ThreadLocal;
20
21pub struct Cache<E, K, V>
22where
23 E: CacheEngine<K, V>,
24 K: Eq + Hash,
25{
26 engine: E,
27 backoff_config: BackoffConfig,
28 context: ThreadLocal<ThreadContext>,
29 _phantom: PhantomData<(K, V)>,
30}
31
32impl<E, K, V> Cache<E, K, V>
33where
34 E: CacheEngine<K, V>,
35 K: Eq + Hash,
36{
37 pub fn new(engine: E, backoff_config: BackoffConfig) -> Self {
38 Self {
39 engine,
40 backoff_config,
41 context: ThreadLocal::new(),
42 _phantom: Default::default(),
43 }
44 }
45
46 pub fn get<Q>(&self, key: &Q) -> Option<Ref<K, V>>
55 where
56 Key<K>: Borrow<Q>,
57 Q: Eq + Hash + ?Sized,
58 {
59 let context = self.context();
60 self.engine.get(key, context)
61 }
62
63 pub fn insert(&self, key: K, value: V) {
70 let entry = Entry::new(key, value);
71
72 self.engine
73 .insert(entry, self.context(), &mut RequestQuota::default());
74 }
75
76 pub fn insert_with_ttl(&self, key: K, value: V, ttl: Duration) {
87 let entry = Entry::with_ttl(key, value, ttl);
88 self.engine
89 .insert(entry, self.context(), &mut RequestQuota::default());
90 }
91
92 pub fn remove<Q>(&self, key: &Q) -> bool
96 where
97 Key<K>: Borrow<Q>,
98 Q: Eq + Hash + ?Sized,
99 {
100 self.engine.remove(key, self.context())
101 }
102
103 pub fn metrics(&self) -> MetricsSnapshot {
104 self.engine.metrics()
105 }
106
107 #[inline]
108 fn context(&self) -> &ThreadContext {
109 self.context
110 .get_or(|| ThreadContext::new(self.backoff_config.build()))
111 }
112}