nodedb_types/namespace.rs
1//! Storage namespace identifiers for the blob KV store.
2//!
3//! Both SQLite (native) and OPFS (WASM) backends use the same namespace
4//! scheme to partition data by engine.
5
6use serde::{Deserialize, Serialize};
7
8/// Storage namespace. Each engine writes to its own namespace in the
9/// blob KV store, preventing key collisions.
10#[derive(
11 Debug,
12 Clone,
13 Copy,
14 PartialEq,
15 Eq,
16 Hash,
17 Serialize,
18 Deserialize,
19 rkyv::Archive,
20 rkyv::Serialize,
21 rkyv::Deserialize,
22)]
23#[repr(u8)]
24pub enum Namespace {
25 /// Database metadata: schema version, config, Shape subscriptions.
26 Meta = 0,
27 /// Vector engine: HNSW graph layers, vector data.
28 Vector = 1,
29 /// Graph engine: CSR arrays, node/label interning tables.
30 Graph = 2,
31 /// CRDT deltas: unsent mutations awaiting sync.
32 Crdt = 3,
33 /// Loro state snapshots: compacted CRDT state for fast cold-start.
34 LoroState = 4,
35 /// Spatial engine: R-tree checkpoints, geohash indexes.
36 Spatial = 5,
37 /// Strict document engine: Binary Tuple rows keyed by PK.
38 Strict = 6,
39 /// Columnar engine: compressed segments, delete bitmaps, segment metadata.
40 Columnar = 7,
41}
42
43impl Namespace {
44 /// Convert from raw u8 (for storage layer deserialization).
45 pub fn from_u8(v: u8) -> Option<Self> {
46 match v {
47 0 => Some(Self::Meta),
48 1 => Some(Self::Vector),
49 2 => Some(Self::Graph),
50 3 => Some(Self::Crdt),
51 4 => Some(Self::LoroState),
52 5 => Some(Self::Spatial),
53 6 => Some(Self::Strict),
54 7 => Some(Self::Columnar),
55 _ => None,
56 }
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn namespace_roundtrip() {
66 for v in 0u8..=7 {
67 let ns = Namespace::from_u8(v).unwrap();
68 assert_eq!(ns as u8, v);
69 }
70 assert!(Namespace::from_u8(8).is_none());
71 }
72}