Skip to main content

CsrIndex

Struct CsrIndex 

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

Dense integer CSR adjacency index with interned node IDs and labels.

Implementations§

Source§

impl CsrIndex

Source

pub fn compact(&mut self)

Merge the mutable buffer into the dense CSR arrays.

Called during idle periods. Rebuilds the contiguous offset/target/label (and weight) arrays from scratch (buffer + surviving dense edges). The old arrays are dropped, freeing memory. O(E) where E = total edges.

Source§

impl CsrIndex

Source

pub fn new() -> Self

Source

pub fn add_node_label(&mut self, node: &str, label: &str) -> bool

Add a label to a node. Returns false if the 64-label limit is hit.

Source

pub fn remove_node_label(&mut self, node: &str, label: &str)

Remove a label from a node.

Source

pub fn node_has_label(&self, node_id: u32, label: &str) -> bool

Check if a node has a specific label.

Source

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

Get all label names for a node.

Source

pub fn add_edge(&mut self, src: &str, label: &str, dst: &str)

Incrementally add an unweighted edge (goes into mutable buffer). Uses weight 1.0 if the graph already has weighted edges.

Source

pub fn add_edge_weighted( &mut self, src: &str, label: &str, dst: &str, weight: f64, )

Incrementally add a weighted edge (goes into mutable buffer).

If this is the first weighted edge (weight != 1.0), initializes the weight tracking infrastructure (backfills existing buffer entries with 1.0).

Source

pub fn remove_edge(&mut self, src: &str, label: &str, dst: &str)

Incrementally remove an edge.

Source

pub fn remove_node_edges(&mut self, node: &str) -> usize

Remove ALL edges touching a node. Returns the number of edges removed.

Source

pub fn remove_nodes_with_prefix(&mut self, prefix: &str)

Remove all edges touching any node whose ID starts with prefix.

Used for tenant purge: prefix = "{tenant_id}:" removes all edges belonging to that tenant.

Source

pub fn neighbors( &self, node: &str, label_filter: Option<&str>, direction: Direction, ) -> Vec<(String, String)>

Get immediate neighbors.

Source

pub fn neighbors_multi( &self, node: &str, label_filters: &[&str], direction: Direction, ) -> Vec<(String, String)>

Get neighbors with multi-label filter. Empty labels = all edges.

Source

pub fn add_node(&mut self, name: &str) -> u32

Add a node without any edges (used for isolated/dangling nodes). Returns the dense node ID. Idempotent — returns existing ID if present.

Source

pub fn node_count(&self) -> usize

Source

pub fn contains_node(&self, node: &str) -> bool

Source

pub fn node_name(&self, dense_id: u32) -> &str

Get the string node ID for a dense node index.

Source

pub fn node_id(&self, name: &str) -> Option<u32>

Look up the dense node ID for a string node ID.

Source

pub fn label_name(&self, label_id: u16) -> &str

Get the string label for a dense label index.

Source

pub fn label_id(&self, name: &str) -> Option<u16>

Look up the dense label ID for a string label.

Source

pub fn out_degree(&self, node_id: u32) -> usize

Out-degree of a node (including buffer, excluding deleted).

Source

pub fn in_degree(&self, node_id: u32) -> usize

In-degree of a node.

Source

pub fn edge_count(&self) -> usize

Total edge count (dense + buffer - deleted). O(V).

Source

pub fn iter_out_edges(&self, node: u32) -> impl Iterator<Item = (u16, u32)> + '_

Iterate all outbound edges for a node (dense + buffer, minus deleted).

Source

pub fn iter_in_edges(&self, node: u32) -> impl Iterator<Item = (u16, u32)> + '_

Iterate all inbound edges for a node (dense + buffer, minus deleted).

Source§

impl CsrIndex

Source

pub fn record_access(&self, node_id: u32)

Record a node access (called during traversals for hot/cold tracking).

Source

pub fn cold_nodes(&self, threshold: u32) -> Vec<u32>

Get nodes with access count below threshold (cold nodes).

