Skip to main content

GraphStore

Struct GraphStore 

Source
pub struct GraphStore {
    pub current_version: u64,
    pub vector_index: Arc<VectorIndexManager>,
    pub property_index: Arc<IndexManager>,
    pub node_columns: ColumnStore,
    pub edge_columns: ColumnStore,
    pub index_sender: Option<UnboundedSender<IndexEvent>>,
    /* private fields */
}
Expand description

In-memory graph storage engine.

GraphStore is the authoritative source of truth for all graph data. Its data structure layout is designed for the access patterns of a Cypher query engine:

FieldTypePurposeLookup cost
nodesVec<Vec<Node>>Arena-allocated node versions, indexed by NodeIdO(1)
edgesVec<Vec<Edge>>Arena-allocated edge versions, indexed by EdgeIdO(1)
outgoingVec<Vec<(NodeId, EdgeId)>>Sorted adjacency list per node (outgoing)O(log d) binary search
incomingVec<Vec<(NodeId, EdgeId)>>Sorted adjacency list per node (incoming)O(log d) binary search
label_indexHashMap<Label, HashSet<NodeId>>Secondary index: label -> node setO(1) lookup, O(n) scan
edge_type_indexHashMap<EdgeType, HashSet<EdgeId>>Secondary index: type -> edge setO(1) lookup, O(n) scan
node_columnsColumnStoreColumnar property storage for late materializationO(1) per cell
catalogGraphCatalogTriple-level statistics for graph-native planning (ADR-015)O(1)

The free_node_ids / free_edge_ids vectors enable ID reuse after deletions, avoiding unbounded growth of the arena vectors.

Thread safety: GraphStore is not Sync by itself. Concurrent access is managed by the server layer, which wraps it in Arc<RwLock<GraphStore>> for shared-nothing read parallelism with exclusive write access.

Fields§

§current_version: u64

Current global version for MVCC

§vector_index: Arc<VectorIndexManager>

Vector indices manager

§property_index: Arc<IndexManager>

Property indices manager

§node_columns: ColumnStore

Columnar storage for node properties

§edge_columns: ColumnStore

Columnar storage for edge properties

§index_sender: Option<UnboundedSender<IndexEvent>>

Async index event sender

Implementations§

Source§

impl GraphStore

Source

pub fn new() -> Self

Create a new empty graph store

Source

pub fn with_async_indexing() -> (Self, UnboundedReceiver<IndexEvent>)

Create a new GraphStore with async indexing enabled

Source

pub async fn start_background_indexer( receiver: UnboundedReceiver<IndexEvent>, vector_index: Arc<VectorIndexManager>, property_index: Arc<IndexManager>, tenant_manager: Arc<TenantManager>, )

Start the background indexer loop

Source

pub fn create_node(&mut self, label: impl Into<Label>) -> NodeId

Create a node with auto-generated ID and single label

Source

pub fn create_node_with_properties( &mut self, tenant_id: &str, labels: Vec<Label>, properties: PropertyMap, ) -> NodeId

Create a node with multiple labels and properties

Source

pub fn get_node_at_version(&self, id: NodeId, version: u64) -> Option<&Node>

Get a node by ID at a specific version (MVCC)

Source

pub fn get_node(&self, id: NodeId) -> Option<&Node>

Get a node by ID (uses current version)

Source

pub fn get_node_mut(&mut self, id: NodeId) -> Option<&mut Node>

Get a mutable node by ID (always latest version)

Source

pub fn has_node(&self, id: NodeId) -> bool

Check if a node exists

Source

pub fn set_node_property( &mut self, tenant_id: &str, node_id: NodeId, key: impl Into<String>, value: impl Into<PropertyValue>, ) -> GraphResult<()>

Set a property on a node and update vector indices if necessary

Source

pub fn delete_node(&mut self, tenant_id: &str, id: NodeId) -> GraphResult<Node>

Delete a node and all its connected edges

Source

pub fn add_label_to_node( &mut self, tenant_id: &str, node_id: NodeId, label: impl Into<Label>, ) -> GraphResult<()>

Add a label to an existing node AND update the label index

This is the correct way to add labels to nodes after creation. Using node.add_label() directly will NOT update the label_index, making the node invisible to get_nodes_by_label() queries.

Source

pub fn create_edge( &mut self, source: NodeId, target: NodeId, edge_type: impl Into<EdgeType>, ) -> GraphResult<EdgeId>

Create an edge between two nodes

Source

pub fn create_edge_with_properties( &mut self, source: NodeId, target: NodeId, edge_type: impl Into<EdgeType>, properties: PropertyMap, ) -> GraphResult<EdgeId>

