use lru::LruCache;
use parking_lot::RwLock;
use std::num::NonZeroUsize;
use zino_core::{state::State, JsonValue, LazyLock};
#[derive(Debug, Clone, Copy, Default)]
pub struct GlobalCache;
impl GlobalCache {
#[inline]
pub fn put(key: impl Into<String>, value: impl Into<JsonValue>) -> Option<JsonValue> {
let mut cache = GLOBAL_CACHE.write();
cache.put(key.into(), value.into())
}
#[inline]
pub fn push(
key: impl Into<String>,
value: impl Into<JsonValue>,
) -> Option<(String, JsonValue)> {
let mut cache = GLOBAL_CACHE.write();
cache.push(key.into(), value.into())
}
#[inline]
pub fn get(key: &str) -> Option<JsonValue> {
let mut cache = GLOBAL_CACHE.write();
cache.get(key).cloned()
}
#[inline]
pub fn peek(key: &str) -> Option<JsonValue> {
let cache = GLOBAL_CACHE.read();
cache.peek(key).cloned()
}
#[inline]
pub fn contains(key: &str) -> bool {
let cache = GLOBAL_CACHE.read();
cache.contains(key)
}
#[inline]
pub fn pop(key: &str) -> Option<JsonValue> {
let mut cache = GLOBAL_CACHE.write();
cache.pop(key)
}
#[inline]
pub fn pop_entry(key: &str) -> Option<(String, JsonValue)> {
let mut cache = GLOBAL_CACHE.write();
cache.pop_entry(key)
}
#[inline]
pub fn pop_lru() -> Option<(String, JsonValue)> {
let mut cache = GLOBAL_CACHE.write();
cache.pop_lru()
}
#[inline]
pub fn promote(key: &str) {
let mut cache = GLOBAL_CACHE.write();
cache.promote(key)
}
#[inline]
pub fn demote(key: &str) {
let mut cache = GLOBAL_CACHE.write();
cache.demote(key)
}
#[inline]
pub fn len() -> usize {
let cache = GLOBAL_CACHE.read();
cache.len()
}
#[inline]
pub fn is_empty() -> bool {
let cache = GLOBAL_CACHE.read();
cache.is_empty()
}
#[inline]
pub fn cap() -> NonZeroUsize {
let cache = GLOBAL_CACHE.read();
cache.cap()
}
#[inline]
pub fn resize(cap: NonZeroUsize) {
let mut cache = GLOBAL_CACHE.write();
cache.resize(cap)
}
pub fn clear() {
let mut cache = GLOBAL_CACHE.write();
cache.clear()
}
}
static GLOBAL_CACHE: LazyLock<RwLock<LruCache<String, JsonValue>>> = LazyLock::new(|| {
let capacity = if let Some(cache) = State::shared().get_config("cache") {
cache
.get("capacity")
.expect("the `capacity` field is missing")
.as_integer()
.expect("the `capacity` field should be an integer")
.try_into()
.expect("the `capacity` field should be a positive integer")
} else {
10000
};
RwLock::new(LruCache::new(
NonZeroUsize::new(capacity).unwrap_or(NonZeroUsize::MIN),
))
});