pub struct LazyGraphManager { /* private fields */ }Expand description
The lazy-loading graph manager
Manages partitioned code graphs stored in SQLite, loading them on-demand into a petgraph-based in-memory representation.
Uses interior mutability via RwLock<PetCodeGraph> to enable concurrent
read access to the graph while maintaining thread safety for writes.
Implementations§
Source§impl LazyGraphManager
impl LazyGraphManager
Sourcepub fn new(prism_dir: &Path) -> Self
pub fn new(prism_dir: &Path) -> Self
Create a new lazy graph manager with default memory budget (512 MB)
§Arguments
prism_dir- The .codeprysm directory path
Sourcepub fn with_memory_budget(
prism_dir: &Path,
memory_budget_bytes: Option<usize>,
) -> Self
pub fn with_memory_budget( prism_dir: &Path, memory_budget_bytes: Option<usize>, ) -> Self
Create a new lazy graph manager with a custom memory budget
§Arguments
prism_dir- The .codeprysm directory pathmemory_budget_bytes- Optional memory budget in bytes (default: 512 MB)
Sourcepub fn open(prism_dir: &Path) -> Result<Self, LazyGraphError>
pub fn open(prism_dir: &Path) -> Result<Self, LazyGraphError>
Open an existing lazy graph from a .codeprysm directory
Loads the manifest but does not load any partitions yet.
Sourcepub fn open_with_memory_budget(
prism_dir: &Path,
memory_budget_bytes: Option<usize>,
) -> Result<Self, LazyGraphError>
pub fn open_with_memory_budget( prism_dir: &Path, memory_budget_bytes: Option<usize>, ) -> Result<Self, LazyGraphError>
Open an existing lazy graph with a custom memory budget
Sourcepub fn init(prism_dir: &Path) -> Result<Self, LazyGraphError>
pub fn init(prism_dir: &Path) -> Result<Self, LazyGraphError>
Initialize a new lazy graph with an empty manifest
Creates the partitions directory if it doesn’t exist.
Sourcepub fn init_with_memory_budget(
prism_dir: &Path,
memory_budget_bytes: Option<usize>,
) -> Result<Self, LazyGraphError>
pub fn init_with_memory_budget( prism_dir: &Path, memory_budget_bytes: Option<usize>, ) -> Result<Self, LazyGraphError>
Initialize a new lazy graph with a custom memory budget
Sourcepub fn init_workspace(
workspace_path: &Path,
prism_dir: &Path,
) -> Result<Self, LazyGraphError>
pub fn init_workspace( workspace_path: &Path, prism_dir: &Path, ) -> Result<Self, LazyGraphError>
Initialize a lazy graph by discovering roots in a workspace
Uses RootDiscovery to find git repositories and code directories,
then registers them in the manifest for multi-root support.
§Arguments
workspace_path- The workspace root to discover roots inprism_dir- The .codeprysm directory for storage
§Examples
use codeprysm_core::lazy::manager::LazyGraphManager;
use std::path::Path;
// Single repo workspace
let manager = LazyGraphManager::init_workspace(
Path::new("/path/to/repo"),
Path::new("/path/to/repo/.codeprysm"),
).unwrap();
// Multi-root workspace
let manager = LazyGraphManager::init_workspace(
Path::new("/path/to/workspace"),
Path::new("/path/to/workspace/.codeprysm"),
).unwrap();Sourcepub fn init_workspace_with_options(
workspace_path: &Path,
prism_dir: &Path,
memory_budget_bytes: Option<usize>,
max_discovery_depth: Option<usize>,
) -> Result<Self, LazyGraphError>
pub fn init_workspace_with_options( workspace_path: &Path, prism_dir: &Path, memory_budget_bytes: Option<usize>, max_discovery_depth: Option<usize>, ) -> Result<Self, LazyGraphError>
Initialize a lazy graph with custom options
§Arguments
workspace_path- The workspace root to discover roots inprism_dir- The .codeprysm directory for storagememory_budget_bytes- Optional memory budget (default: 512 MB)max_discovery_depth- Optional max depth for root discovery (default: 3)
Sourcepub fn roots(&self) -> impl Iterator<Item = &RootInfo>
pub fn roots(&self) -> impl Iterator<Item = &RootInfo>
Get the discovered roots from the manifest
Sourcepub fn is_multi_root(&self) -> bool
pub fn is_multi_root(&self) -> bool
Check if this is a multi-root workspace
Sourcepub fn manifest_mut(&mut self) -> &mut Manifest
pub fn manifest_mut(&mut self) -> &mut Manifest
Get mutable access to the manifest
Sourcepub fn reload_manifest(&mut self) -> Result<(), LazyGraphError>
pub fn reload_manifest(&mut self) -> Result<(), LazyGraphError>
Reload manifest from disk
Sourcepub fn save_manifest(&self) -> Result<(), LazyGraphError>
pub fn save_manifest(&self) -> Result<(), LazyGraphError>
Save manifest to disk
Sourcepub fn get_partition_for_file(&self, file: &str) -> Option<&str>
pub fn get_partition_for_file(&self, file: &str) -> Option<&str>
Get the partition ID for a file path
Sourcepub fn get_partition_for_node(&self, node_id: &str) -> Option<String>
pub fn get_partition_for_node(&self, node_id: &str) -> Option<String>
Get the partition ID for a node by looking at its file path
Returns owned String since registry uses interior mutability (DashMap).
Sourcepub fn compute_partition_id(file: &str) -> String
👎Deprecated: Use compute_partition_id_for_root for multi-root support
pub fn compute_partition_id(file: &str) -> String
Compute the partition ID for a file path (directory-based partitioning)
For multi-root workspaces, use compute_partition_id_for_root instead.
Returns the parent directory path as the partition ID.
Sourcepub fn compute_partition_id_for_root(root_name: &str, file: &str) -> String
pub fn compute_partition_id_for_root(root_name: &str, file: &str) -> String
Compute partition ID for a file in a specific root (multi-root support)
Returns partition ID in format {root_name}_{directory} to avoid
collisions between roots with similar directory structures.
§Examples
use codeprysm_core::lazy::manager::LazyGraphManager;
let pid = LazyGraphManager::compute_partition_id_for_root("repo-a", "src/core/main.py");
assert_eq!(pid, "repo-a_src/core");
let pid = LazyGraphManager::compute_partition_id_for_root("repo-b", "src/core/main.py");
assert_eq!(pid, "repo-b_src/core");
// Root-level files use "{root}_root" partition
let pid = LazyGraphManager::compute_partition_id_for_root("myrepo", "main.py");
assert_eq!(pid, "myrepo_root");Sourcepub fn is_partition_loaded(&self, partition_id: &str) -> bool
pub fn is_partition_loaded(&self, partition_id: &str) -> bool
Check if a partition is currently loaded
Sourcepub fn loaded_partition_count(&self) -> usize
pub fn loaded_partition_count(&self) -> usize
Get the number of loaded partitions
Sourcepub fn loaded_partitions(&self) -> Vec<String>
pub fn loaded_partitions(&self) -> Vec<String>
Get the list of loaded partition IDs
Sourcepub fn partition_ids(&self) -> Vec<String>
pub fn partition_ids(&self) -> Vec<String>
Get all partition IDs from manifest (whether loaded or not)
Sourcepub fn node_ids_in_partition(&self, partition_id: &str) -> Option<Vec<String>>
pub fn node_ids_in_partition(&self, partition_id: &str) -> Option<Vec<String>>
Get node IDs that belong to a specific loaded partition
Returns None if the partition is not currently loaded. Use this after load_partition() to get the nodes for indexing.
Sourcepub fn load_partition(&self, partition_id: &str) -> Result<(), LazyGraphError>
pub fn load_partition(&self, partition_id: &str) -> Result<(), LazyGraphError>
Load a partition from SQLite into the petgraph
Uses double-checked locking to prevent duplicate concurrent loads of the same partition while allowing concurrent loads of different partitions.
If the partition is already loaded, this is a no-op (cache hit). If memory budget is exceeded, evicts least-recently-used partitions first.
Sourcepub fn ensure_partition_loaded(
&self,
partition_id: &str,
) -> Result<(), LazyGraphError>
pub fn ensure_partition_loaded( &self, partition_id: &str, ) -> Result<(), LazyGraphError>
Ensure a partition is loaded (load if not already loaded)
Sourcepub fn load_all_partitions(&self) -> Result<usize, LazyGraphError>
pub fn load_all_partitions(&self) -> Result<usize, LazyGraphError>
Load all partitions into memory
This is useful when you need access to the entire graph, such as for full reindexing. Note that this bypasses the memory budget and may use significant memory for large repositories.
Returns the number of partitions loaded.
Sourcepub fn unload_partition(&self, partition_id: &str) -> usize
pub fn unload_partition(&self, partition_id: &str) -> usize
Unload a partition from petgraph to free memory
Removes all nodes and edges belonging to this partition. Returns the number of nodes unloaded.
Thread-safe: Uses interior mutability via DashMap (registry), Mutex (cache), and RwLock (graph).
Sourcepub fn get_node(&self, id: &str) -> Result<Option<Node>, LazyGraphError>
pub fn get_node(&self, id: &str) -> Result<Option<Node>, LazyGraphError>
Get a node by ID, loading its partition if necessary
Returns an owned clone of the node for thread safety. This enables concurrent read access without holding locks across call boundaries.
Sourcepub fn get_node_if_loaded(&self, id: &str) -> Option<Node>
pub fn get_node_if_loaded(&self, id: &str) -> Option<Node>
Get a node by ID without loading (only returns if already loaded)
Returns an owned clone of the node for thread safety.
Sourcepub fn contains_node(&self, id: &str) -> Result<bool, LazyGraphError>
pub fn contains_node(&self, id: &str) -> Result<bool, LazyGraphError>
Check if a node exists (may require loading partition)
Sourcepub fn contains_node_if_loaded(&self, id: &str) -> bool
pub fn contains_node_if_loaded(&self, id: &str) -> bool
Check if a node exists in the currently loaded graph (no lazy loading)
Sourcepub fn get_incoming_edges(
&self,
node_id: &str,
) -> Result<Vec<(Node, EdgeData)>, LazyGraphError>
pub fn get_incoming_edges( &self, node_id: &str, ) -> Result<Vec<(Node, EdgeData)>, LazyGraphError>
Get incoming edges for a node, loading its partition if necessary
This includes both intra-partition edges (from petgraph) and cross-partition edges (from CrossRefIndex). Cross-partition source nodes are loaded as needed.
Sourcepub fn get_outgoing_edges(
&self,
node_id: &str,
) -> Result<Vec<(Node, EdgeData)>, LazyGraphError>
pub fn get_outgoing_edges( &self, node_id: &str, ) -> Result<Vec<(Node, EdgeData)>, LazyGraphError>
Get outgoing edges from a node, loading its partition if necessary
This includes both intra-partition edges (from petgraph) and cross-partition edges (from CrossRefIndex). Cross-partition target nodes are loaded as needed.
Sourcepub fn add_cross_ref(&mut self, cross_ref: CrossRef)
pub fn add_cross_ref(&mut self, cross_ref: CrossRef)
Add a cross-partition edge reference
Use this when an edge spans two different partitions.
Sourcepub fn add_cross_refs(&mut self, refs: impl IntoIterator<Item = CrossRef>)
pub fn add_cross_refs(&mut self, refs: impl IntoIterator<Item = CrossRef>)
Add multiple cross-partition edge references
Sourcepub fn get_cross_refs_by_target(
&self,
target_id: &str,
) -> Option<&Vec<CrossRef>>
pub fn get_cross_refs_by_target( &self, target_id: &str, ) -> Option<&Vec<CrossRef>>
Get cross-partition edges targeting a specific node
Sourcepub fn get_cross_refs_by_source(
&self,
source_id: &str,
) -> Option<&Vec<CrossRef>>
pub fn get_cross_refs_by_source( &self, source_id: &str, ) -> Option<&Vec<CrossRef>>
Get cross-partition edges from a specific source node
Sourcepub fn remove_cross_refs_by_partition(&mut self, partition: &str)
pub fn remove_cross_refs_by_partition(&mut self, partition: &str)
Remove all cross-partition edges involving a specific partition
Call this when a partition is being rebuilt.
Sourcepub fn cross_ref_count(&self) -> usize
pub fn cross_ref_count(&self) -> usize
Get the number of cross-partition edges
Sourcepub fn save_cross_refs(&self) -> Result<(), LazyGraphError>
pub fn save_cross_refs(&self) -> Result<(), LazyGraphError>
Save cross-partition edges to SQLite
Sourcepub fn reload_cross_refs(&mut self) -> Result<(), LazyGraphError>
pub fn reload_cross_refs(&mut self) -> Result<(), LazyGraphError>
Reload cross-partition edges from SQLite
Sourcepub fn graph(&self) -> &RwLock<PetCodeGraph>
pub fn graph(&self) -> &RwLock<PetCodeGraph>
Get access to the underlying RwLock-protected PetCodeGraph
Callers must acquire read or write lock as appropriate. Use this for operations that don’t require lazy loading.
Sourcepub fn graph_read(&self) -> RwLockReadGuard<'_, PetCodeGraph>
pub fn graph_read(&self) -> RwLockReadGuard<'_, PetCodeGraph>
Get a read lock guard on the underlying PetCodeGraph
Convenience method for read-only graph operations.
Sourcepub fn graph_write(&self) -> RwLockWriteGuard<'_, PetCodeGraph>
pub fn graph_write(&self) -> RwLockWriteGuard<'_, PetCodeGraph>
Get a write lock guard on the underlying PetCodeGraph
Convenience method for mutable graph operations.
Sourcepub fn cache_metrics(&self) -> CacheMetrics
pub fn cache_metrics(&self) -> CacheMetrics
Get a snapshot of cache metrics (hit/miss rates, evictions)
Sourcepub fn reset_cache_metrics(&self)
pub fn reset_cache_metrics(&self)
Reset cache metrics
Sourcepub fn memory_usage_bytes(&self) -> usize
pub fn memory_usage_bytes(&self) -> usize
Get current memory usage in bytes
Sourcepub fn memory_budget_bytes(&self) -> usize
pub fn memory_budget_bytes(&self) -> usize
Get memory budget in bytes
Sourcepub fn memory_usage_ratio(&self) -> f64
pub fn memory_usage_ratio(&self) -> f64
Get memory usage as a ratio (0.0 - 1.0)
Sourcepub fn is_over_budget(&self) -> bool
pub fn is_over_budget(&self) -> bool
Check if memory usage exceeds budget
Sourcepub fn stats(&self) -> LazyGraphStats
pub fn stats(&self) -> LazyGraphStats
Get statistics about the lazy graph
Auto Trait Implementations§
impl !Freeze for LazyGraphManager
impl !RefUnwindSafe for LazyGraphManager
impl Send for LazyGraphManager
impl Sync for LazyGraphManager
impl Unpin for LazyGraphManager
impl !UnwindSafe for LazyGraphManager
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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