Skip to main content

nodedb_types/
namespace.rs

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