62 lines
1.4 KiB
Rust
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)?)))
|
|
}
|
|
}
|