moa_idalloc 0.1.4

id 分配工具箱:单调号 / 回收位图 / 世代槽位表
Documentation
//! `IdAllocator`(回收位图)集成测试。

use moa_idalloc::dense::IdAllocator;

#[test]
fn allocs_start_at_zero_and_increase() {
    let mut a = IdAllocator::new();
    assert_eq!(a.alloc(), 0);
    assert_eq!(a.alloc(), 1);
    assert_eq!(a.alloc(), 2);
}

#[test]
fn freed_id_is_recycled() {
    let mut a = IdAllocator::new();
    a.alloc();
    a.alloc();
    a.alloc();
    a.free(1);
    assert_eq!(a.alloc(), 1, "应复用被释放的最小空闲号");
    assert_eq!(a.alloc(), 3);
}

#[test]
fn smallest_free_first() {
    let mut a = IdAllocator::new();
    for _ in 0..10 {
        a.alloc();
    }
    a.free(7);
    a.free(3);
    assert_eq!(a.alloc(), 3, "3 比 7 小,先取回");
    assert_eq!(a.alloc(), 7);
    assert_eq!(a.alloc(), 10);
}

#[test]
fn free_evens_then_refill_ascending() {
    let mut a = IdAllocator::new();
    for _ in 0..10 {
        a.alloc();
    }
    for even in (0..10).step_by(2) {
        a.free(even);
    }
    for even in (0..10).step_by(2) {
        assert_eq!(a.alloc(), even);
    }
    assert_eq!(a.alloc(), 10, "空闲号用完后从增长区取号");
}

#[test]
fn free_all_then_restart_from_zero() {
    let mut a = IdAllocator::new();
    let ids: Vec<usize> = (0..5).map(|_| a.alloc()).collect();
    for id in ids {
        a.free(id);
    }
    assert_eq!(a.alloc(), 0);
}

#[test]
fn autogrow_keeps_ids_contiguous_and_unique() {
    let mut a = IdAllocator::new();
    // 远超初始容量 64,触发多次翻倍扩容
    for expected in 0..10_000 {
        assert_eq!(a.alloc(), expected);
    }
}

#[test]
fn realloc_after_growth_still_recycles() {
    let mut a = IdAllocator::new();
    for _ in 0..200 {
        a.alloc();
    }
    a.free(150);
    assert_eq!(a.alloc(), 150);
    assert_eq!(a.alloc(), 200);
}

#[test]
fn default_matches_new() {
    let mut a = IdAllocator::default();
    assert_eq!(a.alloc(), 0);
}

#[test]
fn free_out_of_range_is_noop() {
    let mut a = IdAllocator::new();
    // 未分配任何号(cap = 0)时释放不应 panic
    a.free(0);
    a.free(999);
    assert_eq!(a.alloc(), 0, "无效释放后仍从 0 正常开始");
    // 已分配后,释放超出容量的号也是无操作
    a.free(10_000);
    assert_eq!(a.alloc(), 1);
}