pub struct RuleEngine { /* private fields */ }Implementations§
Source§impl RuleEngine
impl RuleEngine
pub fn new() -> Self
pub fn rules(&self) -> impl Iterator<Item = &RuleDef>
pub fn is_owned(&self, etype: u32, src: u32, dst: u32) -> bool
Sourcepub fn provenance(&self) -> &BTreeMap<String, BTreeSet<(u32, u32, u32)>>
pub fn provenance(&self) -> &BTreeMap<String, BTreeSet<(u32, u32, u32)>>
Read-only view of the provenance map: rule name → set of (etype_sym, src, dst).
Sourcepub fn provenance_touching(
&self,
node: u32,
) -> impl Iterator<Item = (&str, u32, u32, u32)> + '_
pub fn provenance_touching( &self, node: u32, ) -> impl Iterator<Item = (&str, u32, u32, u32)> + '_
O(degree) reverse-index lookup: every provenance triple that touches node.
Sourcepub fn provenance_touching_len(&self, node: u32) -> usize
pub fn provenance_touching_len(&self, node: u32) -> usize
Number of provenance triples incident on node.
Sourcepub fn is_tripped(&self, name: &str) -> bool
pub fn is_tripped(&self, name: &str) -> bool
One-way latch: true after a budget breach until Self::rebuild
is the only exit (and only if the full desired set then fits).
Sourcepub fn fire_count(&self, name: &str) -> u64
pub fn fire_count(&self, name: &str) -> u64
Evaluations of this rule: one tick per on_node_changed fire, and
one tick per participating node on backfill and rebuild (even
when rebuild is a provenance no-op).
Sourcepub fn drain_deltas(&mut self) -> Vec<EngineEdgeDelta>
pub fn drain_deltas(&mut self) -> Vec<EngineEdgeDelta>
Drain and return all pending edge-fire / retract deltas since the last
call. Callers (db.rs log_then_apply_with) invoke this after a
successful WAL commit + apply to build [DbEvent]s for live
subscriptions. [GraphDb::open_with] drains and discards after WAL
replay so replay noise never leaks to subscribers.
§T2 note (as-of replay)
When Plan-15 T2 adds as-of replay for subscribers, that path should
call apply-only (no log_then_apply_with) and then call
drain_deltas() to feed those events to the replaying subscriber.
The suppression is already in place: apply accumulates but never
emits; drain_deltas is the only emission gate.
Sourcepub fn pending_delta_count(&self) -> usize
pub fn pending_delta_count(&self) -> usize
Number of accumulated deltas not yet drained. Used by
debug_assert in log_then_apply_with to catch stale-delta bugs.
Sourcepub fn pending_deltas_since(&self, cursor: usize) -> &[EngineEdgeDelta]
pub fn pending_deltas_since(&self, cursor: usize) -> &[EngineEdgeDelta]
Borrow the slice of deltas accumulated since cursor without
consuming them. cursor should be the value returned by
pending_delta_count() before an engine call.
The returned slice is valid until the next call to drain_deltas().
T1’s drain discipline is preserved: these deltas are still in the
buffer and will be drained by log_then_apply_with after apply
returns.
Sourcepub fn to_persist(
&self,
) -> (Vec<RuleDef>, BTreeMap<String, BTreeSet<(u32, u32, u32)>>, BTreeMap<String, bool>, BTreeMap<String, u64>)
pub fn to_persist( &self, ) -> (Vec<RuleDef>, BTreeMap<String, BTreeSet<(u32, u32, u32)>>, BTreeMap<String, bool>, BTreeMap<String, u64>)
Snapshot support: definitions + provenance + tripped/fires. Candidate
indexes and the by_node reverse index are NOT included (derived:
reindex_all / rebuild_by_node on open).
Sourcepub fn from_persist(
rules: Vec<RuleDef>,
prov: BTreeMap<String, BTreeSet<(u32, u32, u32)>>,
tripped: BTreeMap<String, bool>,
fires: BTreeMap<String, u64>,
) -> Self
pub fn from_persist( rules: Vec<RuleDef>, prov: BTreeMap<String, BTreeSet<(u32, u32, u32)>>, tripped: BTreeMap<String, bool>, fires: BTreeMap<String, u64>, ) -> Self
Reconstruct engine from a snapshot. Caller must call reindex_all after.
Sourcepub fn set_emit_deltas(&mut self, emit: bool)
pub fn set_emit_deltas(&mut self, emit: bool)
Enable or disable delta accumulation.
Set to true before the first subscriber or view is added.
Set to false when the last subscriber and last view are removed.
See the emit_deltas field doc for the safety invariant.
Sourcepub fn emit_deltas(&self) -> bool
pub fn emit_deltas(&self) -> bool
Whether delta accumulation is currently enabled.
Sourcepub fn take_rebuild_needed(&mut self) -> Vec<String>
pub fn take_rebuild_needed(&mut self) -> Vec<String>
Drain rule names that exceeded the IVF dst-drift rebuild threshold
during the most recent on_node_changed / on_node_removed.
Sourcepub fn queue_rebuild_needed(&mut self, name: String)
pub fn queue_rebuild_needed(&mut self, name: String)
Re-queue name so a later write can issue RebuildRule.
Used when auto-rebuild WAL IO fails after a durable user op.
Sourcepub fn export_ivf_state(&self) -> BTreeMap<String, RuleIvfExport>
pub fn export_ivf_state(&self) -> BTreeMap<String, RuleIvfExport>
Export IVF state for all approximate rules. Passed to snapshot() in
core-api and stored in the V4 snapshot so open() can restore cluster
assignments without re-fitting k-means.
Sourcepub fn reindex_all(
&mut self,
ids: &IdMap,
syms: &Interner,
labels: &[u32],
props: &ColumnStore,
)
pub fn reindex_all( &mut self, ids: &IdMap, syms: &Interner, labels: &[u32], props: &ColumnStore, )
Rebuild all candidate indexes by scanning every node. Call on open.
Sourcepub fn reindex_all_load_ivf(
&mut self,
ids: &IdMap,
syms: &Interner,
labels: &[u32],
props: &ColumnStore,
ivf_state: BTreeMap<String, RuleIvfExport>,
)
pub fn reindex_all_load_ivf( &mut self, ids: &IdMap, syms: &Interner, labels: &[u32], props: &ColumnStore, ivf_state: BTreeMap<String, RuleIvfExport>, )
Like reindex_all but LOADS persisted IVF state for approximate rules
instead of re-fitting k-means. This eliminates the cold-start re-fit
cost when opening a V4 snapshot.
ivf_state: map from rule name to (src_export, dst_export) as
produced by export_ivf_state / stored in the V4 snapshot.
For approximate rules absent from ivf_state (e.g. a rule added
after the snapshot), falls back to fit_ivf_clusters.
Sourcepub fn export_hnsw_state(&self) -> BTreeMap<String, (Vec<u8>, Vec<u8>)>
pub fn export_hnsw_state(&self) -> BTreeMap<String, (Vec<u8>, Vec<u8>)>
Export HNSW graphs for all approximate rules as opaque bincoded blobs.
Returns a map from rule name to (src_blob, dst_blob). An empty Vec
means the corresponding side has no initialized HNSW graph.
Sourcepub fn load_hnsw_state(&mut self, blobs: BTreeMap<String, (Vec<u8>, Vec<u8>)>)
pub fn load_hnsw_state(&mut self, blobs: BTreeMap<String, (Vec<u8>, Vec<u8>)>)
Restore HNSW graphs from bincoded blobs (overrides any incrementally built
graphs produced during reindex_all_load_ivf).
Called from restore_snapshot_state in db.rs after reindex.
Sourcepub fn hnsw_search_dst(
&self,
field: &str,
dst_label: &str,
q: &[f64],
k: usize,
) -> Option<Vec<(u32, f64)>>
pub fn hnsw_search_dst( &self, field: &str, dst_label: &str, q: &[f64], k: usize, ) -> Option<Vec<(u32, f64)>>
Find approximate nearest-neighbor ids on the dst side of the first
approximate VectorSimilar rule covering (dst_label, field).
Returns None when no matching rule or HNSW index exists.
Sourcepub fn create_rule(
&mut self,
def: RuleDef,
g: &mut GraphMut<'_>,
) -> Result<(), String>
pub fn create_rule( &mut self, def: RuleDef, g: &mut GraphMut<'_>, ) -> Result<(), String>
Register a rule and backfill existing nodes. Returns Err on failed validate() or duplicate name.
Sourcepub fn delete_rule(
&mut self,
name: &str,
g: &mut GraphMut<'_>,
) -> Result<(), String>
pub fn delete_rule( &mut self, name: &str, g: &mut GraphMut<'_>, ) -> Result<(), String>
Remove the rule and exactly its owned edges. Returns Err if unknown.
Sourcepub fn on_node_changed(
&mut self,
n: u32,
changed: Option<(&str, Option<Value>)>,
g: &mut GraphMut<'_>,
)
pub fn on_node_changed( &mut self, n: u32, changed: Option<(&str, Option<Value>)>, g: &mut GraphMut<'_>, )
Called when node n is inserted (changed=None) or a field is updated.
- None: all rules where n’s label matches either side fire; index gains n.
- Some((field, old_value)): only rules watching
fieldfire; index is updated using old_value for removal so stale buckets are cleaned.
For via-hop rules (def.via_label.is_some()), also fires when n carries
the via-label: finds all srcs that route through n and recomputes their
derived edges. Via-hop rules bypass the candidate index and use
compute_desired_via instead.
Sourcepub fn on_edge_changed(
&mut self,
etype_str: &str,
src_id: u32,
dst_id: u32,
g: &mut GraphMut<'_>,
)
pub fn on_edge_changed( &mut self, etype_str: &str, src_id: u32, dst_id: u32, g: &mut GraphMut<'_>, )
Called when a user edge (etype_str, src_id, dst_id) is inserted or
deleted (not a derived edge — those are managed by provenance, not here).
For any via-hop rule where via_edge == etype_str and src_id carries
src_label, the src_id’s desired derived-edge set may have changed:
a new WORKS_AT edge makes a new Org reachable as a via-node, and a
deleted WORKS_AT removes a previously reachable Org.
This is the only hook the engine exposes for topology changes. It is
called from db.rs on WalRecord::InsertEdge and WalRecord::DeleteEdge
immediately after the topo is updated (so g.topo already reflects the
new state).
Sourcepub fn on_node_removed(&mut self, n: u32, g: &mut GraphMut<'_>)
pub fn on_node_removed(&mut self, n: u32, g: &mut GraphMut<'_>)
Retract every provenance edge touching n across all rules and drop
n from every rule index using its current props.
Caller must invoke this while labels/props are still intact (before tombstone). Rules are walked in BTree name order; touching edges in BTree triple order. A second call on an already-retracted node is a no-op (crash-window replay / absent state).
Sourcepub fn rebuild(
&mut self,
name: &str,
g: &mut GraphMut<'_>,
) -> Result<(), String>
pub fn rebuild( &mut self, name: &str, g: &mut GraphMut<'_>, ) -> Result<(), String>
Recompute one rule from scratch. Only exit from the tripped latch.
If the full desired set fits in the budget, it is applied completely
and tripped is cleared. If it still exceeds the budget, existing
provenance is left completely untouched and tripped stays true
(rebuild-is-noop for at/over-cap rules). Always counts as a fire
evaluation per participating node. Returns Err if unknown.