Skip to main content

IncrementalGraph

Struct IncrementalGraph 

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

Incremental Tier-B resolution store. Holds one isolated subgraph per file plus a global definition index, so re-extracting a single changed file rebuilds only that file’s subgraph — never the whole graph — while graph stitches the current cross-file edges on demand.

Output is identical (up to ordering) to running ScopeGraphResolver over the same file set: both share the same per-file build and stitch passes.

use code2graph::{extract_path, resolve::IncrementalGraph};

// `app` imports `Config` from `conf`.
let conf = extract_path("src/conf.rs", "pub struct Config {}").unwrap();
let app = extract_path("src/app.rs", "use conf::Config;\npub fn run() {}").unwrap();

// Keep a resolved graph current as files change: each file is resolved in
// isolation and cross-file edges are stitched on demand.
let mut graph = IncrementalGraph::from_files(&[conf, app]);
let resolves_import = |g: code2graph::graph::CodeGraph| {
    g.edges.iter().any(|e| e.to.to_scip_string().ends_with("conf/Config#"))
};
assert!(resolves_import(graph.graph()));

// Re-extract only the changed file; `conf` is never reprocessed.
let app = extract_path("src/app.rs", "use conf::Config;\npub fn helper() {}").unwrap();
graph.upsert(&app);
assert!(resolves_import(graph.graph()));

Implementations§

Source§

impl IncrementalGraph

Source

pub fn new() -> Self

An empty store.

Source

pub fn from_files(files: &[FileFacts]) -> Self

Build a store from a file set by upserting each in turn. Ergonomic constructor equivalent to new() followed by an upsert per file.

Source

pub fn upsert(&mut self, facts: &FileFacts)

Insert or replace the subgraph for facts.file.

Re-extracting a file rebuilds ONLY that file’s subgraph — structurally guaranteed, because the per-file build reads no file but the one passed. If a subgraph already existed for this key, its definitions are removed from the global index first, so the index reflects only the current set.

Source

pub fn subgraph(&self, file: &str) -> Option<&FileSubgraph>

Return the stored FileSubgraph for a file key, or None if the file is not present in the store.

This is the persistence read path: a consumer serializes the returned subgraph (e.g. with serde_json::to_string) and writes it to a cache store keyed by file path. On the next startup, the consumer deserializes each cached blob and restores it via upsert_subgraph — bypassing build_subgraph entirely for files that have not changed.

Source

pub fn upsert_subgraph(&mut self, file: String, sub: FileSubgraph)

Insert or replace a PRE-BUILT (e.g. deserialized) FileSubgraph for file, updating the global definition index to reflect the new contents.

This is the persistence write path (the restore leg): after deserializing a cached subgraph on startup, call this method to re-populate the store without re-running build_subgraph. The global index is rebuilt from the restored symbols, so the index is never itself persisted — the subgraphs are the single source of truth, and the index is always derived from them.

If a subgraph already exists for file (e.g. a hot-reload of a changed file), its symbols are removed from the index first, exactly as upsert does, so the index never accumulates stale entries.

All of upsert’s index-bookkeeping lives here; upsert itself delegates to this method (after calling build_subgraph) so the two paths can never drift.

Source

pub fn remove(&mut self, file: &str)

Drop the file file from the store, removing its definitions from the global index. A no-op if the file is not present.

Source

pub fn graph(&self) -> CodeGraph

Stitch the current cross-file edges and return the full CodeGraph.

Deterministic: file keys are processed in sorted order, so symbols, intra-file edges, and pending refs always accumulate in the same order regardless of upsert history. Cross-file edges are stitched last against the current global index.

Source

pub fn len(&self) -> usize

Number of files currently held.

Source

pub fn is_empty(&self) -> bool

Whether the store holds no files.

Trait Implementations§

Source§

impl Default for IncrementalGraph

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, 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, 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.