Skip to main content

MaterializedGraph

Struct MaterializedGraph 

Source
pub struct MaterializedGraph {
    pub nodes: HashMap<String, Node>,
    pub edges: HashMap<String, Edge>,
    pub outgoing: HashMap<String, HashSet<String>>,
    pub incoming: HashMap<String, HashSet<String>>,
    pub by_type: HashMap<String, HashSet<String>>,
    pub ontology: Ontology,
    pub quarantined: HashSet<Hash>,
}
Expand description

Materialized graph — derived from the op log.

Provides fast queries without replaying the full log. Updated incrementally as new entries arrive, or rebuilt from scratch by replaying the entire op log.

CRDT semantics:

  • Add-wins for topology (concurrent add + remove → node/edge exists)
  • LWW (Last-Writer-Wins) per property key (highest Lamport clock wins)
  • Tombstones for deletes (mark as deleted, don’t physically remove)

Fields§

§nodes: HashMap<String, Node>

node_id → Node

§edges: HashMap<String, Edge>

edge_id → Edge

§outgoing: HashMap<String, HashSet<String>>

node_id → set of outgoing edge_ids

§incoming: HashMap<String, HashSet<String>>

node_id → set of incoming edge_ids

§by_type: HashMap<String, HashSet<String>>

node_type → set of node_ids (type index)

§ontology: Ontology

The ontology (for validation during materialization)

§quarantined: HashSet<Hash>

R-02: entries that failed ontology validation during apply(). These entries exist in the oplog (for CRDT convergence) but are invisible in the materialized graph. Grow-only set — monotonic, safe.

Implementations§

Source§

impl MaterializedGraph

Source

pub fn new(ontology: Ontology) -> Self

Create an empty materialized graph with the given ontology.

Source

pub fn apply(&mut self, entry: &Entry)

Apply a single entry to the graph (incremental materialization).

R-02: Validates AddNode/AddEdge payloads against the ontology. Invalid entries are quarantined (added to self.quarantined) and skipped for materialization. They remain in the oplog for CRDT convergence — quarantine is a graph-layer concern, not an oplog concern.

Source

pub fn apply_all(&mut self, entries: &[&Entry])

Apply a sequence of entries (full rematerialization from op log).

Source

pub fn rebuild(&mut self, entries: &[&Entry])

Rebuild from scratch: clear everything and replay all entries.

Source

pub fn get_node(&self, node_id: &str) -> Option<&Node>

Get a node by ID (returns None if not found or tombstoned).

Source

pub fn get_edge(&self, edge_id: &str) -> Option<&Edge>

Get an edge by ID (returns None if not found or tombstoned).

Source

pub fn nodes_by_type(&self, node_type: &str) -> Vec<&Node>

Query all live nodes of a given type.

Source

pub fn nodes_by_subtype(&self, subtype: &str) -> Vec<&Node>

Query all live nodes of a given subtype.

Source

pub fn nodes_by_property(&self, key: &str, value: &Value) -> Vec<&Node>

Query nodes by a property value.

Source

pub fn outgoing_edges(&self, node_id: &str) -> Vec<&Edge>

Get outgoing edges for a node (only live edges with live endpoints).

Source

pub fn incoming_edges(&self, node_id: &str) -> Vec<&Edge>

Get incoming edges for a node (only live edges with live endpoints).

Source

pub fn all_nodes(&self) -> Vec<&Node>

All live nodes.

Source

pub fn all_edges(&self) -> Vec<&Edge>

All live edges (with live endpoints).

Source

pub fn neighbors(&self, node_id: &str) -> Vec<&str>

Neighbors of a node (connected via outgoing edges).

Source

pub fn reverse_neighbors(&self, node_id: &str) -> Vec<&str>

Reverse neighbors (connected via incoming edges).

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 = Infallible

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.