cat_gateway/service/utilities/
cache.rs1use std::{collections::hash_map::RandomState, hash::Hash};
3
4use get_size2::GetSize;
5use moka::{policy::EvictionPolicy, sync::Cache as BaseCache};
6
7#[derive(Clone)]
9pub(crate) struct Cache<K, V> {
10 inner: Option<BaseCache<K, V, RandomState>>,
12}
13
14impl<K, V> Cache<K, V>
15where
16 K: Hash + Eq + Send + Sync + 'static,
17 V: Clone + Send + Sync + 'static,
18{
19 fn weigher_fn(k: &K, v: &V) -> u32 {
21 let k_size = GetSize::get_size(&k);
22 let v_size = GetSize::get_size(&v);
23 k_size.saturating_add(v_size).try_into().unwrap_or(u32::MAX)
24 }
25
26 pub(crate) fn new(name: &str, eviction_policy: EvictionPolicy, max_capacity: u64) -> Self {
28 let inner = if max_capacity < 1 {
29 None
30 } else {
31 let cache = BaseCache::builder()
32 .name(name)
33 .eviction_policy(eviction_policy)
34 .max_capacity(max_capacity)
35 .weigher(Self::weigher_fn);
36 Some(cache.build())
37 };
38 Self { inner }
39 }
40
41 pub(crate) fn get(&self, key: &K) -> Option<V> {
43 self.inner.as_ref().and_then(|cache| cache.get(key))
44 }
45
46 pub(crate) fn insert(&self, key: K, value: V) {
48 self.inner
49 .as_ref()
50 .inspect(|cache| cache.insert(key, value));
51 }
52
53 pub(crate) fn clear_cache(&self) {
55 self.inner.as_ref().inspect(|cache| cache.invalidate_all());
56 }
57
58 pub(crate) fn weighted_size(&self) -> u64 {
60 self.inner
61 .as_ref()
62 .inspect(|cache| {
63 cache.run_pending_tasks();
64 })
65 .map(BaseCache::weighted_size)
66 .unwrap_or_default()
67 }
68
69 pub(crate) fn entry_count(&self) -> u64 {
71 self.inner
72 .as_ref()
73 .inspect(|cache| {
74 cache.run_pending_tasks();
75 })
76 .map(BaseCache::entry_count)
77 .unwrap_or_default()
78 }
79
80 pub(crate) fn is_enabled(&self) -> bool {
82 self.inner.is_some()
83 }
84}