1use lru::LruCache;
4use parking_lot::RwLock;
5use std::num::NonZeroUsize;
6use zino_core::{JsonValue, LazyLock, state::State};
7
8#[derive(Debug, Clone, Copy, Default)]
10pub struct GlobalCache;
11
12impl GlobalCache {
13 #[inline]
17 pub fn put(key: impl Into<String>, value: impl Into<JsonValue>) -> Option<JsonValue> {
18 let mut cache = GLOBAL_CACHE.write();
19 cache.put(key.into(), value.into())
20 }
21
22 #[inline]
26 pub fn push(
27 key: impl Into<String>,
28 value: impl Into<JsonValue>,
29 ) -> Option<(String, JsonValue)> {
30 let mut cache = GLOBAL_CACHE.write();
31 cache.push(key.into(), value.into())
32 }
33
34 #[inline]
37 pub fn get(key: &str) -> Option<JsonValue> {
38 let mut cache = GLOBAL_CACHE.write();
39 cache.get(key).cloned()
40 }
41
42 #[inline]
46 pub fn peek(key: &str) -> Option<JsonValue> {
47 let cache = GLOBAL_CACHE.read();
48 cache.peek(key).cloned()
49 }
50
51 #[inline]
54 pub fn contains(key: &str) -> bool {
55 let cache = GLOBAL_CACHE.read();
56 cache.contains(key)
57 }
58
59 #[inline]
62 pub fn pop(key: &str) -> Option<JsonValue> {
63 let mut cache = GLOBAL_CACHE.write();
64 cache.pop(key)
65 }
66
67 #[inline]
70 pub fn pop_entry(key: &str) -> Option<(String, JsonValue)> {
71 let mut cache = GLOBAL_CACHE.write();
72 cache.pop_entry(key)
73 }
74
75 #[inline]
78 pub fn pop_lru() -> Option<(String, JsonValue)> {
79 let mut cache = GLOBAL_CACHE.write();
80 cache.pop_lru()
81 }
82
83 #[inline]
85 pub fn promote(key: &str) -> bool {
86 let mut cache = GLOBAL_CACHE.write();
87 cache.promote(key)
88 }
89
90 #[inline]
92 pub fn demote(key: &str) -> bool {
93 let mut cache = GLOBAL_CACHE.write();
94 cache.demote(key)
95 }
96
97 #[inline]
99 pub fn len() -> usize {
100 let cache = GLOBAL_CACHE.read();
101 cache.len()
102 }
103
104 #[inline]
106 pub fn is_empty() -> bool {
107 let cache = GLOBAL_CACHE.read();
108 cache.is_empty()
109 }
110
111 #[inline]
113 pub fn cap() -> NonZeroUsize {
114 let cache = GLOBAL_CACHE.read();
115 cache.cap()
116 }
117
118 #[inline]
121 pub fn resize(cap: NonZeroUsize) {
122 let mut cache = GLOBAL_CACHE.write();
123 cache.resize(cap)
124 }
125
126 pub fn clear() {
128 let mut cache = GLOBAL_CACHE.write();
129 cache.clear()
130 }
131}
132
133static GLOBAL_CACHE: LazyLock<RwLock<LruCache<String, JsonValue>>> = LazyLock::new(|| {
135 let capacity = if let Some(cache) = State::shared().get_config("cache") {
136 cache
137 .get("capacity")
138 .expect("field `capacity` is missing")
139 .as_integer()
140 .expect("field `capacity` should be an integer")
141 .try_into()
142 .expect("field `capacity` should be a positive integer")
143 } else {
144 10000
145 };
146 RwLock::new(LruCache::new(
147 NonZeroUsize::new(capacity).unwrap_or(NonZeroUsize::MIN),
148 ))
149});