vyre 0.4.0

GPU compute intermediate representation with a standard operation library
Documentation
use vyre_wgpu::runtime::cache::{CacheTier, LruPolicy, TieredCache};

#[test]
fn insert_and_retrieve_from_each_tier() {
    let tiers = vec![
        CacheTier::new("slow", 100),
        CacheTier::new("medium", 100),
        CacheTier::new("fast", 100),
    ];
    let mut cache = TieredCache::new(tiers);

    cache.insert(1, 10).expect("insert into tier 0");
    assert_eq!(cache.get(1).map(|e| e.tier), Some(0));

    for _ in 0..LruPolicy::DEFAULT_THRESHOLD {
        cache.record_access(1);
    }
    cache.promote(1).expect("promote to tier 1");
    assert_eq!(cache.get(1).map(|e| e.tier), Some(1));

    for _ in 0..LruPolicy::DEFAULT_THRESHOLD {
        cache.record_access(1);
    }
    cache.promote(1).expect("promote to tier 2");
    assert_eq!(cache.get(1).map(|e| e.tier), Some(2));
}

#[test]
fn capacity_overflow_triggers_eviction() {
    let tiers = vec![CacheTier::new("only", 20)];
    let mut cache = TieredCache::new(tiers);

    cache.insert(1, 10).unwrap();
    cache.insert(2, 10).unwrap();
    assert!(cache.get(1).is_some());
    assert!(cache.get(2).is_some());

    cache.record_access(1);
    cache.insert(3, 10).unwrap();

    assert!(cache.get(1).is_some());
    assert!(cache.get(2).is_none());
    assert!(cache.get(3).is_some());
}

#[test]
fn frequent_access_promotes_to_higher_tier() {
    let tiers = vec![CacheTier::new("slow", 100), CacheTier::new("fast", 100)];
    let mut cache = TieredCache::new(tiers);

    cache.insert(42, 10).unwrap();
    assert_eq!(cache.get(42).map(|e| e.tier), Some(0));

    for _ in 0..LruPolicy::DEFAULT_THRESHOLD {
        cache.record_access(42);
    }
    cache.promote(42).unwrap();
    assert_eq!(cache.get(42).map(|e| e.tier), Some(1));
}

#[test]
fn lru_eviction_picks_the_right_candidate() {
    let tiers = vec![CacheTier::new("only", 30)];
    let mut cache = TieredCache::new(tiers);

    cache.insert(1, 10).unwrap();
    cache.insert(2, 10).unwrap();
    cache.insert(3, 10).unwrap();

    cache.record_access(1);
    cache.record_access(2);
    cache.record_access(3);
    cache.record_access(1);
    cache.record_access(2);

    cache.insert(4, 10).unwrap();

    assert!(cache.get(1).is_some());
    assert!(cache.get(2).is_some());
    assert!(cache.get(3).is_none(), "LRU should evict key 3");
    assert!(cache.get(4).is_some());
}