use std::sync::Arc;
use std::time::Duration;
use hydracache_core::{CacheCodec, PostcardCodec};
use moka::future::Cache;
use crate::cache::{HydraCache, HydraCacheInner};
use crate::entry::CacheEntry;
use crate::events::EventBus;
use crate::inflight::InFlightMap;
use crate::stats::StatsCounters;
use crate::tag_index::TagIndex;
#[derive(Debug, Clone)]
pub struct HydraCacheBuilder<C = PostcardCodec>
where
C: CacheCodec,
{
max_capacity: u64,
max_entry_bytes: usize,
default_ttl: Duration,
event_buffer_capacity: usize,
access_events: bool,
codec: C,
}
impl<C> HydraCacheBuilder<C>
where
C: CacheCodec,
{
pub fn max_capacity(mut self, max_capacity: u64) -> Self {
self.max_capacity = max_capacity.max(1);
self
}
pub fn max_entry_bytes(mut self, max_entry_bytes: usize) -> Self {
self.max_entry_bytes = max_entry_bytes.max(1);
self
}
pub fn default_ttl(mut self, default_ttl: Duration) -> Self {
self.default_ttl = default_ttl;
self
}
pub fn event_buffer_capacity(mut self, capacity: usize) -> Self {
self.event_buffer_capacity = capacity.max(1);
self
}
pub fn enable_access_events(mut self, enabled: bool) -> Self {
self.access_events = enabled;
self
}
pub fn codec<Next>(self, codec: Next) -> HydraCacheBuilder<Next>
where
Next: CacheCodec,
{
HydraCacheBuilder {
max_capacity: self.max_capacity,
max_entry_bytes: self.max_entry_bytes,
default_ttl: self.default_ttl,
event_buffer_capacity: self.event_buffer_capacity,
access_events: self.access_events,
codec,
}
}
pub fn build(self) -> HydraCache<C> {
let max_entry_bytes = self.max_entry_bytes;
let store = Cache::builder()
.max_capacity(self.max_capacity)
.weigher(move |_key, entry: &CacheEntry| {
entry.value.len().min(max_entry_bytes).max(1) as u32
})
.build();
HydraCache {
inner: Arc::new(HydraCacheInner {
store,
tag_index: TagIndex::default(),
in_flight: InFlightMap::default(),
codec: self.codec,
default_ttl: self.default_ttl,
stats: Arc::new(StatsCounters::default()),
events: EventBus::new(self.event_buffer_capacity, self.access_events),
}),
}
}
}
impl Default for HydraCacheBuilder<PostcardCodec> {
fn default() -> Self {
Self {
max_capacity: 10_000,
max_entry_bytes: 16 * 1024 * 1024,
default_ttl: Duration::from_secs(300),
event_buffer_capacity: 1024,
access_events: false,
codec: PostcardCodec,
}
}
}