pub struct Db<S: VersionStore = MemoryStore> { /* private fields */ }Expand description
A transactional, multi-version key-value database.
Db is the front door. Db::new gives you an in-memory database;
Db::with_store builds one over any VersionStore. From there the whole
common case is begin / get /
put / commit,
with snapshot for read-only point-in-time views.
A Db is a clonable handle over shared state, like an Arc. Cloning it
is cheap and every clone refers to the same database, so the idiomatic way
to use it across threads is to clone a handle per thread.
§Examples
The four-call common case:
use txn_db::Db;
let db = Db::new();
let mut tx = db.begin();
tx.put(b"greeting".to_vec(), b"hei".to_vec());
tx.commit()?;
let tx = db.begin();
assert_eq!(tx.get(b"greeting")?.as_deref(), Some(&b"hei"[..]));Sharing one database across threads:
use std::thread;
use txn_db::Db;
let db = Db::new();
let handles: Vec<_> = (0..4u8)
.map(|i| {
let db = db.clone();
thread::spawn(move || {
let mut tx = db.begin();
tx.put(vec![i], vec![i]);
// Independent keys never conflict.
tx.commit().expect("commit");
})
})
.collect();
for h in handles {
h.join().expect("thread");
}Implementations§
Source§impl Db<MemoryStore>
impl Db<MemoryStore>
Sourcepub fn new() -> Self
pub fn new() -> Self
Create an empty in-memory database.
This is the default configuration: a MemoryStore backing store, ready
for begin.
§Examples
use txn_db::Db;
let db = Db::new();
assert_eq!(db.last_committed(), txn_db::Timestamp::ZERO);Source§impl<S: VersionStore> Db<S>
impl<S: VersionStore> Db<S>
Sourcepub fn with_store(store: S) -> Self
pub fn with_store(store: S) -> Self
Create a database over a custom VersionStore.
This is the Tier-3 seam: supply any backing store and the transaction semantics — snapshot isolation, read-your-own-writes, write-write conflict detection — compose on top of it unchanged.
§Examples
use txn_db::{Db, MemoryStore};
let db = Db::with_store(MemoryStore::new());
let mut tx = db.begin();
tx.put(b"k".to_vec(), b"v".to_vec());
tx.commit()?;Sourcepub fn begin(&self) -> Transaction<S>
pub fn begin(&self) -> Transaction<S>
Begin a read-write transaction over the current state of the database.
The transaction takes its snapshot at this moment: it reads as of the most recent commit and is unaffected by commits that happen afterward.
§Examples
use txn_db::Db;
let db = Db::new();
let mut tx = db.begin();
tx.put(b"k".to_vec(), b"v".to_vec());
tx.commit()?;Sourcepub fn snapshot(&self) -> Snapshot<S>
pub fn snapshot(&self) -> Snapshot<S>
Take a read-only snapshot of the current state of the database.
The returned Snapshot reads as of this instant and never changes,
even as other transactions commit. Use it to read several keys at one
consistent point in time without the overhead of a transaction.
§Examples
use txn_db::Db;
let db = Db::new();
let snap = db.snapshot();
assert_eq!(snap.get(b"k")?, None);Sourcepub fn last_committed(&self) -> Timestamp
pub fn last_committed(&self) -> Timestamp
The timestamp of the most recent successful commit.
Returns Timestamp::ZERO for a database that has never been written.
This is the timestamp a transaction beginning now would read at.
§Examples
use txn_db::Db;
let db = Db::new();
assert_eq!(db.last_committed(), txn_db::Timestamp::ZERO);
let mut tx = db.begin();
tx.put(b"k".to_vec(), b"v".to_vec());
let ts = tx.commit()?;
assert_eq!(db.last_committed(), ts);