1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//! The storage **engine seam** — the one trait everything in SpaceDB rests on.
//!
//! SpaceDB never talks to a concrete database. It talks to [`KvEngine`]: an
//! engine-agnostic, transactional key/value interface. This is what lets the
//! engine be a *per-store decision rather than a rewrite* (redb today; a
//! versioned engine later if temporal reads become a product need — Open Q #6 in
//! the mission), and it is the first of the open-core **seams**: `spacedb-store`
//! ships with the [`crate::RedbEngine`] and [`crate::MemEngine`], and any other
//! engine (including a MATA-hosted one) drops in behind the same trait.
//!
//! ## Transaction model
//!
//! - **Reads** see a consistent snapshot for the transaction's lifetime.
//! - **Writes** are **single-writer** and **atomic**: a [`WriteTx`] buffers its
//! mutations and applies them all-or-nothing on [`WriteTx::commit`]. Dropping a
//! write transaction **without** committing **rolls back** — this is the
//! property the document + index + head-pointer multi-table write depends on,
//! and the property the durability test in S4 will kill a process to verify.
//! - A [`WriteTx`] is also [`Readable`] (read-your-own-writes within the txn).
//!
//! All keys and values at this layer are **opaque bytes**. Typing and encoding
//! live one layer up in [`crate::Table`]; the AEAD value boundary (S2) lives
//! there too, so the engine only ever sees ciphertext.
use crateStoreResult;
/// Durability for a write transaction. Chosen **per write** because the mission's
/// consistency tiers want different guarantees: ledger-grade / strong-tier
/// collections fsync every commit; explicitly-convergent caches may not.
/// A read view over the store. Both [`ReadTx`] and [`WriteTx`] implement it, so
/// [`crate::Table`] read methods accept either (a write txn reads its own
/// uncommitted writes).
/// A read-only transaction: a consistent snapshot for its lifetime.
/// A single-writer transaction. Mutations are buffered and applied atomically on
/// [`commit`](WriteTx::commit); dropping without committing rolls back.
/// The storage engine: opens read and write transactions.
///
/// `Send + Sync` so one engine handle can be shared across the components that
/// need it. The GAT lifetimes let an engine hand a transaction a borrow of
/// itself (the in-memory engine holds a lock guard for the txn's lifetime; redb
/// transactions are self-owned, so they simply ignore the lifetime).