Skip to content

v0.1.0

Choose a tag to compare

@feichai0017 feichai0017 released this 19 May 05:35
· 281 commits to main since this release

First crates.io release. The v0.1 cycle built the engine end-to-
end on a single Unix-only stack: ART core, multi-blob splitBlob
/ mergeBlob / compactBlob, PersistentBackend (O_DIRECT
Linux + F_NOCACHE macOS), physiological WAL with replay,
S3-style range iteration with delimiter rollup. 203 tests on
ubuntu + macOS CI.

Algorithm core

  • 9-NodeType ART layout (Leaf 16 B, Prefix 128 B, Blob
    128 B, Node{4,16,48,256}, EmptyRoot 8 B). Every field
    offset pinned at compile time via offset_of! asserts.
  • 4 KB BlobHeader + bit-packed SlotEntry
    (ntype << 17 | offset / 8); 10 240-slot table per 512 KB
    blob.
  • Recursive walker (insert / lookup / erase / rename) crossing
    blobs transparently via BlobNode.
  • splitBlob in-band spillover, compactBlob in-place repack,
    mergeBlob inverse fold (with is_mergeable guard +
    refresh_blob_node_pointers post-compact invariant repair).
  • 128 B SPILLOVER_RESERVATION + PrefixBlob cross-type
    free-list fallback — spillover can always install its
    emergency BlobNode.
  • Erase-time node shrink (Node256 → 48 → 16 → 4 at hysteresis
    thresholds 37 / 12 / 3) + terminal lone-child
    Node4 → Prefix([byte]) collapse.
  • In-place leaf-value update on same-size writes — zero allocator
    activity.
  • SIMD node16_find_byte (SSE2 + NEON + scalar) and SIMD
    longest_common_prefix for leaf-split / prefix-split hot
    paths.

Concurrency

  • 3-mode HybridLatch (LeanStore: optimistic / shared /
    exclusive) wired into CachedBlob over
    UnsafeCell<AlignedBlobBuf>.
  • Wait-free Tree::get walker — optimistic snapshots with
    validate-after, restart from root on torn read. No Tree-wide
    reader lock.
  • put / delete serialise on wal.lock (not a global writer
    mutex); rename keeps a separate rename_lock for its
    multi-step atomicity.

Persistence

  • MemoryBackend and PersistentBackend (single packed
    blobs.dat + atomic-rename manifest.bin, O_DIRECT Linux,
    F_NOCACHE macOS).
  • Backend trait + AlignedBlobBuf 4 KB-aligned zero-copy
    buffer.
  • 10-variant TxnOp codec (MAGIC | LEN | SEQ | TY | BODY | CRC32); torn-tail-tolerant forward replay scanner.
  • WalWriter with sync_data-on-flush durability + 64 KB
    group-commit auto-flush.
  • Tree::checkpoint flushes WAL + commits BM + truncates WAL
    conditionally; replay reapplies records onto the BM-cached
    blob and resumes next_seq past every replayed record.
  • TxnOp::Batch (TY_BATCH = 10) carries N primitive ops under
    one record with shared CRC and derived seqs; replay
    transparently flattens to per-inner callbacks.

Public API

  • Tree::open(TreeConfig) single entry, TreeBuilder chainable
    config.
  • Tree::put / get / delete / rename (cross-blob via
    lookup_multi / insert_multi / erase_multi).
  • Tree::range() stateful iterator — .prefix(p),
    .start_after(k), .delimiter(b) (S3-style rollup with
    CommonPrefix dedup). Forward-only, best-effort snapshot.
  • Tree::txn(|batch| { ... }) — batched mutations under one
    TxnOp::Batch WAL record. Crash-atomic, runtime isolation is
    best-effort.
  • Tree::checkpoint(), Tree::stats().
  • Typed Error (BackendIo / Alloc / Free / KeyTooLong
    / ValueTooLong / NotYetImplemented / NodeCorrupt /
    ReplaySanityFailed / NotFound / DstExists).
    #[non_exhaustive] so new variants are non-breaking in minor
    releases.

Tests + benches + tooling

  • 202 tests: unit + property (proptest vs HashMap oracle, in
    memory and crash-and-replay persistent modes) + multi-reader
    stress + multi-blob auto-spillover end-to-end.
  • Criterion benches vs RocksDB across three workload shapes
    (kv / objstore / fs) × get / put / mixed × memory /
    persistent.
  • Four examples: basic_kv, filesystem_meta, session_store,
    s3_metadata.
  • GitHub Actions CI matrix (ubuntu + macOS) × build / test /
    doctest + lint (cargo fmt, cargo clippy -D warnings) +
    docs (cargo doc -D warnings) + MSRV (1.82).
  • Windows targets fire a top-of-crate compile_error! — the
    O_DIRECT / F_NOCACHE fast paths have no Windows analog
    worth maintaining.
  • MIT license, MSRV pinned to Rust 1.82.