Skip to content

v1.0.0 — Stable API

Latest

Choose a tag to compare

@jamesgober jamesgober released this 10 Jun 01:15

lsm-db v1.0.0 — Stable

The engine is done. v1.0.0 is the first stable release of lsm-db. The
public API is frozen until 2.0 and the on-disk format is frozen for the
1.x series
. What you build against today keeps working for the life of the 1.x
line.

This release is the close of a milestone-by-milestone build: a single-run
foundation (0.2), multi-run levels with compaction and a frozen format (0.3),
crash-safe durability (0.4), bloom-filtered reads and a feature freeze (0.5), a
block cache and a head-to-head benchmark (0.6), hostile-input hardening and the
API freeze (0.7), and an alpha → beta → RC soak (0.8 – 0.9.5). 1.0 is the
definition-of-done audit and the cut.

What is lsm-db?

A log-structured merge-tree storage engine for Rust — the write path that powers
RocksDB, LevelDB, Cassandra, and ScyllaDB, packaged as a small, audited library.
Writes land in an in-memory memtable (optionally fronted by a write-ahead log);
when it fills, it is flushed to an immutable sorted run on disk; a background
thread compacts runs to keep reads fast and space bounded. It is the storage
layer the portfolio's database crates (txn-db, Hive DB) build on, and it stands
alone as an embedded key-value store.

The 1.0 surface

The common case is four calls — no builder, no generics to name:

use lsm_db::Lsm;

let db = Lsm::open("my-db")?;
db.put(b"user:1", b"alice")?;
assert_eq!(db.get(b"user:1")?, Some(b"alice".to_vec()));
db.delete(b"user:1")?;
for (key, value) in db.scan(b"user:".to_vec()..b"user;".to_vec())? {
    println!("{}", String::from_utf8_lossy(&key));
}
db.flush()?;
# Ok::<(), lsm_db::Error>(())

Tuning lives behind LsmConfig (write-buffer size, compaction trigger, block-cache
size); grouped atomic writes behind Batch. Two opt-in features extend the
engine without changing the surface: durability (every write hits a wal-db
log before acknowledgment, replayed on open — no acknowledged write lost across a
crash) and bloom (per-run filters let a point read skip any run that cannot
contain the key). The full reference, with a runnable example per item, is in
docs/API.md.

What the 1.0 audit changed

The definition-of-done audit was not a rubber stamp — it found and fixed real
issues:

  • Removed the inert framing feature and its unused pack-io optional
    dependency. The flag gated no code, so shipping it into the frozen 1.0 surface
    would have been dead weight that pulled a dependency for nothing. If typed
    on-disk framing is implemented later, it returns as a new additive feature.
  • Corrected the documented MSRV to 1.85 — the declared, CI-verified minimum
    (Rust 2024 edition's floor) — where release notes had drifted to 1.87.
  • Refreshed stale documentation: the README status blockquote still read
    "pre-1.0" and listed durability and bloom filters as upcoming (both shipped in
    0.4 and 0.5), and the feature tables still tagged the shipped bloom feature
    "(planned)".

No code behaviour changed; the engine is identical to the 0.9.x line.

What's frozen

  • Public API — every item in docs/API.md — frozen until 2.0. No breaking
    change in the 1.x series.
  • On-disk format — the sorted-run layout (LSMTBL01), the MANIFEST, the
    bloom sidecar envelope, and the durability write-ahead log — frozen for 1.x.
    A 1.0 database opens on any later 1.x release. The run format is specified in
    docs/SSTABLE_FORMAT.md.

Quality bar

  • #![forbid(unsafe_code)] — zero unsafe in the crate.
  • #![deny(warnings)] and the full clippy restriction set, including no
    unwrap/expect/panic/todo/dbg in library code.
  • Property tests against a reference model for every engine invariant; loom
    model checks for the read-versus-compaction swap.
  • Adversarial tests that corrupt the run, manifest, WAL, and bloom sidecar and
    assert the engine never panics or over-allocates (this caught and fixed a real
    panic on a corrupt sidecar in 0.7).
  • Single- and multi-threaded soak tests across restarts, checked against a
    BTreeMap model.
  • Benchmarks with locked 1.0 baselines (docs/PERFORMANCE.md); a >5% regression
    on a tracked metric blocks a release.

Breaking changes

From 0.9.5: the framing feature flag is removed. It gated no code, so no
working build depended on it; enabling it was a no-op that only pulled an unused
dependency. Everything else is unchanged.

Verification

Green on Windows x86_64 and Linux (WSL2), Rust stable and MSRV 1.85; macOS via the
CI matrix:

cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings
cargo clippy --all-targets --all-features -- -D warnings
cargo test
cargo test --all-features
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features
cargo +1.85 clippy --all-targets --all-features -- -D warnings
cargo +1.85 test --all-features
cargo build --examples --all-features
cargo build --benches --all-features
RUSTFLAGS="--cfg loom" cargo test --test loom_lsm
cargo deny check
cargo audit

All green.

Installation

[dependencies]
lsm-db = "1.0"
# Crash-safe writes and/or bloom-filtered point reads:
lsm-db = { version = "1.0", features = ["durability", "bloom"] }

MSRV: Rust 1.85 (2024 edition).

Documentation


Full diff: v0.9.5...v1.0.0.
Changelog: CHANGELOG.md.