Create an edge with properties

Source

pub fn get_edge_at_version(&self, id: EdgeId, version: u64) -> Option<&Edge>

Get an edge by ID at a specific version (MVCC)

Source

pub fn get_edge(&self, id: EdgeId) -> Option<&Edge>

Get an edge by ID (uses current version)

Source

pub fn get_edge_mut(&mut self, id: EdgeId) -> Option<&mut Edge>

Get a mutable edge by ID (always latest version)

Source

pub fn has_edge(&self, id: EdgeId) -> bool

Check if an edge exists

Source

pub fn delete_edge(&mut self, id: EdgeId) -> GraphResult<Edge>

Delete an edge

Source

pub fn get_outgoing_edges(&self, node_id: NodeId) -> Vec<&Edge>

Get all outgoing edges from a node

Source

pub fn get_incoming_edges(&self, node_id: NodeId) -> Vec<&Edge>

Get all incoming edges to a node

Source

pub fn get_outgoing_edge_targets( &self, node_id: NodeId, ) -> Vec<(EdgeId, NodeId, NodeId, &EdgeType)>

Get outgoing edge targets as lightweight tuples (no Edge clone) Returns (EdgeId, source NodeId, target NodeId, &EdgeType) for each outgoing edge

Source

pub fn get_incoming_edge_sources( &self, node_id: NodeId, ) -> Vec<(EdgeId, NodeId, NodeId, &EdgeType)>

Get incoming edge sources as lightweight tuples (no Edge clone) Returns (EdgeId, source NodeId, target NodeId, &EdgeType) for each incoming edge

Source

pub fn edge_between( &self, source: NodeId, target: NodeId, edge_type: Option<&EdgeType>, ) -> Option<EdgeId>

Check if an edge exists between source and target, optionally filtered by edge type. Uses binary search on sorted adjacency lists for O(log d) lookup. Returns the first matching EdgeId, or None.

Source

pub fn edges_between( &self, source: NodeId, target: NodeId, edge_type: Option<&EdgeType>, ) -> Vec<EdgeId>

Get all edges between source and target, optionally filtered by edge type. Uses binary search on sorted adjacency lists.

Source

pub fn get_nodes_by_label(&self, label: &Label) -> Vec<&Node>

Get all nodes with a specific label

Source

pub fn get_edges_by_type(&self, edge_type: &EdgeType) -> Vec<&Edge>

Get all edges of a specific type

Source

pub fn node_count(&self) -> usize

Get total number of nodes

Source

pub fn edge_count(&self) -> usize

Get total number of edges

Source

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

Get all nodes in the graph

Source

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

Get all edges in the graph

Source

pub fn compute_statistics(&self) -> GraphStatistics

Compute statistics for the current graph state

Source

pub fn catalog(&self) -> &GraphCatalog

Get the triple-level statistics catalog (for graph-native query planning)

Source

pub fn label_node_count(&self, label: &Label) -> usize

Get node count for a specific label (fast, O(1))

Source

pub fn edge_type_count(&self, edge_type: &EdgeType) -> usize

Get edge count for a specific type (fast, O(1))

Source

pub fn all_labels(&self) -> Vec<&Label>

Get all label names in the graph

Source

pub fn all_edge_types(&self) -> Vec<&EdgeType>

Get all edge type names in the graph

Source

pub fn clear(&mut self)

Clear all data from the graph

Source

pub fn handle_index_event( &self, event: IndexEvent, _tenant_manager: Option<Arc<TenantManager>>, )

Source

pub fn create_vector_index( &self, label: &str, property_key: &str, dimensions: usize, metric: DistanceMetric, ) -> VectorResult<()>

Create a vector index for a specific label and property

Search for nearest neighbors using a vector index

Source

pub fn insert_recovered_node(&mut self, node: Node)

Insert a recovered node (used during recovery from persistence) Unlike create_node(), this preserves the node’s existing ID

Source

pub fn insert_recovered_edge(&mut self, edge: Edge) -> GraphResult<()>

Insert a recovered edge (used during recovery from persistence) Unlike create_edge(), this preserves the edge’s existing ID Note: Source and target nodes must already exist

Trait Implementations§

Source§

impl Debug for GraphStore

Source§

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

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

impl Default for GraphStore

Source§

fn default() -> Self

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> 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> 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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

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

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

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
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
Source§

impl<T> OptionalSend for T
where T: Send + ?Sized,

Source§

impl<T> OptionalSync for T
where T: Sync + ?Sized,