use std::num::NonZeroUsize;
use std::sync::{Arc, Mutex};
use lru::LruCache;
use crate::Principal;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct CacheKey(pub(crate) [u8; 32]);
impl CacheKey {
pub fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
}
#[derive(Clone, Debug)]
pub struct CachedPrincipal {
pub(crate) key: CacheKey,
pub(crate) principal: Arc<Principal>,
pub(crate) cached_at: u64,
pub(crate) valid_until: u64,
}
impl CachedPrincipal {
pub fn principal(&self) -> &Arc<Principal> {
&self.principal
}
pub fn valid_until(&self) -> u64 {
self.valid_until
}
}
pub trait PrincipalCache {
fn get(
&self,
key: &CacheKey,
) -> Option<CachedPrincipal>;
fn insert(
&self,
key: CacheKey,
entry: CachedPrincipal,
);
}
pub struct MemoryCache(Mutex<LruCache<CacheKey, CachedPrincipal>>);
impl MemoryCache {
pub fn new(capacity: NonZeroUsize) -> Self {
Self(Mutex::new(LruCache::new(capacity)))
}
pub fn clear(&self) {
self.0.lock().unwrap_or_else(|error| error.into_inner()).clear();
}
}
impl PrincipalCache for MemoryCache {
fn get(
&self,
key: &CacheKey,
) -> Option<CachedPrincipal> {
self.0
.lock()
.unwrap_or_else(|error| error.into_inner())
.get(key)
.cloned()
}
fn insert(
&self,
key: CacheKey,
entry: CachedPrincipal,
) {
self.0
.lock()
.unwrap_or_else(|error| error.into_inner())
.put(key, entry);
}
}