Skip to main content

nodedb_mem/
engine.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! Engine identification for memory budget tracking.
4
5/// Identifies a subsystem that owns a memory budget.
6///
7/// Each engine operates within its allocated memory ceiling. The governor
8/// tracks allocations per engine and rejects requests that would exceed
9/// the budget.
10///
11/// Covers all eight peer engines (Document schemaless, Document strict, KV,
12/// Columnar, Timeseries, Spatial, Vector, Array), plus the two cross-engine
13/// overlays (Graph, Fts), plus infrastructure subsystems (Sparse metadata,
14/// Crdt, Query, Wal, Bridge).
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
16pub enum EngineId {
17    /// HNSW vector index, distance computation buffers, quantized caches.
18    Vector,
19
20    /// CSR adjacency index, traversal algorithm working sets (cross-engine overlay).
21    Graph,
22
23    /// Document (schemaless): MessagePack blobs, secondary index buffers.
24    DocumentSchemaless,
25
26    /// Document (strict): Binary Tuple encode/decode buffers, schema metadata.
27    DocumentStrict,
28
29    /// Key-Value engine: hash index buckets, TTL expiry wheel.
30    Kv,
31
32    /// Columnar engine: compressed segment build buffers, block statistics.
33    Columnar,
34
35    /// Gorilla-encoded memtables, Zstd dictionaries, log buffers.
36    Timeseries,
37
38    /// R*-tree node pools, geohash / H3 index structures.
39    Spatial,
40
41    /// Array engine (ND sparse): tile decompression buffers, coordinate arrays.
42    Array,
43
44    /// FTS LSM memtable, posting lists, compaction merge buffers (cross-engine overlay).
45    Fts,
46
47    /// redb B-Tree, splintr inverted index, schema metadata (sparse/metadata engine).
48    Sparse,
49
50    /// loro CRDT state, merge buffers, operation logs.
51    Crdt,
52
53    /// DataFusion query execution: sorts, aggregates, hash tables.
54    Query,
55
56    /// WAL write buffers, group commit staging.
57    Wal,
58
59    /// SPSC bridge buffers, slab allocator, envelope staging.
60    Bridge,
61}
62
63impl EngineId {
64    /// All known engine identifiers (for iteration in the governor).
65    pub const ALL: &'static [EngineId] = &[
66        EngineId::Vector,
67        EngineId::Graph,
68        EngineId::DocumentSchemaless,
69        EngineId::DocumentStrict,
70        EngineId::Kv,
71        EngineId::Columnar,
72        EngineId::Timeseries,
73        EngineId::Spatial,
74        EngineId::Array,
75        EngineId::Fts,
76        EngineId::Sparse,
77        EngineId::Crdt,
78        EngineId::Query,
79        EngineId::Wal,
80        EngineId::Bridge,
81    ];
82
83    /// Number of known engine identifiers.
84    pub const COUNT: usize = Self::ALL.len();
85
86    /// Dense array index for this engine, for use with fixed-size
87    /// per-engine arrays sized `EngineId::COUNT`.
88    ///
89    /// `EngineId` is a fieldless enum, so the discriminant cast matches the
90    /// declaration position, and `ALL` lists variants in that same order —
91    /// the inline test below locks the two together.
92    pub const fn index(self) -> usize {
93        self as usize
94    }
95}
96
97impl std::fmt::Display for EngineId {
98    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99        match self {
100            EngineId::Vector => write!(f, "vector"),
101            EngineId::Graph => write!(f, "graph"),
102            EngineId::DocumentSchemaless => write!(f, "document_schemaless"),
103            EngineId::DocumentStrict => write!(f, "document_strict"),
104            EngineId::Kv => write!(f, "kv"),
105            EngineId::Columnar => write!(f, "columnar"),
106            EngineId::Timeseries => write!(f, "timeseries"),
107            EngineId::Spatial => write!(f, "spatial"),
108            EngineId::Array => write!(f, "array"),
109            EngineId::Fts => write!(f, "fts"),
110            EngineId::Sparse => write!(f, "sparse"),
111            EngineId::Crdt => write!(f, "crdt"),
112            EngineId::Query => write!(f, "query"),
113            EngineId::Wal => write!(f, "wal"),
114            EngineId::Bridge => write!(f, "bridge"),
115        }
116    }
117}
118
119#[cfg(test)]
120mod tests {
121    use super::*;
122
123    #[test]
124    fn index_matches_all_declaration_order() {
125        assert_eq!(EngineId::ALL.len(), EngineId::COUNT);
126        for id in EngineId::ALL {
127            assert_eq!(EngineId::ALL[id.index()], *id);
128        }
129    }
130}