Get started
Add the crate, open a database, write a batch.
TessariKV is a library: there is no server to run. It needs Rust 1.89 or newer and a tokio runtime. It is in early development (0.0.x): the API and the on-disk format may change in any release before 1.0, so pin the version you build against.
Install
One dependency, and tokio.
cargo add tessarikv@0.0.2
cargo add tokio --features macros,rt-multi-threadFirst write
Write a key, read it back.
DbOptions::in_memory() keeps the whole database in memory, which is the quickest way to try it; give Db::open a directory and default options for a database on disk. Close it when you are done: a running flush finishes, every acknowledged write is synced and the directory is released.
use tessarikv::{Db, DbOptions, KeyspaceId, ReadOptions, WriteBatch, WriteOptions};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let db = Db::open("example", DbOptions::in_memory()).await?;
let mut batch = WriteBatch::new();
batch.put(KeyspaceId::DEFAULT, b"apple", b"red")?;
db.write(&batch, &WriteOptions::default()).await?;
let value = db.get(KeyspaceId::DEFAULT, b"apple", &ReadOptions::default()).await?;
assert_eq!(value.as_deref(), Some(&b"red"[..]));
db.close().await?;
Ok(())
}Durability
Say how durable each write must be.
The default is Durability::Sync: the log record is on stable storage before write returns. A write that can afford to lose the last moments before a machine failure hands its record to the operating system instead, and a bulk load that can be redone skips the log entirely.
use tessarikv::{Durability, WriteOptions};
let mut fast = WriteOptions::default();
fast.durability = Durability::Buffered; // survives a process crash
db.write(&batch, &fast).await?;
db.sync_wal().await?; // and now everything written so far is durableTransactions
Read at a snapshot, commit as one batch.
A transaction reads as of the moment it began, sees its own writes, and commits them atomically. If another commit touched a key it writes after it began, commit is refused with Conflict and writes nothing; run it again.
let mut txn = db.begin()?;
txn.put(KeyspaceId::DEFAULT, b"apple", b"green")?;
let own = txn.get(KeyspaceId::DEFAULT, b"apple", &ReadOptions::default()).await?;
assert_eq!(own.as_deref(), Some(&b"green"[..]));
txn.commit(&WriteOptions::default()).await?;From source
Building and testing the engine.
The last command model-checks the lock-free building blocks under loom. Before a change goes in, formatting, clippy with warnings denied (also for Linux and Windows targets) and cargo deny pass.
git clone https://github.com/tessaridb/tessarikv && cd tessarikv
cargo build --workspace
cargo test --workspace --tests
RUSTFLAGS="--cfg loom" LOOM_MAX_PREEMPTIONS=3 cargo test -p tessarikv-sync --release --lib