Skip to main content

Graph

Struct Graph 

Source
pub struct Graph { /* private fields */ }
Expand description

The graph database handle. Cheap to clone: all state is behind Arc.

Implementations§

Source§

impl Graph

Source

pub fn dfs(&self, start: NodeId, hops: u8) -> Result<Vec<NodeId>, Error>

Depth-first search outward from start up to hops levels deep.

Source

pub fn count_triangle_cycles( &self, spec: &TriangleCountSpec<'_>, ) -> Result<u64, Error>

Counts variable assignments of the directed triangle pattern (a)-[t1]->(b)-[t2]->(c)-[t3]->(a) under spec’s per-hop relationship types and per-variable labels.

The count follows Cypher MATCH semantics: each distinct assignment of (a, b, c, e1, e2, e3) is one match, so a single 3-cycle of distinct nodes counts once per rotation of a (three when all hops share one type), parallel edges multiply, and the three relationships must be pairwise distinct (relationship uniqueness), which only constrains self-loop assignments where a == b == c.

Source

pub fn count_linear_paths(&self, spec: &PathCountSpec<'_>) -> Result<u64, Error>

Counts variable assignments of an open directed path of one or two hops under spec’s per-hop relationship types and per-variable labels, with no materialization of the matched rows.

The count follows Cypher MATCH semantics: each distinct assignment of the node and relationship variables is one match, nodes may repeat, parallel edges multiply, and for the two-hop pattern the two relationships must be distinct (relationship uniqueness). That uniqueness only removes assignments where a single edge could fill both hops, which requires a self-loop shared by both hops.

The Cypher optimizer lowers a grouping-free count over a one-hop or two-hop directed expansion to this kernel via the PathCount physical operator.

Source

pub fn grouped_edge_counts( &self, spec: &GroupedDegreeSpec<'_>, ) -> Result<Vec<(NodeId, u64)>, Error>

Counts typed edges grouped by one endpoint, returning (group node id, count) for every group node with a non-zero count. See GroupedDegreeSpec for the grouping and filtering semantics.

This scans the CSR snapshot’s outgoing adjacency once, incrementing a per-node counter, so it is O(nodes + edges) with no per-edge row materialization. It is the kernel the Cypher optimizer lowers a count aggregation grouped by one endpoint of a single directed hop to (the GroupedDegree physical operator), turning what would be a full expansion-and-fold into an integer pass over adjacency.

Source

pub fn detect_cycle(&self) -> Result<bool, Error>

Detects if there is at least one directed cycle in the graph.

Source

pub fn all_neighbors( &self, node: NodeId, ) -> Result<Vec<DirectedNeighborEntry>, Error>

Returns directed neighbor entries for all outgoing and incoming edges of node.

Source

pub fn all_paths( &self, src: NodeId, dst: NodeId, ) -> Result<Vec<Vec<NodeId>>, Error>

Returns all simple paths (no repeated nodes) between src and dst.

Source

pub fn all_shortest_paths( &self, src: NodeId, dst: NodeId, ) -> Result<Vec<Vec<NodeId>>, Error>

Returns all unweighted shortest paths between src and dst.

Source

pub fn longest_path( &self, src: NodeId, dst: NodeId, ) -> Result<Option<Vec<NodeId>>, Error>

Returns the longest simple path (no repeated nodes) between src and dst.

Source

pub fn shortest_path_dijkstra( &self, src: NodeId, dst: NodeId, ) -> Result<Option<WeightedPath>, Error>

Computes the weighted shortest path between src and dst using Dijkstra’s algorithm.

Edge weights come from the materialized CSR snapshot, which reads the first present of the weight, cost, capacity, or cap edge properties, defaulting to 1.0. The weight source is fixed: unlike shortest_path_top_k and spanning_forest, this method does not take a weight-property argument.

Source

pub fn spanning_forest( &self, weight_property: &str, maximum: bool, ) -> Result<Vec<EdgeId>, Error>

Computes the Minimum or Maximum Spanning Forest (MSF) of the graph.

Source

pub fn label_propagation( &self, max_iterations: usize, ) -> Result<HashMap<NodeId, u64>, Error>

Computes community detection on the graph using the Label Propagation Algorithm (LPA / CDLP).

Source

pub fn harmonic_centrality(&self) -> Result<HashMap<NodeId, f64>, Error>

Computes the harmonic closeness centrality for all nodes in the graph.

Source

pub fn betweenness_centrality(&self) -> Result<HashMap<NodeId, f64>, Error>

Computes the betweenness centrality for all nodes in the graph.

Source

pub fn strongly_connected_components( &self, ) -> Result<HashMap<NodeId, u64>, Error>

Computes the strongly connected components (SCC) of the graph using Tarjan’s algorithm.

Source

pub fn degree_centrality( &self, direction: DegreeDirection, ) -> Result<HashMap<NodeId, u64>, Error>

Computes the degree centrality for all nodes in the graph based on the specified direction.

Source

pub fn maximum_flow( &self, source: NodeId, sink: NodeId, capacity_property: &str, ) -> Result<f64, Error>

Computes the maximum flow from a source node to a sink node.

Source

pub fn shortest_path_top_k( &self, src: NodeId, dst: NodeId, k: usize, weight_property: &str, ) -> Result<Vec<WeightedPath>, Error>

Computes the K shortest paths from a source node to a destination node using Yen’s algorithm.

Source

pub fn bfs(&self, start: NodeId, hops: u8) -> Result<Vec<NodeId>, Error>

Breadth-first search outward from start up to hops levels deep.

Source

pub fn shortest_path( &self, src: NodeId, dst: NodeId, ) -> Result<Option<Vec<NodeId>>, Error>

Unweighted shortest path from src to dst by BFS.

Source

pub fn page_rank( &self, iterations: u32, damping: f32, ) -> Result<HashMap<NodeId, f32>, Error>

Iterative PageRank over the current CSR snapshot.

Source

pub fn all_nodes(&self) -> Result<Vec<NodeId>, Error>

Returns all node IDs in the graph in ascending order.

Source

pub fn connected_components(&self) -> Result<HashMap<NodeId, u64>, Error>

Weakly connected components via BFS treating all edges as undirected.

Returns a map from each node ID to a component ID. Component IDs are assigned in ascending order of first discovery and have no guaranteed relationship to node IDs.

Source§

impl Graph

Source

pub fn add_edge( &self, src: NodeId, dst: NodeId, etype: &str, props: &impl Serialize, ) -> Result<EdgeId, Error>

Insert a directed edge src → dst with a string type and properties.

Source

pub fn update_edge( &self, id: EdgeId, props: &impl Serialize, ) -> Result<(), Error>

Update the properties of an existing edge, preserving src, dst, and type.

Source

pub fn get_edge(&self, id: EdgeId) -> Result<Option<EdgeRecord>, Error>

Fetch an edge record by id.

Source

pub fn delete_edge(&self, id: EdgeId) -> Result<(), Error>

Delete an edge.

Source

pub fn out_neighbors(&self, node: NodeId) -> Result<Vec<NeighborEntry>, Error>

Returns neighbor entries for all outgoing edges of node.

Reads the out_adj store directly through the supplied transaction so the result always reflects committed (and, inside a WriteTxn, uncommitted) writes. The CSR snapshot is deliberately not consulted here: it lags writes until the background rebuild runs, so serving point lookups from it would return deleted edges, hide newly added ones, and disagree with Self::in_neighbors. The snapshot remains the basis for the GraphBLAS matrix algorithms, which have explicit snapshot semantics.

Source

pub fn in_neighbors(&self, node: NodeId) -> Result<Vec<NeighborEntry>, Error>

Returns neighbor entries for all incoming edges of node.

Source

pub fn node_has_relationships(&self, node: NodeId) -> Result<bool, Error>

Returns whether the node has any incident relationship, reading the adjacency stores directly. Unlike Self::out_neighbors, this never consults the CSR snapshot, which lags writes until the background rebuild completes. Write-time consistency checks (such as the DELETE connected-node guard) must see just-applied edge deletions, so they rely on this method.

Source§

impl Graph

Source

pub fn nodes_by_label(&self, label: &str) -> Result<Vec<NodeId>, Error>

Returns all node IDs with the given label, in ascending ID order.

Source

pub fn edges_by_type(&self, etype: &str) -> Result<Vec<EdgeId>, Error>

Returns all edge IDs with the given type, in ascending ID order.

Source

pub fn label_name(&self, id: LabelId) -> Result<Option<String>, Error>

Resolves a LabelId back to its string name.

Scans the meta sub-database for the matching label:{name} entry. Returns None for ids that are not in the registry.

Source

pub fn type_name(&self, id: TypeId) -> Result<Option<String>, Error>

Resolves a TypeId back to its string name.

Scans the meta sub-database for the matching type:{name} entry. Returns None for ids that are not in the registry.

Source

pub fn node_count_by_label(&self, label: &str) -> Result<u64, Error>

Get the count of nodes matching a string label.

Source

pub fn node_count_hint(&self) -> Result<u64, Error>

Upper-bound estimate of the node count: the node-id high-water mark. This does not decrease when a node is deleted, so it is not an exact live count; it exists for query-planner cardinality estimates (for example, average relationship fan-out). O(1).

Source

pub fn edge_count_by_type(&self, etype: &str) -> Result<u64, Error>

Get the count of edges matching a string type.

Source

pub fn create_node_property_index( &self, label: &str, property: &str, ) -> Result<(), Error>

Source

pub fn create_node_unique_constraint( &self, label: &str, property: &str, ) -> Result<(), Error>

Source

pub fn create_node_required_constraint( &self, label: &str, property: &str, ) -> Result<(), Error>

Source

pub fn drop_node_property_index( &self, label: &str, property: &str, ) -> Result<(), Error>

Source

pub fn drop_node_unique_constraint( &self, label: &str, property: &str, ) -> Result<(), Error>

Source

pub fn drop_node_required_constraint( &self, label: &str, property: &str, ) -> Result<(), Error>

Source

pub fn create_edge_property_index( &self, etype: &str, property: &str, ) -> Result<(), Error>

Source

pub fn create_edge_unique_constraint( &self, etype: &str, property: &str, ) -> Result<(), Error>

Source

pub fn create_edge_required_constraint( &self, etype: &str, property: &str, ) -> Result<(), Error>

Source

pub fn drop_edge_property_index( &self, etype: &str, property: &str, ) -> Result<(), Error>

Source

pub fn drop_edge_unique_constraint( &self, etype: &str, property: &str, ) -> Result<(), Error>

Source

pub fn drop_edge_required_constraint( &self, etype: &str, property: &str, ) -> Result<(), Error>

Source

pub fn nodes_by_property( &self, label: &str, property: &str, val: PropValue, ) -> Result<Vec<NodeId>, Error>

Source

pub fn nodes_by_property_range( &self, label: &str, property: &str, min_val: Option<PropValue>, min_inclusive: bool, max_val: Option<PropValue>, max_inclusive: bool, ) -> Result<Vec<NodeId>, Error>

Source

pub fn has_node_property_index( &self, label: &str, property: &str, ) -> Result<bool, Error>

Source

pub fn edges_by_property( &self, etype: &str, property: &str, val: PropValue, ) -> Result<Vec<EdgeId>, Error>

Source

pub fn edges_by_property_range( &self, etype: &str, property: &str, min_val: Option<PropValue>, max_val: Option<PropValue>, ) -> Result<Vec<EdgeId>, Error>

Source

pub fn list_node_indexes_and_constraints( &self, ) -> Result<Vec<(String, String, u8)>, Error>

Source

pub fn list_edge_indexes_and_constraints( &self, ) -> Result<Vec<(String, String, u8)>, Error>

Source§

impl Graph

Source

pub fn add_node( &self, label: &str, props: &impl Serialize, ) -> Result<NodeId, Error>

Insert a node with a single string label and msgpack-serializable properties.

Source

pub fn add_node_multi( &self, labels: &[&str], props: &impl Serialize, ) -> Result<NodeId, Error>

Insert a node with zero or more string labels and msgpack-serializable properties. An empty slice creates an unlabeled node.

Source

pub fn get_node(&self, id: NodeId) -> Result<Option<NodeRecord>, Error>

Fetch a node record by id.

Source

pub fn update_node( &self, id: NodeId, props: &impl Serialize, ) -> Result<(), Error>

Update the properties of an existing node. The node’s label is unchanged.

§Deadlock warning

Do not call this method from inside a Graph::update closure. Use WriteTxn::update_node inside the closure instead.

Source

pub fn add_label(&self, id: NodeId, label: &str) -> Result<(), Error>

Add a label to an existing node. No-op if the node already carries it.

Source

pub fn remove_label(&self, id: NodeId, label: &str) -> Result<(), Error>

Remove a label from an existing node. No-op if the node lacks the label, the label was never registered, or the node does not exist.

Source

pub fn node_labels(&self, id: NodeId) -> Result<Vec<String>, Error>

Return the string labels of a node in insertion order. Returns an empty vector for an unlabeled or nonexistent node.

Source

pub fn delete_node(&self, id: NodeId) -> Result<(), Error>

Delete a node.

Source§

impl Graph

Source

pub fn estimate_expand_fanout( &self, src_label: &str, rel_type: &str, incoming: bool, ) -> Result<Option<f64>, Error>

Estimated average fan-out for expanding edges of rel_type from a node carrying src_label: the per-source-label typed out-degree, or the typed in-degree when incoming is true.

Returns the count of qualifying edges divided by the count of src_label nodes. Returns None when the label or type is unknown, the label has no nodes, or no such edges exist, so the caller can fall back to the global average fan-out. The underlying frequency table is recomputed lazily when committed writes advance past the cached generation; because the result only weights plan choices, a stale or absent estimate never affects query correctness.

Source

pub fn estimate_expand_fanout_to( &self, src_label: &str, rel_type: &str, dst_label: &str, incoming: bool, ) -> Result<Option<f64>, Error>

Destination-label-aware fan-out: the average number of dst_label neighbors reached by expanding edges of rel_type from a node carrying src_label (or the symmetric in-direction when incoming).

This sharpens Graph::estimate_expand_fanout when the expansion target also carries a label, dividing the realized (src_label, type, dst_label) triple count by the src_label node count instead of the type marginal. Returns None (fall back to the marginal or the global average) when a label or type is unknown, the source label has no nodes, or no such triple exists.

Source

pub fn schema_has_edge( &self, src_label: &str, rel_type: &str, dst_label: &str, ) -> Result<Option<bool>, Error>

Whether the data schema contains any directed edge src_label --rel_type--> dst_label. Returns Some(false) when the labels and type are all known but no such edge exists (the directed pattern is unsatisfiable), and None when any of the three names is unknown to the registry, so the caller cannot decide.

The underlying schema table reflects all committed writes (it is rebuilt when the write generation advances), so a Some(false) is authoritative for committed state. Callers that prune work on this answer must guard against uncommitted same-statement writes, which the table cannot see.

Source§

impl Graph

Source

pub fn open(path: &Path, map_size_gb: usize) -> Result<Self, Error>

Source

pub fn set_thread_count(&self, n: i32) -> Result<(), Error>

Set the thread count for GraphBLAS matrix computations, overriding the ISSUNDB_NUM_THREADS environment variable. Set to 0 to restore the default behavior.

Source

pub fn node_prop_json( &self, id: NodeId, prop: &str, ) -> Result<Option<Value>, Error>

Read one property of a node through the in-memory property columns, as the serde_json::Value that decoding the stored record would give. Returns None for a nonexistent node and Some(Value::Null) for a missing property. Builds or refreshes the columns on first use after a write, so the result always reflects committed state.

Source

pub fn node_props_json_table( &self, ids: &[NodeId], props: &[&str], ) -> Result<Vec<Vec<Value>>, Error>

Bulk form of Graph::node_prop_json: gather props for each id in ids through the in-memory property columns, row-major (out[i][j] is props[j] on ids[i]). One columns refresh covers the whole gather, and each id resolves to its dense index once. A missing property reads as Value::Null; a nonexistent node is Error::NodeNotFound.

Source

pub fn node_prop_json_column( &self, ids: &[NodeId], prop: &str, ) -> Result<Vec<Value>, Error>

Single-property column form of Graph::node_props_json_table: out[i] is the value of prop on ids[i], as one flat vector, so a bulk single-property gather does not pay one row vector allocation per id. A missing property reads as Value::Null; a nonexistent node is Error::NodeNotFound.

Source

pub fn node_prop_group_codes( &self, ids: &[NodeId], prop: &str, ) -> Result<(Vec<u32>, Vec<Value>), Error>

Group ids by the exact value of prop through the in-memory property columns: one dense group code per id, plus one representative value per code (the first occurrence). Null and missing property values share one code represented by Value::Null; a nonexistent node is Error::NodeNotFound. Codes are assigned under value identity, which for the typed columns needs no per-row value materialization.

Source

pub fn edge_prop_json( &self, id: EdgeId, prop: &str, ) -> Result<Option<Value>, Error>

Read one property of an edge through the in-memory edge property columns. Returns None for a nonexistent edge and Some(Value::Null) for a missing property.

Source

pub fn edge_props_json_table( &self, ids: &[EdgeId], props: &[&str], ) -> Result<Vec<Vec<Value>>, Error>

Bulk row-major gather of props for each edge id in ids.

Source

pub fn edge_prop_json_column( &self, ids: &[EdgeId], prop: &str, ) -> Result<Vec<Value>, Error>

Single-property column gather for edges: out[i] is prop on ids[i].

Source

pub fn edge_prop_group_codes( &self, ids: &[EdgeId], prop: &str, ) -> Result<(Vec<u32>, Vec<Value>), Error>

Group ids by the exact value of edge property prop: one dense group code per id plus one representative value per code.

Source

pub fn node_prop_min_max( &self, prop: &str, ) -> Result<Option<(Value, Value)>, Error>

The minimum and maximum non-null value of one node property, from the lazily computed statistics over the in-memory property columns. None when the property has no typed column or no non-null values.

Source

pub fn estimate_range_selectivity( &self, prop: &str, lower: Option<&Value>, upper: Option<&Value>, ) -> Result<Option<f64>, Error>

Estimated fraction of non-null values of prop inside the given bounds (either bound optional), from the property’s equi-depth histogram. None when no statistics exist for the property.

Source

pub fn estimate_equality_selectivity( &self, prop: &str, val: &Value, ) -> Result<Option<f64>, Error>

Estimated fraction of non-null values of prop equal to val: exact for the property’s most common values, histogram-estimated otherwise. None when no statistics exist for the property.

Source

pub fn set_extension<T: Any + Send + Sync>(&self, val: Arc<T>)

Store an extension value (as Arc) keyed by its concrete type. Replaces any existing value of the same type.

Source

pub fn get_extension<T: Any + Send + Sync>(&self) -> Option<Arc<T>>

Retrieve an Arc to a previously stored extension value, or None if absent.

Source

pub fn get_or_init_extension_with<T, E, F>(&self, init: F) -> Result<Arc<T>, E>
where T: Any + Send + Sync, F: FnOnce() -> Result<Arc<T>, E>,

Return the extension of type T, initializing it with init if absent.

init runs without the extensions lock held, so it may call back into the graph (for example, to read from storage) without risking a lock ordering problem. If two threads initialize concurrently, both may run init, but only the first stored value is kept and every caller observes that same Arc. init is fallible; on error nothing is stored and the error is propagated.

Source

pub fn view<F, T>(&self, f: F) -> Result<T, Error>
where F: FnOnce(&ReadTxn<'_>) -> Result<T, Error>,

Execute a read-only transaction inside a closure.

Source

pub fn update<F, T>(&self, f: F) -> Result<T, Error>
where F: FnOnce(&mut WriteTxn<'_>) -> Result<T, Error>,

Execute a read-write transaction inside a closure.

Source

pub fn with_write_lock<F, R>(&self, f: F) -> R
where F: FnOnce() -> R,

Hold the write lock for the duration of f, executing f without starting an LMDB transaction. Use this to make a multi-step read-then-write sequence (such as MERGE) atomic with respect to other writers.

Source

pub fn rebuild_csr(&self) -> Result<(), Error>

Synchronously rebuild the CSR snapshot from LMDB. Useful after bulk loads or when tests need a consistent read view before the threshold has been crossed.

Source

pub fn backup(&self, destination: &Path) -> Result<(), Error>

Create a hot backup of this database to destination.

destination is a file path for the backup snapshot (e.g. /backups/mydb_2026-05-27.mdb). The file is a complete, portable LMDB snapshot. Concurrent reads and writes are not blocked.

To restore: create an empty directory, copy the snapshot file to <dir>/data.mdb, then call Graph::open(<dir>, map_size_gb).

Source

pub fn backup_compact(&self, destination: &Path) -> Result<(), Error>

Same as backup but compacts the database during the copy.

The resulting file is smaller than a raw backup but the operation takes longer because it rewrites every live page.

Source

pub fn restore(snapshot_file: &Path, dst_dir: &Path) -> Result<(), Error>

Restore a backup snapshot created by backup or backup_compact into a new database directory.

Creates dst_dir if it does not exist, then copies snapshot_file into dst_dir/data.mdb. After this call succeeds the caller can open the restored database with Graph::open(dst_dir, map_size_gb).

Trait Implementations§

Source§

impl Clone for Graph

Source§

fn clone(&self) -> Graph

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for Graph

§

impl !UnwindSafe for Graph

§

impl Freeze for Graph

§

impl Send for Graph

§

impl Sync for Graph

§

impl Unpin for Graph

§

impl UnsafeUnpin for Graph

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more