1use std::num::NonZeroUsize;
2use std::sync::{Arc, Mutex};
3
4use lru::LruCache;
5
6use crate::Principal;
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
10pub struct CacheKey(pub(crate) [u8; 32]);
11
12impl CacheKey {
13 pub fn as_bytes(&self) -> &[u8; 32] {
14 &self.0
15 }
16}
17
18#[derive(Clone, Debug)]
20pub struct CachedPrincipal {
21 pub(crate) key: CacheKey,
22 pub(crate) principal: Arc<Principal>,
23 pub(crate) cached_at: u64,
24 pub(crate) valid_until: u64
25}
26
27impl CachedPrincipal {
28 pub fn principal(&self) -> &Arc<Principal> {
29 &self.principal
30 }
31 pub fn valid_until(&self) -> u64 {
32 self.valid_until
33 }
34}
35
36pub trait PrincipalCache {
42 fn get(
43 &self,
44 key: &CacheKey
45 ) -> Option<CachedPrincipal>;
46 fn insert(
47 &self,
48 key: CacheKey,
49 entry: CachedPrincipal
50 );
51}
52
53pub struct MemoryCache(Mutex<LruCache<CacheKey, CachedPrincipal>>);
55
56impl MemoryCache {
57 pub fn new(capacity: NonZeroUsize) -> Self {
58 Self(Mutex::new(LruCache::new(capacity)))
59 }
60
61 pub fn clear(&self) {
62 self.0.lock().unwrap_or_else(|error| error.into_inner()).clear();
63 }
64}
65
66impl PrincipalCache for MemoryCache {
67 fn get(
68 &self,
69 key: &CacheKey
70 ) -> Option<CachedPrincipal> {
71 self.0.lock().unwrap_or_else(|error| error.into_inner()).get(key).cloned()
72 }
73
74 fn insert(
75 &self,
76 key: CacheKey,
77 entry: CachedPrincipal
78 ) {
79 self.0.lock().unwrap_or_else(|error| error.into_inner()).put(key, entry);
80 }
81}