Source

pub fn hot_node_count(&self) -> usize

Number of hot nodes (access count > 0).

Source

pub fn query_epoch(&self) -> u64

Current query epoch (incremented per traversal call).

Source

pub fn reset_access_counts(&mut self)

Reset access counters (called during compaction or periodically).

Source

pub fn prefetch_node(&self, node_id: u32)

Predictive prefetch: hint the OS to load a node’s adjacency data into the page cache before the traversal touches it.

For in-memory dense CSR, this prefetches the cache line containing the node’s offset/target entries. For future mmap’d cold segments, this would call madvise(MADV_WILLNEED) on the relevant pages.

Called during BFS planning: when adding nodes to the next frontier, prefetch their neighbors’ data so it’s resident when the BFS loop reaches them on the next iteration.

Source

pub fn prefetch_batch(&self, node_ids: &[u32])

Prefetch a batch of nodes (called during BFS frontier expansion).

Source

pub fn evaluate_memory_pressure( &self, utilization: u8, spill_threshold: u8, restore_threshold: u8, ) -> (usize, usize)

Evaluate graph memory pressure and return promotion/demotion hints.

Uses SpillController-compatible thresholds (90%/75% hysteresis):

  • Above spill threshold: demote cold nodes (spill to potential mmap)
  • Below restore threshold: promote warm nodes back to hot RAM

utilization = estimated memory usage as percentage (0-100). Returns (nodes_to_demote, nodes_to_promote) counts.

Source

pub fn estimated_memory_bytes(&self) -> usize

Estimated memory usage of the dense CSR in bytes.

Used for SpillController utilization calculation.

Source§

impl CsrIndex

Source

pub fn checkpoint_to_bytes(&self) -> Vec<u8>

Serialize the index to rkyv bytes (with magic header) for storage.

rkyv is ~3x faster than MessagePack for both serialization and deserialization. The magic header allows from_checkpoint to auto-detect the format for backward compatibility.

Source

pub fn from_checkpoint(bytes: &[u8]) -> Option<Self>

Restore an index from a checkpoint snapshot.

Auto-detects format: rkyv (magic header RKCSR\0) or legacy MessagePack. Backwards-compatible with old checkpoints.

Source§

impl CsrIndex

Source

pub fn node_to_id_map(&self) -> &HashMap<String, u32>

Node-to-ID mapping (for snapshot cloning).

Source

pub fn id_to_node_list(&self) -> &[String]

ID-to-node list (for snapshot cloning).

Source

pub fn label_to_id_map(&self) -> &HashMap<String, u16>

Label-to-ID mapping (for snapshot cloning).

Source

pub fn id_to_label_list(&self) -> &[String]

ID-to-label list (for snapshot cloning).

Source

pub fn out_offsets_slice(&self) -> &[u32]

Outbound offset array slice.

Source

pub fn out_targets_slice(&self) -> &[u32]

Outbound target array slice.

Source

pub fn out_labels_slice(&self) -> &[u16]

Outbound label array slice.

Source

pub fn out_weights_slice(&self) -> Option<&[f64]>

Outbound weight array slice (None if unweighted).

Source

pub fn in_offsets_slice(&self) -> &[u32]

Inbound offset array slice.

Source

pub fn in_targets_slice(&self) -> &[u32]

Inbound target array slice.

Source

pub fn in_labels_slice(&self) -> &[u16]

Inbound label array slice.

Source

pub fn in_weights_slice(&self) -> Option<&[f64]>

Inbound weight array slice (None if unweighted).

Source§

impl CsrIndex

Source

pub fn compute_statistics(&self) -> GraphStatistics

Compute full graph statistics from the current CSR state.

O(V + E) — iterates all nodes and edges once. Intended for query planning, not hot-path execution.

Source

pub fn label_edge_count(&self, label: &str) -> usize

Get the edge count for a specific label. O(E) unless cached.

Returns 0 if the label doesn’t exist.

Source

pub fn label_selectivity(&self, label: &str) -> f64

