Skip to main content

RuleEngine

Struct RuleEngine 

Source
pub struct RuleEngine { /* private fields */ }

Implementations§

Source§

impl RuleEngine

Source

pub fn new() -> Self

Source

pub fn rules(&self) -> impl Iterator<Item = &RuleDef>

Source

pub fn is_owned(&self, etype: u32, src: u32, dst: u32) -> bool

Source

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).

Source

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.

Source

pub fn provenance_touching_len(&self, node: u32) -> usize

Number of provenance triples incident on node.

Source

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).

Source

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).

Source

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.

Source

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.

Source

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.

Source

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).

Source

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.

Source

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.

Source

pub fn emit_deltas(&self) -> bool

Whether delta accumulation is currently enabled.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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 field fire; 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.

Source

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).

Source

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).

Source

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.

Trait Implementations§

Source§

impl Debug for RuleEngine

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for RuleEngine

Source§

fn default() -> RuleEngine

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.