armdb 0.2.0

sharded bitcask key-value storage optimized for NVMe
Documentation
use armdb::Config;
use std::fs;
use tempfile::tempdir;

#[test]
fn shard_open_removes_stale_tmp_files() {
    let dir = tempdir().unwrap();
    let config = Config::test();
    let tree = armdb::ConstTree::<[u8; 8], 8>::open(dir.path(), config.clone()).unwrap();

    // Write some data so shard directories exist
    tree.put(&1u64.to_be_bytes(), &[0u8; 8]).unwrap();
    drop(tree);

    // Plant stale tmp files in shard directories
    for entry in fs::read_dir(dir.path()).unwrap() {
        let entry = entry.unwrap();
        if entry.file_type().unwrap().is_dir() {
            let shard_dir = entry.path();
            fs::write(shard_dir.join("000099.data.tmp"), b"stale data").unwrap();
            fs::write(shard_dir.join("000099.tags.tmp"), b"stale tags").unwrap();
            fs::write(shard_dir.join("000099.hint.tmp"), b"stale hint").unwrap();
        }
    }

    // Reopen — should clean up tmp files
    let tree = armdb::ConstTree::<[u8; 8], 8>::open(dir.path(), config).unwrap();

    // Verify tmp files are gone
    for entry in fs::read_dir(dir.path()).unwrap() {
        let entry = entry.unwrap();
        if entry.file_type().unwrap().is_dir() {
            let shard_dir = entry.path();
            assert!(!shard_dir.join("000099.data.tmp").exists());
            assert!(!shard_dir.join("000099.tags.tmp").exists());
            assert!(!shard_dir.join("000099.hint.tmp").exists());
        }
    }

    // Verify data still accessible
    assert_eq!(tree.get(&1u64.to_be_bytes()), Some([0u8; 8]));
    drop(tree);
}