use std::sync::Arc;
use uuid::Uuid;
use super::frame::{Frame, FrameStatus};
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize, Default)]
pub enum CacheStrategy {
LastOnly,
#[default]
All,
}
#[derive(Debug, Clone, Copy, Default)]
pub struct CacheStatsSnapshot {
pub hits: u64,
pub misses: u64,
pub size: usize,
}
impl CacheStatsSnapshot {
pub fn hit_rate(&self) -> f64 {
let total = self.hits + self.misses;
if total == 0 { 0.0 } else { self.hits as f64 / total as f64 }
}
}
pub trait FrameCache: Send + Sync {
fn get(&self, node_uuid: Uuid, frame_idx: i32) -> Option<Frame>;
fn insert(&self, node_uuid: Uuid, frame_idx: i32, frame: Frame);
fn get_status(&self, node_uuid: Uuid, frame_idx: i32) -> Option<FrameStatus>;
fn len(&self) -> usize;
fn is_empty(&self) -> bool { self.len() == 0 }
fn set_strategy(&self, strategy: CacheStrategy);
fn stats_snapshot(&self) -> CacheStatsSnapshot;
}
pub trait WorkerPool: Send + Sync {
fn execute_with_epoch(&self, epoch: u64, f: Box<dyn FnOnce() + Send + 'static>);
}
impl<T: FrameCache + ?Sized> FrameCache for Arc<T> {
fn get(&self, node_uuid: Uuid, frame_idx: i32) -> Option<Frame> {
(**self).get(node_uuid, frame_idx)
}
fn insert(&self, node_uuid: Uuid, frame_idx: i32, frame: Frame) {
(**self).insert(node_uuid, frame_idx, frame)
}
fn get_status(&self, node_uuid: Uuid, frame_idx: i32) -> Option<FrameStatus> {
(**self).get_status(node_uuid, frame_idx)
}
fn len(&self) -> usize {
(**self).len()
}
fn set_strategy(&self, strategy: CacheStrategy) {
(**self).set_strategy(strategy)
}
fn stats_snapshot(&self) -> CacheStatsSnapshot {
(**self).stats_snapshot()
}
}
impl<T: WorkerPool + ?Sized> WorkerPool for Arc<T> {
fn execute_with_epoch(&self, epoch: u64, f: Box<dyn FnOnce() + Send + 'static>) {
(**self).execute_with_epoch(epoch, f)
}
}