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}