mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
94 lines
2.3 KiB
Rust
94 lines
2.3 KiB
Rust
use std::sync::{Arc, RwLock};
|
|
|
|
use once_cell::sync::Lazy;
|
|
use rustc_hash::FxHashMap;
|
|
|
|
#[derive(Debug)]
|
|
pub struct CacheEntry<T> {
|
|
data: Arc<T>,
|
|
timestamp: i64,
|
|
}
|
|
|
|
#[derive(Debug, Clone, thiserror::Error)]
|
|
pub enum CacheError {
|
|
#[error("Could not acquire the lock for cache entry")]
|
|
CouldNotAcquireLock,
|
|
#[error("Entry not found in cache")]
|
|
EntryNotFound,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct StaticCache<T> {
|
|
data: Lazy<RwLock<FxHashMap<String, CacheEntry<T>>>>,
|
|
}
|
|
|
|
impl<T> StaticCache<T>
|
|
where
|
|
T: Send,
|
|
{
|
|
// Cannot have default impl as it cannot be called during instantiation of static item
|
|
#[allow(clippy::new_without_default)]
|
|
pub const fn new() -> Self {
|
|
Self {
|
|
data: Lazy::new(|| RwLock::new(FxHashMap::default())),
|
|
}
|
|
}
|
|
|
|
pub fn present(&self, key: &String) -> Result<bool, CacheError> {
|
|
let the_map = self
|
|
.data
|
|
.read()
|
|
.map_err(|_| CacheError::CouldNotAcquireLock)?;
|
|
|
|
Ok(the_map.get(key).is_some())
|
|
}
|
|
|
|
pub fn expired(&self, key: &String, timestamp: i64) -> Result<bool, CacheError> {
|
|
let the_map = self
|
|
.data
|
|
.read()
|
|
.map_err(|_| CacheError::CouldNotAcquireLock)?;
|
|
|
|
Ok(match the_map.get(key) {
|
|
None => false,
|
|
Some(entry) => timestamp > entry.timestamp,
|
|
})
|
|
}
|
|
|
|
pub fn retrieve(&self, key: &String) -> Result<Arc<T>, CacheError> {
|
|
let the_map = self
|
|
.data
|
|
.read()
|
|
.map_err(|_| CacheError::CouldNotAcquireLock)?;
|
|
|
|
let cache_entry = the_map.get(key).ok_or(CacheError::EntryNotFound)?;
|
|
|
|
Ok(Arc::clone(&cache_entry.data))
|
|
}
|
|
|
|
pub fn save(&self, key: String, data: T, timestamp: i64) -> Result<(), CacheError> {
|
|
let mut the_map = self
|
|
.data
|
|
.write()
|
|
.map_err(|_| CacheError::CouldNotAcquireLock)?;
|
|
|
|
let entry = CacheEntry {
|
|
data: Arc::new(data),
|
|
timestamp,
|
|
};
|
|
|
|
the_map.insert(key, entry);
|
|
Ok(())
|
|
}
|
|
|
|
pub fn clear(&self) -> Result<(), CacheError> {
|
|
let mut the_map = self
|
|
.data
|
|
.write()
|
|
.map_err(|_| CacheError::CouldNotAcquireLock)?;
|
|
|
|
the_map.clear();
|
|
Ok(())
|
|
}
|
|
}
|