mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-15 09:22:55 +00:00
89 lines
2.2 KiB
Rust
89 lines
2.2 KiB
Rust
use std::ops::{Deref, DerefMut};
|
|
|
|
/// A generic trait which exposes types of cache's key and value,
|
|
/// as well as the notion of cache entry invalidation.
|
|
/// This is useful for [`Cached`].
|
|
#[allow(async_fn_in_trait)]
|
|
pub trait Cache {
|
|
/// Used for entry invalidation.
|
|
type LookupInfo;
|
|
|
|
/// Invalidate an entry using a lookup info.
|
|
/// We don't have an empty default impl because it's error-prone.
|
|
async fn invalidate(&self, _: &Self::LookupInfo);
|
|
}
|
|
|
|
impl<C: Cache> Cache for &C {
|
|
type LookupInfo = C::LookupInfo;
|
|
|
|
async fn invalidate(&self, info: &Self::LookupInfo) {
|
|
C::invalidate(self, info).await
|
|
}
|
|
}
|
|
|
|
/// Wrapper for convenient entry invalidation.
|
|
pub struct Cached<C: Cache, V> {
|
|
/// Cache + lookup info.
|
|
pub token: Option<(C, C::LookupInfo)>,
|
|
|
|
/// The value itself.
|
|
pub value: V,
|
|
}
|
|
|
|
impl<C: Cache, V> Cached<C, V> {
|
|
/// Place any entry into this wrapper; invalidation will be a no-op.
|
|
pub fn new_uncached(value: V) -> Self {
|
|
Self { token: None, value }
|
|
}
|
|
|
|
pub fn take_value(self) -> (Cached<C, ()>, V) {
|
|
(
|
|
Cached {
|
|
token: self.token,
|
|
value: (),
|
|
},
|
|
self.value,
|
|
)
|
|
}
|
|
|
|
/// Drop this entry from a cache if it's still there.
|
|
pub async fn invalidate(self) -> V {
|
|
if let Some((cache, info)) = &self.token {
|
|
cache.invalidate(info).await;
|
|
}
|
|
self.value
|
|
}
|
|
|
|
/// Tell if this entry is actually cached.
|
|
pub fn cached(&self) -> bool {
|
|
self.token.is_some()
|
|
}
|
|
}
|
|
|
|
impl<C: Cache, V> Deref for Cached<C, V> {
|
|
type Target = V;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.value
|
|
}
|
|
}
|
|
|
|
impl<C: Cache, V> DerefMut for Cached<C, V> {
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
&mut self.value
|
|
}
|
|
}
|
|
|
|
impl<K, V, S> Cache for moka::future::Cache<K, V, S>
|
|
where
|
|
K: std::hash::Hash + Eq + Send + Sync + 'static,
|
|
V: Clone + Send + Sync + 'static,
|
|
S: std::hash::BuildHasher + Clone + Send + Sync + 'static,
|
|
{
|
|
type LookupInfo = K;
|
|
|
|
async fn invalidate(&self, key: &Self::LookupInfo) {
|
|
moka::future::Cache::invalidate(self, key).await
|
|
}
|
|
}
|