1 个不稳定版本

0.1.0 2021 年 8 月 18 日

#2632数据库接口


2 crates 使用

AGPL-3.0

72KB
1.5K SLoC

针对本地和 Wasm 的版本化和事务性 KV 存储

AssemblageKV 是一个用 100% 安全的 Rust 实现的非常简单的嵌入式键值存储库,类似于 Bitcask 的日志结构化散列表。新或更改的值的写入永远不会覆盖旧条目,而是简单地追加到存储的末尾。旧值保留在存储中的早期偏移量中,并保持可访问性。内存散列表跟踪所有键的存储偏移量,允许从存储的相关部分直接进行高效的读取。存储可以合并,这将丢弃旧版本并构建一个包含每个键最新值的更紧凑表示。

功能

  • 简单:日志结构化散列架构,所有键都在内存中
  • 完全版本化:旧值在合并之前保持可访问
  • 事务性:所有读取和写入仅在隔离事务中发生
  • 存储独立:支持本地上的文件和 Wasm 上的 IndexedDB

必须警告

AssemblageKV 是一个个人项目,源于我对一个可以在本地和 Wasm 目标上运行的简单 KV 存储库的需求。不言而喻,它不是一个经过实战考验的生产就绪数据库,可能会随时损坏你的所有数据。 如果你需要持久化生产数据,请使用真正的数据库,如 Postgres、SQLite,或者考虑使用 sled 在 Rust 中进行 KV 存储。

示例

let store_name = storage.name().to_string();
let mut store = KvStore::open(storage).await?;
let slot = 0;

{
    let mut current = store.current().await;
    assert_eq!(current.get::<_, u8>(slot, &"key1").await?, None);
    current.insert(slot, &"key1", 1)?;
    current.commit().await?;
}

{
    let mut current = store.current().await;
    assert_eq!(current.get(slot, &"key1").await?, Some(1));
    current.remove(slot, &"key1")?;
    current.commit().await?;
}

{
    let mut current = store.current().await;
    assert_eq!(current.get::<_, u8>(slot, &"key1").await?, None);
    current.insert(slot, &"key1", 3)?;
    current.commit().await?;
}

{
    let current = store.current().await;
    let versions = current.versions(slot, &"key1").await?;
    assert_eq!(versions.len(), 3);
    assert_eq!(current.get_version(slot, &"key1", versions[0]).await?, Some(1));
    assert_eq!(current.get_version::<_, u8>(slot, &"key1", versions[1]).await?, None);
    assert_eq!(current.get_version(slot, &"key1", versions[2]).await?, Some(3));
}

store.merge().await?;
let storage = storage::open(&store_name).await?;
let store = KvStore::open(storage).await?;

{
    let current = store.current().await;
    let versions = current.versions(slot, &"key1").await?;
    assert_eq!(versions.len(), 1);
    assert_eq!(current.get(slot, &"key1").await?, Some(3));
}

依赖项

~2.9–7MB
~118K SLoC