Skip to main content

omega_cache/
lib.rs

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    /// Retrieves a value from the cache.
47    ///
48    /// If the key exists, the admission policy is notified of the access.
49    ///
50    /// Returns a [`Ref`] handle that provides controlled access to the entry.
51    ///
52    /// The entry is pinned in memory for the duration of the handle's life using
53    /// epoch-based memory reclamation.
54    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    /// Inserts a key-value pair into the cache.
64    ///
65    /// # Arguments
66    ///
67    /// * `key` - The key to associate with the value.
68    /// * `value` - The value to be cached.
69    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    /// Inserts a key-value pair into the cache with a specific Time-to-Live (TTL).
77    ///
78    /// The entry will be automatically considered expired after the specified `ttl`
79    /// duration has elapsed.
80    ///
81    /// # Arguments
82    ///
83    /// * `key` - The key to associate with the value.
84    /// * `value` - The value to be cached.
85    /// * `ttl` - The duration for which the entry should remain valid.
86    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    /// Removes an entry from the cache.
93    ///
94    /// Returns `true` if the entry was found and successfully removed.
95    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}