use quick_cache::{DefaultHashBuilder, UnitWeighter, Weighter}; use std::{ future::Future, hash::{BuildHasher, Hash}, num::NonZeroU32, sync::Arc, time::Duration, }; use crate::{KQCacheWithTTL, PlaceholderGuardWithTTL}; pub struct CacheWithTTL( KQCacheWithTTL, ); impl CacheWithTTL { pub async fn new(capacity: usize, ttl: Duration) -> Self { Self::new_with_options( capacity, 1.try_into().unwrap(), capacity as u64, UnitWeighter, DefaultHashBuilder::default(), ttl, ) .await } pub async fn arc_with_capacity(capacity: usize, ttl: Duration) -> Arc { let x = Self::new(capacity, ttl).await; Arc::new(x) } } impl< Key: Eq + Hash + Clone + Send + Sync + 'static, Val: Clone + Send + Sync + 'static, We: Weighter + Clone + Send + Sync + 'static, B: BuildHasher + Clone + Default + Send + Sync + 'static, > CacheWithTTL { pub async fn new_with_weights( estimated_items_capacity: usize, max_item_weigth: NonZeroU32, weight_capacity: u64, weighter: We, ttl: Duration, ) -> Self { let max_item_weigth = max_item_weigth.min((weight_capacity as u32).try_into().unwrap()); let inner = KQCacheWithTTL::new_with_options( estimated_items_capacity, max_item_weigth, weight_capacity, weighter, B::default(), ttl, ) .await; Self(inner) } pub async fn new_with_options( estimated_items_capacity: usize, max_item_weight: NonZeroU32, weight_capacity: u64, weighter: We, hash_builder: B, ttl: Duration, ) -> Self { let inner = KQCacheWithTTL::new_with_options( estimated_items_capacity, max_item_weight, weight_capacity, weighter, hash_builder, ttl, ) .await; Self(inner) } #[inline] pub fn get(&self, key: &Key) -> Option { self.0.get(key, &()) } #[inline] pub async fn get_or_insert_async(&self, key: &Key, f: Fut) -> Val where Fut: Future, { self.0.get_or_insert_async(key, &(), f).await } #[inline] pub async fn try_get_or_insert_async(&self, key: &Key, f: Fut) -> Result where Fut: Future>, { self.0.try_get_or_insert_async(key, &(), f).await } #[inline] pub async fn get_value_or_guard_async( &self, key: Key, ) -> Result> { self.0.get_value_or_guard_async(key, ()).await } /// if the item was too large to insert, it is returned with the error #[inline] pub fn try_insert(&self, key: Key, val: Val) -> Result<(), (Key, Val)> { self.0.try_insert(key, (), val).map_err(|(k, _q, v)| (k, v)) } #[inline] pub fn remove(&self, key: &Key) -> bool { self.0.remove(key, &()) } }