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(
21 k: &K,
22 v: &V,
23 ) -> u32 {
24 let k_size = GetSize::get_size(&k);
25 let v_size = GetSize::get_size(&v);
26 k_size.saturating_add(v_size).try_into().unwrap_or(u32::MAX)
27 }
28
29 pub(crate) fn new(
31 name: &str,
32 eviction_policy: EvictionPolicy,
33 max_capacity: u64,
34 ) -> Self {
35 let inner = if max_capacity < 1 {
36 None
37 } else {
38 let cache = BaseCache::builder()
39 .name(name)
40 .eviction_policy(eviction_policy)
41 .max_capacity(max_capacity)
42 .weigher(Self::weigher_fn);
43 Some(cache.build())
44 };
45 Self { inner }
46 }
47
48 pub(crate) fn get(
50 &self,
51 key: &K,
52 ) -> Option<V> {
53 self.inner.as_ref().and_then(|cache| cache.get(key))
54 }
55
56 pub(crate) fn insert(
58 &self,
59 key: K,
60 value: V,
61 ) {
62 self.inner
63 .as_ref()
64 .inspect(|cache| cache.insert(key, value));
65 }
66
67 pub(crate) fn clear_cache(&self) {
69 self.inner.as_ref().inspect(|cache| cache.invalidate_all());
70 }
71
72 pub(crate) fn weighted_size(&self) -> u64 {
74 self.inner
75 .as_ref()
76 .inspect(|cache| {
77 cache.run_pending_tasks();
78 })
79 .map(BaseCache::weighted_size)
80 .unwrap_or_default()
81 }
82
83 pub(crate) fn entry_count(&self) -> u64 {
85 self.inner
86 .as_ref()
87 .inspect(|cache| {
88 cache.run_pending_tasks();
89 })
90 .map(BaseCache::entry_count)
91 .unwrap_or_default()
92 }
93
94 pub(crate) fn is_enabled(&self) -> bool {
96 self.inner.is_some()
97 }
98}