Skip to main content

MutableCsrTrait

Trait MutableCsrTrait 

Source
pub trait MutableCsrTrait: CsrBase {
Show 29 methods // Required methods fn insert_edge( &mut self, src_vid: u32, dst: VertexId, edge_id: EdgeId, ts: u64, ) -> Result<(), StorageError>; fn delete_edge( &mut self, src_vid: u32, edge_id: EdgeId, ts: u64, ) -> Result<bool, StorageError>; fn delete_edge_by_dst( &mut self, src_vid: u32, dst: VertexId, ts: u64, ) -> usize; fn delete_edge_by_offset( &mut self, src_vid: u32, offset: i32, ts: u64, ) -> Result<bool, StorageError>; fn revert_delete_by_offset( &mut self, src_vid: u32, offset: i32, ts: u64, ) -> bool; fn get_edge(&self, src_vid: u32, dst: VertexId, ts: u64) -> Option<Nbr>; fn edges_of(&self, src_vid: u32, ts: u64) -> Vec<Nbr>; fn used_memory_size(&self) -> usize; // Provided methods fn delete_edge_by_dst_reporting( &mut self, src_vid: u32, dst: VertexId, ts: u64, _on_deleted: &mut dyn FnMut(EdgeId), ) -> usize { ... } fn delete_edge_by_dst_reporting_positioned( &mut self, src_vid: u32, dst: VertexId, ts: u64, on_deleted: &mut dyn FnMut(EdgeId, Option<EdgePosition>), ) -> usize { ... } fn locate_edge( &self, _src_vid: u32, _edge_id: EdgeId, ) -> Option<(EdgePosition, Nbr)> { ... } fn delete_edge_at_position( &mut self, src_vid: u32, _position: EdgePosition, expected: EdgeId, ts: u64, ) -> Result<bool, StorageError> { ... } fn revert_delete_at_position( &mut self, src_vid: u32, _position: EdgePosition, expected: EdgeId, ts: u64, ) -> bool { ... } fn nbr_at_offset(&self, _src_vid: u32, _offset: i32) -> Option<Nbr> { ... } fn get_edge_physical(&self, _src_vid: u32, _dst: VertexId) -> Option<Nbr> { ... } fn physical_edges_of(&self, _src_vid: u32) -> Vec<Nbr> { ... } fn fill_physical_into(&self, src_vid: u32, out: &mut Vec<Nbr>) { ... } fn has_physical_entries(&self, _vid: u32) -> bool { ... } fn primary_contains(&self, _src_vid: u32, _edge_id: EdgeId) -> bool { ... } fn rollback_insert(&mut self, _src_vid: u32, _edge_id: EdgeId) -> bool { ... } fn revert_delete_by_edge_id( &mut self, _src_vid: u32, _edge_id: EdgeId, _ts: u64, ) -> bool { ... } fn compact_vertex_with_reporting( &mut self, _vid: u32, _cutoff: u64, _on_edge_removed: &mut dyn FnMut(EdgeId, u64), ) -> usize { ... } fn reclaimable_count(&self, _vid: u32, _cutoff: u64) -> usize { ... } fn vertex_needs_compact(&self, vid: u32, cutoff: u64) -> bool { ... } fn vertex_census(&self, _vid: u32) -> (usize, usize, usize) { ... } fn vertex_reclaim_probe(&self, vid: u32, cutoff: u64) -> (usize, usize) { ... } fn row_gap(&self, _vid: u32) -> usize { ... } fn row_density(&self, _vid: u32) -> f32 { ... } fn rebalance_row(&mut self, _vid: u32) -> bool { ... }
}

Required Methods§

Source

fn insert_edge( &mut self, src_vid: u32, dst: VertexId, edge_id: EdgeId, ts: u64, ) -> Result<(), StorageError>

Insert an edge.

Topology and properties are decoupled: the CSR stores only the topology (neighbor, edge_id, timestamps). Properties are stored separately indexed by EdgeId.

Physical uniqueness only, without timestamp ordering checks. Snapshot visibility is decided by the version authority above this layer.

Returns Ok(()) on success, or an error explaining why insertion failed:

  • MutableCsr: checks for duplicate live (neighbor) keys across primary and overflow, writes to primary if space available, otherwise spills to overflow with auto-expansion. Returns EdgeAlreadyExists on duplicate.
  • SingleMutableCsr: rejects a second live edge in an occupied slot with Conflict, matching the table-layer Single contract. A tombstoned slot accepts a rebuild at any timestamp. No silent overwrite exists.
