# Engine Internals `Engine` owns the backend-local active graph and all indexes used by traversal, search composition, sync overlays, status reporting, and persistence. ## Engine Fields ', desc: 'edge label table; index 0 is reserved for untyped root edges' }, { name: 'resolution_store', type: 'ResolutionStore', desc: 'builder, finalized bytes, or mmap-backed lookup backend' }, { name: 'resolution_delta', type: 'ResolutionDeltaIndex', desc: 'indexed post-build inserts that cannot mutate finalized/mmap index' }, { name: '_mmap', type: 'Option', desc: 'owns mmap lifetime for mmap-backed stores' }, { name: 'edge_buffer', type: 'Vec', desc: 'post-build edge insert/delete overlay' }, { name: 'tenant_membership', type: 'HashMap', desc: 'tenant to allowed node set' } ]} /> ## Resolution Backends `ResolutionStore` has three modes: | Mode | When used | Lookup behavior | |---|---|---| | `Builder` | During node ingestion | Compact build entries | | `Finalized` | After `finalize_resolution()` | Binary search over sorted bytes | | `MmapBacked` | After loading a persisted artifact | Binary search over the mmap resolution section | `resolution_delta` is checked before the main backend. This keeps post-build sync inserts resolvable without rewriting the immutable finalized or mmap section. Unlike the build-time compact builder, the delta is keyed by `(table_oid, pk_hash)` so sync-time lookups verify only matching candidates instead of scanning every post-build insert. ## Edge Type Registry The registry starts as: ```text index 0 = "" index 1..254 = user edge labels ``` `Engine::register_edge_type()` returns existing IDs when labels are reused and raises `EdgeTypeLimit` after 254 user labels. The `u8` ID is stored in CSR parallel to each target edge. ## Traversal Dispatch Engine traversal does: 1. Verify the engine is built. 2. Resolve the seed table+PK to `node_idx`. 3. Resolve the requested edge label strings to compact `u8` IDs. 4. Build the edge overlay maps for the chosen direction. 5. Build `BfsConfig`. 6. Choose forward or reverse CSR based on direction. 7. Run BFS or DFS. 8. Convert node indices back to source coordinates and edge labels. - `bfs::execute` - `bfs::execute_dfs` ## Sync Overlay Semantics `edge_buffer` contains ordered mutations: ```rust pub struct EdgeMutation { pub source: u32, pub target: u32, pub type_id: u8, pub kind: MutationKind, } ``` Before traversal, the engine reduces the buffer into: | Overlay | Type | Meaning | |---|---|---| | inserts | `HashMap>` | Extra neighbors by source node | | deletes | `HashMap>` | Base edges hidden from traversal, keyed by source node | Insert after delete cancels the delete; delete after insert cancels the insert. ## Status Computation `Engine::status()` returns counts, memory estimates, sync status, schema state, edge labels, pending sync state, and read-only flags. Some fields are refreshed by SQL runtime helpers before calling `Engine::status()`, including disabled trigger count, pending sync rows, and schema drift. ## Important Invariants | Invariant | Why it matters | |---|---| | `edge_type_registry[0] == ""` | Root/path formatting assumes ID 0 is reserved | | `reverse_edge_store` matches `edge_store` | Inbound traversal must avoid scanning all edges | | `resolution_delta` is checked first | Synced inserts shadow immutable base indexes | | `resolution_delta` verifies candidates through `node_store` | Tombstones and hash collisions cannot resolve stale or wrong nodes | | Mmap store pointers never outlive `Engine._mmap` | Raw pointer reads depend on mmap lifetime | | `node_store.is_active()` gates resolved nodes | Tombstones must not appear as live results | | `edge_buffer.len() <= graph.edge_buffer_size` | Prevents unbounded overlay memory |