Skip to content

Architecture

A short tour of the code. Design explains the decisions and guarantees.

crates/kv0            the library
  src/storage.rs           locations, storage options, open-or-create a Lance dataset
  src/rt.rs                the Tokio runtime behind the blocking APIs
  src/background.rs        one thread that flushes every open handle on its interval
  src/clock.rs             sequence numbers (a hybrid logical clock)
  src/kv/view.rs           the in-memory ordered view: newest-wins application of operations
  src/kv/wal.rs            the local write-ahead log: segments, records, replay of crashed writers
  src/kv/store.rs          the Lance operation log: read fragments, append, replace (compaction)
  src/kv/mod.rs            Db, Options, WriteBatch, DbIterator: buffering, flush, refresh, compaction
  src/tracking/schema.rs   Arrow schemas of runs, params, series and metrics
  src/tracking/mod.rs      Repo and Run: buffers, flush, queries, optimize
crates/kv0-py         PyO3 bindings and the pure-Python package kv0

Key-value write path

put / delete / write(batch)
  -> assign sequence numbers, append one record to the local WAL (fsync per wal_sync)
  -> apply to the view (visible now), append to the pending buffer
  -> buffer full, timer, flush(), sync=True or close():
       seal the WAL segment; append the buffer as one Lance fragment (one commit, retried by
       Lance on conflict) carrying the writer id and highest sequence number; delete the sealed segments
       read any fragments other writers committed meanwhile into the view
       more than max_fragments files? compact (materialise the view, or merge files)

Key-value read path

get / multi_get / iterator seek
  -> refresh_interval elapsed? check the latest version; read only fragments not yet applied
  -> answer from the in-memory ordered view (values over the lazy threshold are read from Lance)

Tracking write and read paths

Run.track / set_params / update -> the Repo buffer
flush -> one append per non-empty table: runs, params, series, metrics (in that order)
query -> flush, check out the latest table version, filtered scan, resolve newest-wins / order by step