v0.1.0
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 (
Leaf16 B,Prefix128 B,Blob
128 B,Node{4,16,48,256},EmptyRoot8 B). Every field
offset pinned at compile time viaoffset_of!asserts. - 4 KB
BlobHeader+ bit-packedSlotEntry
(ntype << 17 | offset / 8); 10 240-slot table per 512 KB
blob. - Recursive walker (insert / lookup / erase / rename) crossing
blobs transparently viaBlobNode. splitBlobin-band spillover,compactBlobin-place repack,
mergeBlobinverse fold (withis_mergeableguard +
refresh_blob_node_pointerspost-compact invariant repair).- 128 B
SPILLOVER_RESERVATION+Prefix↔Blobcross-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_prefixfor leaf-split / prefix-split hot
paths.
Concurrency
- 3-mode
HybridLatch(LeanStore: optimistic / shared /
exclusive) wired intoCachedBlobover
UnsafeCell<AlignedBlobBuf>. - Wait-free
Tree::getwalker — optimistic snapshots with
validate-after, restart from root on torn read. No Tree-wide
reader lock. put/deleteserialise onwal.lock(not a global writer
mutex);renamekeeps a separaterename_lockfor its
multi-step atomicity.
Persistence
MemoryBackendandPersistentBackend(single packed
blobs.dat+ atomic-renamemanifest.bin,O_DIRECTLinux,
F_NOCACHEmacOS).Backendtrait +AlignedBlobBuf4 KB-aligned zero-copy
buffer.- 10-variant
TxnOpcodec (MAGIC | LEN | SEQ | TY | BODY | CRC32); torn-tail-tolerant forward replay scanner. WalWriterwithsync_data-on-flush durability + 64 KB
group-commit auto-flush.Tree::checkpointflushes WAL + commits BM + truncates WAL
conditionally; replay reapplies records onto the BM-cached
blob and resumesnext_seqpast 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,TreeBuilderchainable
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
CommonPrefixdedup). Forward-only, best-effort snapshot.Tree::txn(|batch| { ... })— batched mutations under one
TxnOp::BatchWAL 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 (
proptestvsHashMaporacle, 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_NOCACHEfast paths have no Windows analog
worth maintaining. - MIT license, MSRV pinned to Rust 1.82.