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
72 .lock()
73 .unwrap_or_else(|error| error.into_inner())
74 .get(key)
75 .cloned()
76 }
77
78 fn insert(
79 &self,
80 key: CacheKey,
81 entry: CachedPrincipal,
82 ) {
83 self.0
84 .lock()
85 .unwrap_or_else(|error| error.into_inner())
86 .put(key, entry);
87 }
88}