Source

fn delete_edge( &mut self, src_vid: u32, edge_id: EdgeId, ts: u64, ) -> Result<bool, StorageError>

Delete an edge by edge_id.

Returns:

  • Ok(true) when the edge was deleted.

  • Ok(false) when the edge does not exist or cannot be deleted at ts (e.g. create_ts > ts), or when it was already deleted at exactly ts (idempotent re-delete).

  • Err(StorageError::write_write_conflict) when the edge already exists but was deleted at a different timestamp.

  • MutableCsr: uses edge_id to locate and delete the specific edge.

  • SingleMutableCsr: the stored edge id must match exactly. No wildcard edge id is supported; callers pass the precise id or use endpoint addressing.

Source

fn delete_edge_by_dst(&mut self, src_vid: u32, dst: VertexId, ts: u64) -> usize

Delete all edges matching (src, dst) with full-match semantics.

One call deletes every live match; no first-only variant exists. Returns the deleted count so table rollback can reconcile by count and tombstone metrics can observe multi-match rows.

  • MutableCsr: scans primary and overflow, deletes all matching edges.
  • SingleMutableCsr: deletes the single edge if dst matches (0 or 1).
Source

fn delete_edge_by_offset( &mut self, src_vid: u32, offset: i32, ts: u64, ) -> Result<bool, StorageError>

Delete an edge by its offset position in the primary block.

Offset indexes into the live row degree, never into reserved capacity. Out-of-degree offsets fail without touching any slot. Conflict errors are propagated instead of folded into a failure value.

Source

fn revert_delete_by_offset( &mut self, src_vid: u32, offset: i32, ts: u64, ) -> bool

Revert a deleted edge by its offset position.

  • MutableCsr: offset indexes into the primary block degree.
  • SingleMutableCsr: only offset == 0 is valid.
Source

fn get_edge(&self, src_vid: u32, dst: VertexId, ts: u64) -> Option<Nbr>

Get a specific edge by source and destination. Test-only row-stamp filter; production reads go through the version authority.

Source

fn edges_of(&self, src_vid: u32, ts: u64) -> Vec<Nbr>

Get all valid edges of a vertex at the given timestamp. Test-only row-stamp filter; production reads go through the version authority. Test and offline use; production traversals use the visitor or caller-buffer fill paths instead of this allocating accessor.

Source

fn used_memory_size(&self) -> usize

Return the approximate memory usage in bytes.

Provided Methods§

Source

fn delete_edge_by_dst_reporting( &mut self, src_vid: u32, dst: VertexId, ts: u64, _on_deleted: &mut dyn FnMut(EdgeId), ) -> usize

Delete all edges matching (src, dst), reporting every stamped id.

Same single-pass semantics as delete_edge_by_dst, plus one on_deleted call per stamped edge so callers needing the ids (append logs, audits) skip their own collection scan. The default routes through delete_edge_by_dst and reports nothing; row stores override it with an in-place reporting pass. A zero return covers both no match and read-only refusal without invoking the callback; table write paths reject frozen groups before reaching here so the two cases never merge into one silent miss.

Source

fn delete_edge_by_dst_reporting_positioned( &mut self, src_vid: u32, dst: VertexId, ts: u64, on_deleted: &mut dyn FnMut(EdgeId, Option<EdgePosition>), ) -> usize

Delete all edges matching (src, dst), reporting each stamped id with its row position.

Same single-pass semantics as delete_edge_by_dst_reporting, plus the position of each stamped entry so the caller can revert or re-delete the exact slot without rescanning the row. Positions are row-local and valid only until the next compaction, rebalance, repack or removal of the row; every positional write revalidates the edge id. Stores without positional addressing report None and the caller falls back to the edge-id path. The default adapts the id-only pass.

Source

fn locate_edge( &self, _src_vid: u32, _edge_id: EdgeId, ) -> Option<(EdgePosition, Nbr)>

Locate one stored edge, returning its row position and copy.

The default reports no position; row stores override it with a single scan shared by delete and revert callers.

Source

fn delete_edge_at_position( &mut self, src_vid: u32, _position: EdgePosition, expected: EdgeId, ts: u64, ) -> Result<bool, StorageError>

Delete the edge at position when it still holds expected id.

Stale positions are refused with Ok(false). Position-less stores fail closed with an error so a cross-variant position can never fall back to an id scan silently; positional stores override it with a direct slot write.

Source

