moa_idalloc 0.1.4

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

use std::{collections::HashSet, thread};

use moa_idalloc::monotonic::IdGen;

#[test]
fn starts_at_one() {
    let g = IdGen::new();
    assert_eq!(g.alloc(), 1);
    assert_eq!(g.alloc(), 2);
    assert_eq!(g.alloc(), 3);
}

#[test]
fn never_yields_zero() {
    let g = IdGen::new();
    for _ in 0..1000 {
        assert_ne!(g.alloc(), 0);
    }
}

#[test]
fn strictly_increasing_and_unique() {
    let g = IdGen::new();
    let mut prev = g.alloc();
    let mut seen = HashSet::new();
    seen.insert(prev);
    for _ in 0..10_000 {
        let cur = g.alloc();
        assert!(cur > prev, "must be strictly increasing");
        assert!(seen.insert(cur), "must be unique");
        prev = cur;
    }
}

#[test]
fn default_matches_new() {
    let g = IdGen::default();
    assert_eq!(g.alloc(), 1);
}

#[test]
fn concurrent_allocs_are_unique() {
    const THREADS: usize = 8;
    const PER_THREAD: usize = 5_000;

    let idgen = IdGen::new();
    let all: Vec<u64> = thread::scope(|s| {
        let handles: Vec<_> = (0..THREADS)
            .map(|_| s.spawn(|| (0..PER_THREAD).map(|_| idgen.alloc()).collect::<Vec<u64>>()))
            .collect();
        handles.into_iter().flat_map(|h| h.join().unwrap()).collect()
    });

    let total = all.len();
    assert_eq!(total, THREADS * PER_THREAD);
    let unique: HashSet<u64> = all.into_iter().collect();
    assert_eq!(unique.len(), total, "并发分配的 id 必须各不相同");
}