Skip to main content

sui_graph_store/
lib.rs

1//! sui-graph-store — content-addressed graph store for sui.
2//!
3//! Replaces the SeaORM/SQLite path with a typed two-tier store:
4//!
5//! * **L0 index** — `redb` 4.x copy-on-write B+ tree, pure Rust, ACID,
6//!   MVCC snapshots, zero-copy `&[u8]` reads. Maps `GraphHash` →
7//!   on-disk blob path + bookkeeping (size, kind, created-at).
8//! * **L1 blobs** — `rkyv` 0.8 archives on a sharded content-addressed
9//!   filesystem layout. Read path is `mmap` + cast → typed access with
10//!   zero allocations. Wire format is frozen on the 0.8 series.
11//!
12//! ## Design contract
13//!
14//! Every byte written to a blob path is the canonical rkyv archive of a
15//! typed graph (lockfile graph, AST graph, module graph). The blob's
16//! filename **is** its BLAKE3 hash; the index entry asserts the binding.
17//! Verification is implicit on every read: callers either trust the
18//! local hash they just computed (`get_unchecked`) or pay the bytecheck
19//! pass when pulling from an untrusted source (`get_validated`).
20//!
21//! The on-disk layout is ZFS-aware: blobs live on a dedicated dataset
22//! tuned `recordsize=1M, compression=zstd-3, atime=off`; the redb index
23//! lives on a sibling dataset tuned `recordsize=16K, logbias=latency`.
24//! Snapshots and `zfs send`-based fleet replication fall out for free —
25//! the whole cache is one `zfs send -R | zfs recv` away from every peer.
26//!
27//! ## Why this exists
28//!
29//! The previous SQLite path paid a SQL round-trip per access, didn't
30//! support `mmap`, and treated the store as a row collection instead of
31//! a blob collection. Content-addressed graphs want exactly the opposite
32//! shape: write once, read many, verify by hash, no parse cost on read.
33//! See `docs/architecture/l1-graph-store.md` (forthcoming) for the
34//! full design brief.
35//!
36//! ## Usage
37//!
38//! ```no_run
39//! use sui_graph_store::{GraphHash, GraphKind, GraphStore};
40//! # use std::path::Path;
41//!
42//! let store = GraphStore::open(Path::new("/var/lib/sui/graph-store"))?;
43//!
44//! // Archive any rkyv-serializable graph.
45//! let bytes = b"...rkyv-encoded payload...";
46//! let hash = GraphHash::of(bytes);
47//! store.put(GraphKind::Lockfile, hash, bytes)?;
48//!
49//! // Read it back — zero-copy mmap + cast.
50//! let mmap = store.get(GraphKind::Lockfile, hash)?;
51//! assert_eq!(&mmap[..], bytes);
52//! # Ok::<(), sui_graph_store::Error>(())
53//! ```
54
55#![warn(clippy::pedantic)]
56#![allow(clippy::module_name_repetitions)]
57
58pub mod content_address;
59pub mod error;
60pub mod layout;
61pub mod store;
62
63pub use content_address::GraphHash;
64pub use error::{Error, Result};
65pub use layout::{GraphKind, StoreLayout};
66pub use store::{GraphStore, IndexEntry};