fn revert_delete_at_position( &mut self, src_vid: u32, _position: EdgePosition, expected: EdgeId, ts: u64, ) -> bool

Revert the deletion at position when it still holds expected id.

Stale positions are refused with false. Position-less stores report false so cross-form reuse is observable instead of silently succeeding through another path; positional stores override it.

Source

fn nbr_at_offset(&self, _src_vid: u32, _offset: i32) -> Option<Nbr>

Read-only view of one primary slot for offset identity checks.

Source

fn get_edge_physical(&self, _src_vid: u32, _dst: VertexId) -> Option<Nbr>

Locate the first live edge by endpoint without consulting snapshots.

Physical addressing only; tombstoned and gap slots are skipped. Snapshot visibility still needs the version authority above this layer, while tombstone access uses the full physical views.

Source

fn physical_edges_of(&self, _src_vid: u32) -> Vec<Nbr>

Every physically stored entry of one vertex without timestamp filtering.

Test and offline use; production scans use fill_physical_into or the visitor paths instead of this allocating accessor.

Source

fn fill_physical_into(&self, src_vid: u32, out: &mut Vec<Nbr>)

Fill a caller buffer with every physically stored entry of one vertex.

Same content as the allocating accessor above, without the per-vertex allocation. The default forwards to the allocating accessor; row stores override it with a direct fill.

Source

fn has_physical_entries(&self, _vid: u32) -> bool

Whether one vertex holds any physically stored entry.

Source

fn primary_contains(&self, _src_vid: u32, _edge_id: EdgeId) -> bool

Whether the primary row of one vertex holds edge_id.

Source

fn rollback_insert(&mut self, _src_vid: u32, _edge_id: EdgeId) -> bool

Erase one just-inserted edge for insert rollback (no tombstone trace).

Insert-rollback only: erases the slot as if the edge never existed. Never use for MVCC deletes, which must go through delete_edge so the tombstone stays visible to the reclaim machinery. Reclaims the slot and updates the edge count. Only implemented by writable strategies; other strategies default to no-op.

Source

fn revert_delete_by_edge_id( &mut self, _src_vid: u32, _edge_id: EdgeId, _ts: u64, ) -> bool

Revert a deletion by edge id if it happened at or before ts.

Restores the entry as live. Only implemented by MutableCsr; other strategies default to no-op.

Source

fn compact_vertex_with_reporting( &mut self, _vid: u32, _cutoff: u64, _on_edge_removed: &mut dyn FnMut(EdgeId, u64), ) -> usize

Reclaim one vertex in place, dropping entries eligible for collection at cutoff and tightening live entries without touching other rows.

Returns the number of removed entries. Reported removals flow through on_edge_removed so tombstone promotion stays centralized. Strategies without per-row fragmentation default to no-op.

Mutable-row entry only: production reclaim of frozen rows must go through the group-batched entries (one linear pass for any number of rows) instead of one call per row. Frozen implementations reject the single-row entry; every production trigger dispatches frozen groups to the batched path before reaching here.

Source

fn reclaimable_count(&self, _vid: u32, _cutoff: u64) -> usize

Count entries of one vertex that are reclaimable at cutoff.

The write-path trigger consults this per-vertex count instead of a whole-table ratio, so small writes never cause large rebuilds.

Source

fn vertex_needs_compact(&self, vid: u32, cutoff: u64) -> bool

Whether one vertex holds anything reclaimable at cutoff.

Source

fn vertex_census(&self, _vid: u32) -> (usize, usize, usize)

Physical entry census of one vertex: (live, dead, capacity).

Backs the per-vertex fragmentation view; strategies without rows report zeros.

Source

fn vertex_reclaim_probe(&self, vid: u32, cutoff: u64) -> (usize, usize)

Single-walk reclaim probe of one vertex: (dead, reclaimable).

Fuses the census and eligibility walks so maintenance passes pay one row scan instead of two. The default derives both from the separate primitives; row stores override it with one fused walk.

Source

fn row_gap(&self, _vid: u32) -> usize

Reserved primary slots minus live primary entries of one row.

Steady-state write gaps; strategies without rows report zero.

Source

fn row_density(&self, _vid: u32) -> f32

Live primary entries per unit of reserved primary capacity.

Strategies without rows report full density.

Source

fn rebalance_row(&mut self, _vid: u32) -> bool

Rebalance one row in place, pulling overflow entries into primary gaps and repacking leftover overflow. Returns true when the row no longer holds overflow. Strategies without rows report true.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§