use std::collections::HashSet;
use std::sync::{Mutex, MutexGuard, OnceLock};
use super::context_dedup::{ContextDedup, DedupResult, format_unchanged_stub};
static DEDUP: OnceLock<Mutex<ContextDedup>> = OnceLock::new();
static SEEN_PATHS: OnceLock<Mutex<HashSet<String>>> = OnceLock::new();
static STATS: OnceLock<Mutex<DedupStats>> = OnceLock::new();
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum DedupAction {
DeliverFull,
DeliverStub {
stub: String,
},
DeliverModified,
}
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct DedupStats {
pub total_checks: usize,
pub cache_hits: usize,
pub cache_misses: usize,
pub tokens_saved: usize,
pub hit_rate: f64,
}
#[must_use]
pub fn check_content(path: &str, content: &str, fresh: bool) -> DedupAction {
if fresh {
invalidate(path);
return DedupAction::DeliverFull;
}
check_content_enabled(
super::kernel_config::features().content_dedup,
crate::core::conversation::scope_cannot_identify_caller(),
path,
content,
)
}
#[must_use]
pub fn dedup_stats() -> DedupStats {
let mut snapshot = *lock(stats());
snapshot.hit_rate = if snapshot.total_checks == 0 {
0.0
} else {
snapshot.cache_hits as f64 / snapshot.total_checks as f64
};
snapshot
}
pub fn invalidate(path: &str) {
lock(dedup()).invalidate(path);
lock(seen_paths()).remove(path);
}
pub fn forget_deliveries() {
lock(dedup()).clear();
lock(seen_paths()).clear();
}
pub fn reset_dedup() {
lock(dedup()).clear();
lock(seen_paths()).clear();
*lock(stats()) = DedupStats::default();
}
fn check_content_enabled(
enabled: bool,
callers_indistinguishable: bool,
path: &str,
content: &str,
) -> DedupAction {
if !enabled {
return DedupAction::DeliverFull;
}
let result = lock(dedup()).check_and_record(path, content);
match result {
DedupResult::Unchanged { hash, saved_tokens } if !callers_indistinguishable => {
record_check(true, saved_tokens);
DedupAction::DeliverStub {
stub: format_unchanged_stub(path, &hash),
}
}
DedupResult::Unchanged { .. } => {
record_check(false, 0);
DedupAction::DeliverFull
}
DedupResult::Fresh => {
let modified = !lock(seen_paths()).insert(path.to_owned());
record_check(false, 0);
if modified {
DedupAction::DeliverModified
} else {
DedupAction::DeliverFull
}
}
}
}
fn record_check(hit: bool, saved_tokens: usize) {
let mut current = lock(stats());
current.total_checks += 1;
if hit {
current.cache_hits += 1;
current.tokens_saved += saved_tokens;
} else {
current.cache_misses += 1;
}
}
fn dedup() -> &'static Mutex<ContextDedup> {
DEDUP.get_or_init(|| {
Mutex::new(ContextDedup::new(
super::kernel_config::features().dedup_capacity,
))
})
}
fn seen_paths() -> &'static Mutex<HashSet<String>> {
SEEN_PATHS.get_or_init(|| Mutex::new(HashSet::new()))
}
fn stats() -> &'static Mutex<DedupStats> {
STATS.get_or_init(|| Mutex::new(DedupStats::default()))
}
fn lock<T>(mutex: &Mutex<T>) -> MutexGuard<'_, T> {
mutex
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
}
#[cfg(test)]
pub mod tests {
use super::super::kernel_config::{KERNEL_TEST_LOCK, reset_features};
use std::sync::MutexGuard;
use super::{DedupAction, check_content_enabled, dedup_stats, invalidate, reset_dedup};
fn isolated() -> MutexGuard<'static, ()> {
let guard = KERNEL_TEST_LOCK
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
reset_features();
reset_dedup();
guard
}
#[test]
fn indistinguishable_callers_never_receive_a_stub() {
let _guard = isolated();
check_content_enabled(true, true, "src/lib.rs", "content");
assert_eq!(
check_content_enabled(true, true, "src/lib.rs", "content"),
DedupAction::DeliverFull,
"a ledger that cannot tell callers apart must not substitute a stub"
);
}
#[test]
fn indistinguishable_callers_do_not_count_as_cache_hits() {
let _guard = isolated();
check_content_enabled(true, true, "a", "one");
check_content_enabled(true, true, "a", "one");
let stats = dedup_stats();
assert_eq!(stats.cache_hits, 0);
assert_eq!(stats.tokens_saved, 0);
}
#[test]
fn new_content_delivers_full() {
let _guard = isolated();
assert_eq!(
check_content_enabled(true, false, "src/lib.rs", "content"),
DedupAction::DeliverFull
);
}
#[test]
fn repeated_content_delivers_stub() {
let _guard = isolated();
check_content_enabled(true, false, "src/lib.rs", "content");
assert!(matches!(
check_content_enabled(true, false, "src/lib.rs", "content"),
DedupAction::DeliverStub { .. }
));
}
#[test]
fn modified_content_delivers_modified() {
let _guard = isolated();
check_content_enabled(true, false, "src/lib.rs", "before");
assert_eq!(
check_content_enabled(true, false, "src/lib.rs", "after"),
DedupAction::DeliverModified
);
}
#[test]
fn disabled_always_full() {
let _guard = isolated();
assert_eq!(
check_content_enabled(false, false, "src/lib.rs", "content"),
DedupAction::DeliverFull
);
assert_eq!(
check_content_enabled(false, false, "src/lib.rs", "content"),
DedupAction::DeliverFull
);
assert_eq!(dedup_stats().total_checks, 0);
}
#[test]
fn invalidate_forces_full() {
let _guard = isolated();
check_content_enabled(true, false, "src/lib.rs", "content");
invalidate("src/lib.rs");
assert_eq!(
check_content_enabled(true, false, "src/lib.rs", "content"),
DedupAction::DeliverFull
);
}
#[test]
fn stats_track_hits() {
let _guard = isolated();
check_content_enabled(true, false, "a", "one");
check_content_enabled(true, false, "a", "one");
check_content_enabled(true, false, "a", "one");
check_content_enabled(true, false, "b", "two");
check_content_enabled(true, false, "b", "two");
let stats = dedup_stats();
assert_eq!(stats.total_checks, 5);
assert_eq!(stats.cache_hits, 3);
assert_eq!(stats.cache_misses, 2);
assert!((stats.hit_rate - 0.6).abs() < f64::EPSILON);
}
}