use cachekit::policy::mru::MruCore;
fn main() {
println!("=== MRU Cache Example ===\n");
let mut cache = MruCore::new(5);
println!("Created MRU cache: capacity={}\n", cache.capacity());
for i in 1..=5 {
cache.insert(i, format!("value-{}", i));
}
println!("Inserted keys 1-5");
println!(" len: {}", cache.len());
cache.get(&5);
println!("\nAccessed key 5 (moved to MRU/head position)");
cache.insert(6, "value-6".to_string());
println!("Inserted key 6");
println!("\nAfter inserting key 6:");
println!(
" contains 5? {} (was most recent, got evicted!)",
cache.contains(&5)
);
println!(
" contains 1? {} (oldest, still in cache)",
cache.contains(&1)
);
println!(" contains 6? {} (newly inserted)", cache.contains(&6));
println!(" len: {}", cache.len());
println!("\n=== MRU vs LRU Comparison ===\n");
println!("Key differences:");
println!(" • MRU: Evicts from head (most recently used)");
println!(" • LRU: Evicts from tail (least recently used)");
println!();
println!("Example with cache capacity 3:");
println!(" Initial: [A, B, C]");
println!(" Access A → A moves to MRU position: [A, B, C]");
println!(" Insert D:");
println!(" • MRU evicts A (most recent) → [D, B, C]");
println!(" • LRU would evict C (least recent) → [D, A, B]");
println!("\n=== Cyclic Pattern Demo ===\n");
let mut cache = MruCore::new(3);
println!("Simulating cyclic access pattern: 1, 2, 3, 1, 2, 3, ...");
println!("(Each number represents a different page in a cycle)\n");
for i in 1..=3 {
cache.insert(i, format!("page-{}", i));
}
println!("First cycle complete: keys 1, 2, 3 in cache");
cache.insert(1, "page-1-updated".to_string());
println!("Accessed 1 again (evicted 3 - the most recent)");
cache.insert(2, "page-2-updated".to_string());
println!("Accessed 2 again (evicted 1 - the most recent)");
cache.insert(3, "page-3-updated".to_string());
println!("Accessed 3 again (evicted 2 - the most recent)");
println!("\nFinal state:");
println!(" contains 1? {}", cache.contains(&1));
println!(" contains 2? {}", cache.contains(&2));
println!(" contains 3? {}", cache.contains(&3));
println!(" len: {}", cache.len());
println!("\n=== When MRU Performs Poorly ===\n");
let mut cache = MruCore::new(3);
println!("Access pattern with temporal locality:");
println!(" hot_page (many times), cold_page_1, cold_page_2\n");
cache.insert("hot_page", "important");
for _ in 0..5 {
cache.get(&"hot_page");
}
println!("Accessed 'hot_page' 6 times total");
cache.insert("cold_page_1", "data1");
cache.insert("cold_page_2", "data2");
println!("Inserted 'cold_page_1' and 'cold_page_2'");
println!("\nResult:");
println!(" contains hot_page? {}", cache.contains(&"hot_page"));
println!(" contains cold_page_1? {}", cache.contains(&"cold_page_1"));
println!(" contains cold_page_2? {}", cache.contains(&"cold_page_2"));
println!();
println!("⚠️ 'hot_page' was evicted despite being accessed frequently!");
println!(" This is why MRU is NOT recommended for general-purpose caching.");
println!(" Use LRU, SLRU, or S3-FIFO for typical workloads.");
}