cat_gateway/service/utilities/
cache.rs

1//! Cache wrapper type
2use std::{collections::hash_map::RandomState, hash::Hash};
3
4use get_size2::GetSize;
5use moka::{policy::EvictionPolicy, sync::Cache as BaseCache};
6
7/// Cache type that is disabled if the maximum capacity is set to zero.
8#[derive(Clone)]
9pub(crate) struct Cache<K, V> {
10    /// Optional `moka::sync::Cache`.
11    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    /// Function to determine cache entry weighted size.
20    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    /// Constructs a new `Cache`.
27    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    /// Get entry from the cache by key.
42    pub(crate) fn get(&self, key: &K) -> Option<V> {
43        self.inner.as_ref().and_then(|cache| cache.get(key))
44    }
45
46    /// Insert entry into the cache.
47    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    /// Clear entries in the cache.
54    pub(crate) fn clear_cache(&self) {
55        self.inner.as_ref().inspect(|cache| cache.invalidate_all());
56    }
57
58    /// Weighted-size of the cache.
59    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    /// Number of entries in the cache.
70    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    /// Returns `true` if the cache is enabled.
81    pub(crate) fn is_enabled(&self) -> bool {
82        self.inner.is_some()
83    }
84}