core_storage/v8/layout.rs
1//! rkyv-archived layout types for the V8 snapshot format.
2//!
3//! All primitive fields archive as little-endian via rend (rkyv's LE-primitive
4//! crate), which is the default for rkyv 0.8 on all targets. The format is
5//! therefore architecture-portable and LE-pinned.
6
7use rkyv::{Archive, Deserialize, Serialize};
8
9// ---------------------------------------------------------------------------
10// CSR topology
11// ---------------------------------------------------------------------------
12
13/// One vertex's sorted adjacency list within an edge type and direction.
14#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
15pub struct CsrRow {
16 pub vertex: u32,
17 /// Sorted, unique neighbor ids.
18 pub neighbors: Vec<u32>,
19}
20
21/// All adjacency rows for one direction (out or in) of one edge type.
22/// Rows are sorted by `vertex` ascending so lookups can binary-search.
23#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
24pub struct CsrAdjMap {
25 pub rows: Vec<CsrRow>,
26}
27
28/// Full typed adjacency (out + in) for a single edge type.
29/// `etype` is the intern id of the edge-type label.
30#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
31pub struct CsrEtype {
32 pub etype: u32,
33 pub out_adj: CsrAdjMap,
34 pub in_adj: CsrAdjMap,
35}
36
37/// The full archived CSR topology: all edge types, sorted ascending by etype.
38#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
39pub struct CsrData {
40 /// Sorted by `etype` so lookups can binary-search.
41 pub etypes: Vec<CsrEtype>,
42 pub edge_count: u64,
43}
44
45// ---------------------------------------------------------------------------
46// Columns
47// ---------------------------------------------------------------------------
48
49/// Typed column payload. Mixed/list columns fall back to a bincode blob.
50/// Tag 5 (`Vector`) stores raw f64 runs for all-float list properties,
51/// enabling zero-copy `&[f64]` access without boxing through `Value`.
52#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
53pub enum ColumnData {
54 /// Dense i64 column. `present` is the presence bitmap as u64 words (LE).
55 Int { data: Vec<i64>, present: Vec<u64> },
56 /// Dense f64 column.
57 Float { data: Vec<f64>, present: Vec<u64> },
58 /// Dense bool column stored as u8 (0/1).
59 Bool { data: Vec<u8>, present: Vec<u64> },
60 /// String column: ids index into `strings`; `present` is the presence bitmap.
61 Str {
62 ids: Vec<u32>,
63 present: Vec<u64>,
64 strings: Vec<String>,
65 },
66 /// Mixed/list column: bincode-encoded `HashMap<u32, Value>`.
67 Mixed(Vec<u8>),
68 /// Raw f64 vector column (B2). `dim` floats per node, stored contiguously.
69 ///
70 /// Layout: `data[id * dim .. (id + 1) * dim]` = the vector for node `id`.
71 /// `present[word]` bit `bit` is set iff `id = word*64 + bit` has a value.
72 /// Zero-copy `&[f64]` access via `ColumnsView::vector(id, field)`.
73 ///
74 /// **Overlay/archive asymmetry:** vectors written after the last snapshot
75 /// live in the owned overlay as `Value::List([Value::Float, ...])` and are
76 /// not accessible through `vector()`. Callers must fall back to
77 /// `ColumnsView::get()` which returns `ValueRef::Owned(Value::List(...))`.
78 Vector {
79 dim: u32,
80 data: Vec<f64>,
81 present: Vec<u64>,
82 },
83}
84
85/// One field entry: name + typed column.
86#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
87pub struct FieldEntry {
88 pub name: String,
89 pub col: ColumnData,
90}
91
92/// The full archived column store. Fields are sorted by name for determinism.
93#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
94pub struct ColumnsData {
95 pub fields: Vec<FieldEntry>,
96}
97
98// ---------------------------------------------------------------------------
99// IdMap
100// ---------------------------------------------------------------------------
101
102/// Archived id map: dense-allocated key → id table plus tombstones.
103#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
104pub struct IdMapData {
105 /// Keys in dense id order (to_key[id] = key).
106 pub to_key: Vec<String>,
107 /// Permanently retired ids, sorted ascending.
108 pub tombstones: Vec<u32>,
109}
110
111// ---------------------------------------------------------------------------
112// Interner
113// ---------------------------------------------------------------------------
114
115/// Archived symbol interner: symbol ids map to their string names.
116#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
117pub struct InternerData {
118 /// to_str[sym] = name.
119 pub to_str: Vec<String>,
120}
121
122// ---------------------------------------------------------------------------
123// Shared string table (section 12)
124// ---------------------------------------------------------------------------
125
126/// The one string table a V9 snapshot carries for *every* `ColumnData::Str` in
127/// the columns section: `ids[node]` indexes into `strings`.
128///
129/// Up to V8 each string column carried its own `strings: Vec<String>` copy of
130/// the whole intern table, so a snapshot with K string columns paid for K
131/// copies. V9 writes the table once here and leaves every column's own
132/// `strings` empty. The resolution rule, in `seam.rs`'s `Str` arm and in
133/// `encode::archived_to_columnstore`, is one sentence: if the shared table is
134/// present it is the table, otherwise the column's own `strings` is — which is
135/// what keeps a pre-V9 snapshot, whose directory has no section 12, readable.
136#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
137pub struct StringTableData {
138 pub strings: Vec<String>,
139}
140
141// ---------------------------------------------------------------------------
142// Edge props (section 5)
143// ---------------------------------------------------------------------------
144
145/// One edge's property blob: (etype, src, dst) + bincode(BTreeMap<String, Value>).
146/// Entries in `EdgePropsData` are sorted by (etype, src, dst) for binary search.
147#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
148pub struct EdgePropEntry {
149 pub etype: u32,
150 pub src: u32,
151 pub dst: u32,
152 /// bincode-encoded `BTreeMap<String, Value>`.
153 pub props_blob: Vec<u8>,
154}
155
156/// All archived edge properties, sorted by (etype, src, dst).
157#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
158pub struct EdgePropsData {
159 pub entries: Vec<EdgePropEntry>,
160}
161
162// ---------------------------------------------------------------------------
163// HNSW (section 6)
164// ---------------------------------------------------------------------------
165
166/// Blob-per-rule HNSW storage. Each entry holds one rule's persisted graph for
167/// the src and dst sides. Stored as **opaque** bytes so core-storage remains
168/// independent of core-rules; zero-copy blob slicing avoids loading unused
169/// rules.
170///
171/// The blobs are self-describing: since 0.6.6 each carries its own magic
172/// (`MHNS`) and version, and core-rules' decoder also accepts a 0.6.5 store's
173/// bare bincoded index as version 1. Because this section never parses them,
174/// the blob format evolves without a snapshot format bump — and a reader that
175/// does not recognise a blob ignores it and falls back to a full scan.
176#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
177pub struct HnswRuleEntry {
178 pub name: String,
179 /// Opaque versioned HNSW blob for the source side.
180 pub src_blob: Vec<u8>,
181 /// Opaque versioned HNSW blob for the destination side.
182 pub dst_blob: Vec<u8>,
183}
184
185/// All per-rule HNSW graph blobs, sorted by rule name.
186#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
187pub struct HnswSectionData {
188 pub rules: Vec<HnswRuleEntry>,
189}
190
191// ---------------------------------------------------------------------------
192// Provenance (section 7)
193// ---------------------------------------------------------------------------
194
195/// A single provenance triple (etype, src, dst) serialized as three u32s.
196#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
197pub struct Triple {
198 pub etype: u32,
199 pub src: u32,
200 pub dst: u32,
201}
202
203/// Provenance triples for one rule, sorted by (etype, src, dst) ascending.
204/// Binary search replaces BTreeSet iteration on the read path.
205#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
206pub struct ProvenanceEntry {
207 pub rule: String,
208 pub triples: Vec<Triple>,
209}
210
211/// All per-rule provenance entries, sorted by rule name.
212#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
213pub struct ProvenanceSectionData {
214 pub entries: Vec<ProvenanceEntry>,
215}
216
217// ---------------------------------------------------------------------------
218// Rules meta (section 8)
219// ---------------------------------------------------------------------------
220
221/// Tripped (budget-trip) flag for one rule.
222#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
223pub struct RuleTripEntry {
224 pub rule: String,
225 pub tripped: bool,
226}
227
228/// Fire counter for one rule.
229#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
230pub struct RuleFireEntry {
231 pub rule: String,
232 pub fires: u64,
233}
234
235/// All rule definitions, trip flags, and fire counters.
236/// Entries in each sub-list are sorted by rule name.
237#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
238pub struct RulesMetaData {
239 /// One bincoded `RuleDef` per rule, in rule-name order.
240 pub rule_defs: Vec<Vec<u8>>,
241 pub tripped: Vec<RuleTripEntry>,
242 pub fires: Vec<RuleFireEntry>,
243}
244
245// ---------------------------------------------------------------------------
246// Views (section 9)
247// ---------------------------------------------------------------------------
248
249/// All materialized view definitions (one bincoded `ViewDef` per entry).
250#[derive(Archive, Serialize, Deserialize, Clone, Debug)]
251pub struct ViewsSectionData {
252 pub view_defs: Vec<Vec<u8>>,
253}
254
255// ---------------------------------------------------------------------------
256// Type aliases matching the binding interface
257// ---------------------------------------------------------------------------
258
259pub type ArchivedCsr = ArchivedCsrData;
260pub type ArchivedColumns = ArchivedColumnsData;
261pub type ArchivedIdMap = ArchivedIdMapData;
262pub type ArchivedInterner = ArchivedInternerData;
263pub type ArchivedEdgeProps = ArchivedEdgePropsData;
264pub type ArchivedHnsw = ArchivedHnswSectionData;
265pub type ArchivedProvenance = ArchivedProvenanceSectionData;
266pub type ArchivedRulesMeta = ArchivedRulesMetaData;
267pub type ArchivedViews = ArchivedViewsSectionData;
268pub type ArchivedStringTable = ArchivedStringTableData;