Crate assemblage_kv[][src]

Expand description

Versioned and transactional key-value store for native and wasm targets.

This crate provides a persistent key-value store implemented as a log-structured hash table similar to Bitcask. Writes of new or changed values never overwrite old entries, but are simply appended to the end of the storage. Old values are kept at earlier offsets in the storage and remain accessible. An in-memory hash table tracks the storage offsets of all keys and allows efficient reads directly from the relevant portions of the storage. A store can be merged, which discards old versions and builds a more compact representation containing only the latest value of each key.

Features

  • simple: log-structured hash architecture, with all keys in memory
  • fully versioned: old values remain accessible until merged
  • transactional: all reads and writes happen only in isolated transactions
  • storage-agnostic: supports files on native and IndexedDB on wasm

Example

use assemblage_kv::{run, storage::{self, Storage}, KvStore, Snapshot, Result};

fn main() -> Result<()> {
    // The `run!` macro abstracts away the boilerplate of setting up the
    // right async environment and storage for native / wasm and is not
    // needed outside of doc tests.
    run!(async |storage| {
        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));
        }
        Ok(())
    })
}

Modules

A storage backend abstraction for kv stores, similar to an append-only file.

Timestamp utilities that run on both native and wasm targets.

Macros

Allows the same test to be used on both native and wasm target_archs.

Creates a new storage, passes it to an async block and runs it.

Wraps test fns using hybrid-test! and automatically chooses the right storage implementation for the target_arch.

Structs

A versioned key-value store using a log-structured hash table.

A transactional snapshot of a store at a particular point in time that caches all reads and buffers all writes in memory.

A version of a key-value pair in a store at a particular point in time.

Enums

The error type for store operations.

Type Definitions

A specialized Result type for store operations.