use std::collections::HashMap;
#[derive(Debug)]
pub struct LocalFirstCoordinator {
response_cache: LocalCache<String>,
}
impl LocalFirstCoordinator {
pub fn new() -> Self {
Self {
response_cache: LocalCache::new(),
}
}
pub fn cache_response(&mut self, key: &str, response: String, size_bytes: usize) {
let entry = LocalCacheEntry {
key: key.to_string(),
value: response,
size_bytes,
};
self.response_cache.put(entry);
}
pub fn stats(&self) -> LocalFirstStats {
let cache_stats = self.response_cache.stats();
LocalFirstStats {
offline_status: OfflineStatus::Online,
bandwidth_saved_bytes: cache_stats.total_size_bytes,
cache_stats,
}
}
}
impl Default for LocalFirstCoordinator {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug)]
pub struct LocalCache<T> {
entries: HashMap<String, LocalCacheEntry<T>>,
max_entries: usize,
}
#[derive(Debug, Clone)]
pub struct LocalCacheEntry<T> {
key: String,
#[allow(dead_code)]
value: T,
size_bytes: usize,
}
impl LocalCache<String> {
pub fn new() -> Self {
Self {
entries: HashMap::new(),
max_entries: 1000,
}
}
pub fn put(&mut self, entry: LocalCacheEntry<String>) {
if self.entries.len() >= self.max_entries {
if let Some(first_key) = self.entries.keys().next().cloned() {
self.entries.remove(&first_key);
}
}
self.entries.insert(entry.key.clone(), entry);
}
pub fn stats(&self) -> CacheStats {
let total_size_bytes: usize = self.entries.values().map(|e| e.size_bytes).sum();
CacheStats {
entry_count: self.entries.len(),
total_size_bytes,
hit_rate: 0.0, }
}
}
impl Default for LocalCache<String> {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub struct CacheStats {
pub entry_count: usize,
pub total_size_bytes: usize,
pub hit_rate: f64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OfflineStatus {
Online,
#[allow(dead_code)]
Offline,
}
impl std::fmt::Display for OfflineStatus {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
OfflineStatus::Online => write!(f, "Online"),
OfflineStatus::Offline => write!(f, "Offline"),
}
}
}
#[derive(Debug, Clone)]
pub struct LocalFirstStats {
pub offline_status: OfflineStatus,
pub bandwidth_saved_bytes: usize,
pub cache_stats: CacheStats,
}
#[cfg(test)]
#[path = "../../tests/unit/session/local_first/local_first_test.rs"]
mod tests;