radar-gi/src/utils/cache.rs
2024-08-14 17:05:06 +08:00

62 lines
1.4 KiB
Rust

use crate::errors::*;
use std::{cell::RefCell, hash::Hash, num::NonZeroUsize, rc::Rc};
use lru::LruCache;
use crate::data_loader::Data;
pub struct Cache<K: Hash + Eq, V> {
cache: LruCache<K, V>,
}
impl<K: Hash + Eq, V> Cache<K, V> {
pub fn new() -> Self {
Self {
cache: LruCache::new(NonZeroUsize::new(10).unwrap()),
}
}
pub fn get(&mut self, key: &K) -> Option<&V> {
self.cache.get(key)
}
pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
self.cache.get_mut(key)
}
}
impl<K, V> Cache<K, V>
where
K: AsRef<std::path::Path> + Hash + Eq + Clone,
V: CacheData,
{
pub fn insert(&mut self, key: K) -> Result<()> {
let value = V::from_path(&key)?;
self.cache.put(key, value);
Ok(())
}
pub fn get_or_insert(&mut self, key: K) -> Result<&V> {
if !self.cache.contains(&key) {
self.insert(key.clone())?;
}
Ok(self.cache.get(&key).unwrap())
}
}
pub type CachedData<T> = Rc<RefCell<T>>;
pub trait CacheData: Sized {
fn from_path(path: impl AsRef<std::path::Path>) -> Result<Self>;
}
impl CacheData for Data {
fn from_path(path: impl AsRef<std::path::Path>) -> Result<Self> {
Data::from_path(path)
}
}
impl<T: CacheData> CacheData for CachedData<T> {
fn from_path(path: impl AsRef<std::path::Path>) -> Result<Self> {
Ok(Rc::new(RefCell::new(T::from_path(path)?)))
}
}