Estimate the selectivity of a label: edge_count / total_edges.

Returns 1.0 for unknown labels (conservative — assume all edges). Returns 0.0 for graphs with no edges.

Source§

impl CsrIndex

Source

pub fn has_weights(&self) -> bool

Whether this CSR has any weighted edges.

Source

pub fn out_edge_weight(&self, edge_idx: usize) -> f64

Get the weight of the i-th outbound edge from a node (dense CSR only).

edge_idx is the absolute index into out_targets/out_weights. Returns 1.0 for unweighted graphs.

Source

pub fn in_edge_weight(&self, edge_idx: usize) -> f64

Get the weight of the i-th inbound edge to a node (dense CSR only).

Source

pub fn edge_weight(&self, src: &str, label: &str, dst: &str) -> Option<f64>

Get the weight of a specific outbound edge from src to dst via label.

Checks both dense and buffer. Returns 1.0 if the edge exists but has no weight, or None if the edge doesn’t exist.

Source

pub fn iter_out_edges_weighted( &self, node: u32, ) -> impl Iterator<Item = (u16, u32, f64)> + '_

Iterate outbound edges of a node with weights: (label_id, dst_id, weight).

Yields from both dense CSR and buffer, excluding deleted edges. Weights are 1.0 for unweighted graphs.

Source§

impl CsrIndex

Source

pub fn traverse_bfs( &self, start_nodes: &[&str], label_filter: Option<&str>, direction: Direction, max_depth: usize, max_visited: usize, ) -> Vec<String>

BFS traversal. Returns all reachable node IDs within max_depth hops.

max_visited caps the number of nodes visited to prevent supernode fan-out explosion. Pass DEFAULT_MAX_VISITED for the standard limit.

Source

pub fn traverse_bfs_with_depth( &self, start_nodes: &[&str], label_filter: Option<&str>, direction: Direction, max_depth: usize, max_visited: usize, ) -> Vec<(String, u8)>

BFS traversal returning nodes with depth information.

max_visited caps the number of nodes visited to prevent supernode fan-out explosion. Pass DEFAULT_MAX_VISITED for the standard limit.

Source

pub fn traverse_bfs_with_depth_multi( &self, start_nodes: &[&str], label_filters: &[&str], direction: Direction, max_depth: usize, max_visited: usize, ) -> Vec<(String, u8)>

BFS traversal with multi-label filter. Empty labels = all edges.

max_visited caps the number of nodes visited to prevent supernode fan-out explosion. Pass DEFAULT_MAX_VISITED for the standard limit.

Source

pub fn shortest_path( &self, src: &str, dst: &str, label_filter: Option<&str>, max_depth: usize, max_visited: usize, ) -> Option<Vec<String>>

Shortest path via bidirectional BFS.

max_visited caps the combined forward+backward visited set to prevent supernode fan-out explosion. Pass DEFAULT_MAX_VISITED for the standard limit.

Source

pub fn subgraph( &self, start_nodes: &[&str], label_filter: Option<&str>, max_depth: usize, max_visited: usize, ) -> Vec<(String, String, String)>

Materialize a subgraph as edge tuples within max_depth.

max_visited caps the number of nodes visited to prevent supernode fan-out explosion. Pass DEFAULT_MAX_VISITED for the standard limit.

Trait Implementations§

Source§

impl Default for CsrIndex

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

Source§

type ArchivedMetadata = ()

The archived version of the pointer metadata for this type.
Source§

fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata

Converts some archived metadata to the pointer metadata for itself.
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> LayoutRaw for T

Source§

fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>

Returns the layout of the type.
Source§

impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
where T: SharedNiching<N1, N2>, N1: Niching<T>, N2: Niching<T>,

Source§

unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool

Returns whether the given value has been niched. Read more
Source§

fn resolve_niched(out: Place<NichedOption<T, N1>>)

Writes data to out indicating that a T is niched.
Source§

impl<T> Pointee for T

Source§

type Metadata = ()

The metadata type for pointers and references to this type.
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