#[cfg(test)]
mod storage_tests {
use rssn_advanced::dag::builder::DagBuilder;
use rssn_advanced::dag::node::DagNodeId;
use rssn_advanced::heuristic::{HeuristicConfig, HeuristicEngine, SearchStrategy};
use rssn_advanced::storage::{DiskCache, DynamicHotspotTable, evict_cold_nodes};
use std::fs::remove_dir_all;
use std::path::PathBuf;
#[test]
fn test_disk_cache_spill_and_restore() {
let cache_dir = PathBuf::from("./test_spillover_cache");
let disk_cache = DiskCache::new(&cache_dir).unwrap();
let mut builder = DagBuilder::new();
let x = builder.variable("x");
let y = builder.variable("y");
let expr = builder.add(x, y);
disk_cache.spill("my_arena", builder.arena()).unwrap();
let restored_arena = disk_cache.restore("my_arena").unwrap();
assert_eq!(restored_arena.len(), builder.arena().len());
let node = restored_arena.get(expr).unwrap();
assert_eq!(node.children.len(), 2);
disk_cache.delete("my_arena").unwrap();
let _ = remove_dir_all(&cache_dir);
}
#[test]
fn test_hotspot_table_and_eviction() {
let hotspots = DynamicHotspotTable::new();
let id_0 = DagNodeId::new(0);
let id_1 = DagNodeId::new(1);
let id_2 = DagNodeId::new(2);
hotspots.record_access(id_0);
hotspots.record_access(id_0); hotspots.record_access(id_1);
assert!(hotspots.is_hot(id_0, 2));
assert!(!hotspots.is_hot(id_1, 2));
assert_eq!(hotspots.get_frequency(id_2), 0);
let mut builder = DagBuilder::new();
builder.constant(1.0); builder.constant(2.0); builder.constant(3.0);
let result = evict_cold_nodes(builder.arena(), &hotspots, 2);
assert!(result.arena.len() <= builder.arena().len());
assert!(result.translate(id_0).is_some());
}
#[test]
fn test_heuristic_engine_and_timeout() {
let mut builder = DagBuilder::new();
let x = builder.variable("x");
let mut current = x;
for _ in 0..10 {
current = builder.add(current, x);
}
let config = HeuristicConfig::default()
.timeout(std::time::Duration::from_millis(5))
.max_depth(3);
let mut engine = HeuristicEngine::new(config, SearchStrategy::Greedy);
let simplified = engine.simplify(&mut builder, current);
assert!(simplified.index() < builder.arena().len());
}
#[test]
fn test_approximate_simplification_folding() {
let mut builder = DagBuilder::new();
let x = builder.variable("x");
let mut current = x;
for _ in 0..8 {
current = builder.add(current, x);
}
let config = HeuristicConfig::default()
.simplification_aggressiveness(0.7)
.max_depth(10);
let mut engine = HeuristicEngine::new(config, SearchStrategy::Greedy);
let simplified = engine.simplify(&mut builder, current);
let node = builder.arena().get(simplified).expect("simplified node");
assert!(
node.children.len() > 0
|| matches!(
node.kind,
rssn_advanced::dag::symbol::SymbolKind::Constant(_)
)
);
}
}