use super::fifo_cache::FifoCache;
use super::Cache;
use pdk_core::classy::extract::context::ConfigureContext;
use pdk_core::classy::extract::{Extract, FromContext};
use pdk_core::classy::{Clock, SharedData};
use pdk_core::policy_context::api::Metadata;
use std::convert::Infallible;
use std::rc::Rc;
cfg_if::cfg_if! {
if #[cfg(test)] {
use crate::mocks::MockConcurrentSharedData as ConcurrentSharedData;
} else {
use pdk_core::classy::shared_data::concurrent_shared_data::ConcurrentSharedData;
}
}
const DEFAULT_MAX_ENTRIES: usize = 100;
pub struct CacheBuilder {
clock: Rc<dyn Clock>,
shared_data: Rc<dyn SharedData>,
max_entries: usize,
prefix: String,
}
impl FromContext<ConfigureContext> for CacheBuilder {
type Error = Infallible;
fn from_context(context: &ConfigureContext) -> Result<Self, Self::Error> {
let clock: Rc<dyn Clock> = context.extract()?;
let shared_data: Rc<dyn SharedData> = context.extract()?;
let metadata: Metadata = context.extract()?;
Ok(CacheBuilder {
clock,
shared_data,
max_entries: DEFAULT_MAX_ENTRIES,
prefix: format!(
"isolated-cache_id-{}-{}",
metadata.policy_metadata.policy_name, metadata.policy_metadata.policy_namespace
),
})
}
}
impl CacheBuilder {
#[allow(clippy::new_ret_no_self)]
pub fn new(&self, cache_id: String) -> CacheBuilderInstance {
CacheBuilderInstance {
clock: Rc::clone(&self.clock),
shared_data: Rc::clone(&self.shared_data),
max_entries: self.max_entries,
prefix: self.prefix.clone(),
key: cache_id,
}
}
}
pub struct CacheBuilderInstance {
clock: Rc<dyn Clock>,
shared_data: Rc<dyn SharedData>,
max_entries: usize,
prefix: String,
key: String,
}
impl CacheBuilderInstance {
pub fn max_entries(mut self, max_entries: usize) -> Self {
self.max_entries = max_entries;
self
}
pub fn shared(mut self) -> Self {
self.prefix = "shared-cache_id".to_string();
self
}
pub fn build(self) -> impl Cache + 'static {
FifoCache::new(
format!("{}-{}", self.prefix, self.key),
self.max_entries,
ConcurrentSharedData::new(self.clock, self.shared_data),
)
}
}