pub trait StorageEngine: Send + Sync {
Show 46 methods
// Required methods
fn put_node(&self, node: &Node) -> Result<()>;
fn get_node(&self, id: NodeId) -> Result<Option<Node>>;
fn detach_delete_node(&self, id: NodeId) -> Result<()>;
fn put_edge(&self, edge: &Edge) -> Result<()>;
fn get_edge(&self, id: EdgeId) -> Result<Option<Edge>>;
fn delete_edge(&self, id: EdgeId) -> Result<()>;
fn apply_batch(&self, mutations: &[GraphMutation]) -> Result<()>;
fn all_nodes(&self) -> Result<Vec<Node>>;
fn all_edges(&self) -> Result<Vec<Edge>>;
fn all_node_ids(&self) -> Result<Vec<NodeId>>;
fn outgoing(&self, source: NodeId) -> Result<Vec<(EdgeId, NodeId)>>;
fn incoming(&self, target: NodeId) -> Result<Vec<(EdgeId, NodeId)>>;
fn nodes_by_label(&self, label: &str) -> Result<Vec<NodeId>>;
fn edges_by_type(&self, edge_type: &str) -> Result<Vec<EdgeId>>;
fn nodes_by_property(
&self,
label: &str,
property: &str,
value: &Property,
) -> Result<Vec<NodeId>>;
fn nodes_by_properties(
&self,
label: &str,
properties: &[String],
values: &[Property],
) -> Result<Vec<NodeId>>;
fn edges_by_property(
&self,
edge_type: &str,
property: &str,
value: &Property,
) -> Result<Vec<EdgeId>>;
fn create_property_index(&self, label: &str, property: &str) -> Result<()>;
fn drop_property_index(&self, label: &str, property: &str) -> Result<()>;
fn create_property_index_composite(
&self,
label: &str,
properties: &[String],
) -> Result<()>;
fn drop_property_index_composite(
&self,
label: &str,
properties: &[String],
) -> Result<()>;
fn list_property_indexes(&self) -> Vec<PropertyIndexSpec>;
fn create_edge_property_index(
&self,
edge_type: &str,
property: &str,
) -> Result<()>;
fn drop_edge_property_index(
&self,
edge_type: &str,
property: &str,
) -> Result<()>;
fn create_edge_property_index_composite(
&self,
edge_type: &str,
properties: &[String],
) -> Result<()>;
fn drop_edge_property_index_composite(
&self,
edge_type: &str,
properties: &[String],
) -> Result<()>;
fn list_edge_property_indexes(&self) -> Vec<EdgePropertyIndexSpec>;
fn create_point_index(&self, label: &str, property: &str) -> Result<()>;
fn drop_point_index(&self, label: &str, property: &str) -> Result<()>;
fn list_point_indexes(&self) -> Vec<PointIndexSpec>;
fn nodes_in_bbox(
&self,
label: &str,
property: &str,
srid: i32,
xlo: f64,
ylo: f64,
xhi: f64,
yhi: f64,
) -> Result<Vec<NodeId>>;
fn create_edge_point_index(
&self,
edge_type: &str,
property: &str,
) -> Result<()>;
fn drop_edge_point_index(
&self,
edge_type: &str,
property: &str,
) -> Result<()>;
fn list_edge_point_indexes(&self) -> Vec<EdgePointIndexSpec>;
fn edges_in_bbox(
&self,
edge_type: &str,
property: &str,
srid: i32,
xlo: f64,
ylo: f64,
xhi: f64,
yhi: f64,
) -> Result<Vec<EdgeId>>;
fn create_property_constraint(
&self,
name: Option<&str>,
scope: &ConstraintScope,
properties: &[String],
kind: PropertyConstraintKind,
if_not_exists: bool,
) -> Result<PropertyConstraintSpec>;
fn drop_property_constraint(
&self,
name: &str,
if_exists: bool,
) -> Result<()>;
fn list_property_constraints(&self) -> Vec<PropertyConstraintSpec>;
fn create_checkpoint(&self, path: &Path) -> Result<()>;
fn clear_all(&self) -> Result<()>;
// Provided methods
fn put_trigger(&self, _name: &str, _value: &[u8]) -> Result<()> { ... }
fn delete_trigger(&self, _name: &str) -> Result<()> { ... }
fn list_triggers(&self) -> Result<Vec<(String, Vec<u8>)>> { ... }
fn put_pending_tx(&self, _key: &[u8], _value: &[u8]) -> Result<()> { ... }
fn delete_pending_tx(&self, _key: &[u8]) -> Result<()> { ... }
fn list_pending_txs(&self) -> Result<Vec<(Vec<u8>, Vec<u8>)>> { ... }
}Expand description
Object-safe interface for a graph storage backend. See module docs for design notes.
Required Methods§
fn put_node(&self, node: &Node) -> Result<()>
fn get_node(&self, id: NodeId) -> Result<Option<Node>>
fn detach_delete_node(&self, id: NodeId) -> Result<()>
fn put_edge(&self, edge: &Edge) -> Result<()>
fn get_edge(&self, id: EdgeId) -> Result<Option<Edge>>
fn delete_edge(&self, id: EdgeId) -> Result<()>
Sourcefn apply_batch(&self, mutations: &[GraphMutation]) -> Result<()>
fn apply_batch(&self, mutations: &[GraphMutation]) -> Result<()>
Apply a sequence of mutations atomically. Either every mutation
lands or none does. See GraphMutation for the variant set.
fn all_nodes(&self) -> Result<Vec<Node>>
fn all_edges(&self) -> Result<Vec<Edge>>
fn all_node_ids(&self) -> Result<Vec<NodeId>>
fn outgoing(&self, source: NodeId) -> Result<Vec<(EdgeId, NodeId)>>
fn incoming(&self, target: NodeId) -> Result<Vec<(EdgeId, NodeId)>>
fn nodes_by_label(&self, label: &str) -> Result<Vec<NodeId>>
fn edges_by_type(&self, edge_type: &str) -> Result<Vec<EdgeId>>
fn nodes_by_property( &self, label: &str, property: &str, value: &Property, ) -> Result<Vec<NodeId>>
Sourcefn nodes_by_properties(
&self,
label: &str,
properties: &[String],
values: &[Property],
) -> Result<Vec<NodeId>>
fn nodes_by_properties( &self, label: &str, properties: &[String], values: &[Property], ) -> Result<Vec<NodeId>>
Composite form of Self::nodes_by_property. properties
and values are parallel slices of equal length — the tuple
must match an equivalent stored index entry. Single-property
callers should use Self::nodes_by_property which delegates
here with length-1 slices.
Sourcefn edges_by_property(
&self,
edge_type: &str,
property: &str,
value: &Property,
) -> Result<Vec<EdgeId>>
fn edges_by_property( &self, edge_type: &str, property: &str, value: &Property, ) -> Result<Vec<EdgeId>>
Equality lookup through an edge property index. Mirrors
StorageEngine::nodes_by_property for the relationship side.
The caller is responsible for verifying the (edge_type, property)
index exists before dispatching — a missing index returns an
empty result (no entries maintained) rather than erroring so
the planner’s race with a concurrent DROP stays safe.
fn create_property_index(&self, label: &str, property: &str) -> Result<()>
fn drop_property_index(&self, label: &str, property: &str) -> Result<()>
Sourcefn create_property_index_composite(
&self,
label: &str,
properties: &[String],
) -> Result<()>
fn create_property_index_composite( &self, label: &str, properties: &[String], ) -> Result<()>
Composite form of Self::create_property_index — declares
a tuple index over (label, properties...). Single-property
callers should use Self::create_property_index which
delegates here with a length-1 slice.
Sourcefn drop_property_index_composite(
&self,
label: &str,
properties: &[String],
) -> Result<()>
fn drop_property_index_composite( &self, label: &str, properties: &[String], ) -> Result<()>
Composite form of Self::drop_property_index.
fn list_property_indexes(&self) -> Vec<PropertyIndexSpec>
Sourcefn create_edge_property_index(
&self,
edge_type: &str,
property: &str,
) -> Result<()>
fn create_edge_property_index( &self, edge_type: &str, property: &str, ) -> Result<()>
Declare a new (edge_type, property) single-property equality
index and backfill it from every edge currently carrying the
type. Idempotent: re-creating an already-registered index is a
no-op. Matches StorageEngine::create_property_index for
node scope.
Sourcefn drop_edge_property_index(
&self,
edge_type: &str,
property: &str,
) -> Result<()>
fn drop_edge_property_index( &self, edge_type: &str, property: &str, ) -> Result<()>
Tear down an edge property index. Removes the meta entry and
every entry under the (edge_type, prop) prefix. Idempotent.
Sourcefn create_edge_property_index_composite(
&self,
edge_type: &str,
properties: &[String],
) -> Result<()>
fn create_edge_property_index_composite( &self, edge_type: &str, properties: &[String], ) -> Result<()>
Composite form of Self::create_edge_property_index.
Sourcefn drop_edge_property_index_composite(
&self,
edge_type: &str,
properties: &[String],
) -> Result<()>
fn drop_edge_property_index_composite( &self, edge_type: &str, properties: &[String], ) -> Result<()>
Composite form of Self::drop_edge_property_index.
Sourcefn list_edge_property_indexes(&self) -> Vec<EdgePropertyIndexSpec>
fn list_edge_property_indexes(&self) -> Vec<EdgePropertyIndexSpec>
Snapshot the currently-registered edge property indexes.
Sourcefn create_point_index(&self, label: &str, property: &str) -> Result<()>
fn create_point_index(&self, label: &str, property: &str) -> Result<()>
Declare a point index on (label, property) and backfill it
by scanning every node carrying label. Idempotent:
re-creating a registered index is a no-op. Single-property
and node-scope only — composite / relationship-scope spatial
indexes are follow-ups.
Sourcefn drop_point_index(&self, label: &str, property: &str) -> Result<()>
fn drop_point_index(&self, label: &str, property: &str) -> Result<()>
Tear down a point index. Removes the meta entry and sweeps
every stored entry under the (label, property) header — the
SRID-keyed sub-prefixes all fall inside that header, so one
range scan covers all coordinate systems. Idempotent.
Sourcefn list_point_indexes(&self) -> Vec<PointIndexSpec>
fn list_point_indexes(&self) -> Vec<PointIndexSpec>
Snapshot the currently-registered point indexes.
Sourcefn nodes_in_bbox(
&self,
label: &str,
property: &str,
srid: i32,
xlo: f64,
ylo: f64,
xhi: f64,
yhi: f64,
) -> Result<Vec<NodeId>>
fn nodes_in_bbox( &self, label: &str, property: &str, srid: i32, xlo: f64, ylo: f64, xhi: f64, yhi: f64, ) -> Result<Vec<NodeId>>
Axis-aligned bounding-box range query over the point index
(label, property) under srid. Entries tagged with a
different SRID are scoped out by the index key prefix, so
cross-SRID rows never leak. A missing index returns empty
rather than erroring — matches the soft-fail contract of
Self::nodes_by_property.
Sourcefn create_edge_point_index(&self, edge_type: &str, property: &str) -> Result<()>
fn create_edge_point_index(&self, edge_type: &str, property: &str) -> Result<()>
Relationship-scope analogue of Self::create_point_index.
Declares an edge point index on (edge_type, property) and
backfills by scanning every edge currently carrying
edge_type. Idempotent.
Sourcefn drop_edge_point_index(&self, edge_type: &str, property: &str) -> Result<()>
fn drop_edge_point_index(&self, edge_type: &str, property: &str) -> Result<()>
Tear down an edge point index. Idempotent. Mirrors
Self::drop_point_index.
Sourcefn list_edge_point_indexes(&self) -> Vec<EdgePointIndexSpec>
fn list_edge_point_indexes(&self) -> Vec<EdgePointIndexSpec>
Snapshot the currently-registered edge point indexes.
Sourcefn edges_in_bbox(
&self,
edge_type: &str,
property: &str,
srid: i32,
xlo: f64,
ylo: f64,
xhi: f64,
yhi: f64,
) -> Result<Vec<EdgeId>>
fn edges_in_bbox( &self, edge_type: &str, property: &str, srid: i32, xlo: f64, ylo: f64, xhi: f64, yhi: f64, ) -> Result<Vec<EdgeId>>
Relationship-scope analogue of Self::nodes_in_bbox.
Sourcefn create_property_constraint(
&self,
name: Option<&str>,
scope: &ConstraintScope,
properties: &[String],
kind: PropertyConstraintKind,
if_not_exists: bool,
) -> Result<PropertyConstraintSpec>
fn create_property_constraint( &self, name: Option<&str>, scope: &ConstraintScope, properties: &[String], kind: PropertyConstraintKind, if_not_exists: bool, ) -> Result<PropertyConstraintSpec>
Declare a new property constraint. If name is None, the
backend derives a deterministic name from the other fields so
DROP CONSTRAINT can still target it. When if_not_exists is
true, re-declaring a constraint with the same name is a no-op
(including when the existing constraint has different
label/property/kind — matches Neo4j’s name-first semantics).
Returns the final PropertyConstraintSpec that was either
installed or already present.
UNIQUE constraints implicitly require a backing property
index; implementations should ensure one exists on the relevant
(label, property) pair. The backing index is NOT torn down
when the constraint is dropped — users who want it gone must
issue a separate DROP INDEX.
Sourcefn drop_property_constraint(&self, name: &str, if_exists: bool) -> Result<()>
fn drop_property_constraint(&self, name: &str, if_exists: bool) -> Result<()>
Tear down a constraint identified by name. When if_exists
is true, dropping a non-existent constraint is a no-op.
Sourcefn list_property_constraints(&self) -> Vec<PropertyConstraintSpec>
fn list_property_constraints(&self) -> Vec<PropertyConstraintSpec>
Snapshot every registered constraint. Order is insertion order
for deterministic SHOW CONSTRAINTS output across restarts.
Sourcefn create_checkpoint(&self, path: &Path) -> Result<()>
fn create_checkpoint(&self, path: &Path) -> Result<()>
Persist a point-in-time copy of the backend’s on-disk state into
path. The shape of what lands at path is backend-specific — the
caller is expected to package it in a backend-aware way (see
meshdb-rpc::raft_applier for the RocksDB path). For RocksDB this is
a Checkpoint directory of SST files; a different backend is free
to write a single file, a directory of segments, etc., as long as
its own open(path) can later rehydrate from the same layout.
Provided Methods§
Sourcefn put_trigger(&self, _name: &str, _value: &[u8]) -> Result<()>
fn put_trigger(&self, _name: &str, _value: &[u8]) -> Result<()>
Persist an apoc.trigger.* registration. The value is a
JSON-encoded blob owned by meshdb-executor’s
TriggerSpec — storage stays format-agnostic so the
schema can evolve without bumping the storage trait.
Default impl errors loudly so backends that haven’t
wired triggers in yet surface the gap immediately.
Sourcefn delete_trigger(&self, _name: &str) -> Result<()>
fn delete_trigger(&self, _name: &str) -> Result<()>
Remove a registered trigger by name. Idempotent — dropping a non-existent name is a no-op.
Sourcefn list_triggers(&self) -> Result<Vec<(String, Vec<u8>)>>
fn list_triggers(&self) -> Result<Vec<(String, Vec<u8>)>>
Snapshot every registered trigger as (name, value) pairs
in insertion-order by name. The value bytes are passed
straight back to the caller for format-side decoding.
Sourcefn put_pending_tx(&self, _key: &[u8], _value: &[u8]) -> Result<()>
fn put_pending_tx(&self, _key: &[u8], _value: &[u8]) -> Result<()>
Persist an in-doubt cross-partition transaction’s staging
blob. Used by the multi-raft PartitionGraphApplier so
pending_txs survives a process restart — without
persistence, an applied PreparedTx would be invisible to
post-restart recovery (openraft replays only entries past
last_applied, and the staged commands live in memory).
key is a partition-namespaced txid (e.g. b"<u32 LE partition><txid bytes>"); value is the serde-encoded
Vec<GraphMutation> to apply on CommitTx. Default impl
errors so backends that don’t host multi-raft surface the
gap immediately.
Sourcefn delete_pending_tx(&self, _key: &[u8]) -> Result<()>
fn delete_pending_tx(&self, _key: &[u8]) -> Result<()>
Drop a pending-tx entry by key. Idempotent for unknown keys.