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 and resolved pending-reference state, so re-extracting a single changed file rebuilds only that file’s subgraph and selectively restitches affected cross-file references.

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 affected cross-file edges are selectively restitched.
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, applying the whole set as ONE batch so the cross-file stitch runs a single time. Produces the identical graph to a new() followed by an upsert per file — the stitch is order-independent for a complete set — but avoids the quadratic cost of sequential upserts: each upsert that changes a re-export re-resolves every pending reference (commit_prepared_bounded), so a per-file cold build of a project whose files carry pub use re-exports is O(N²). Batching keeps it linear.

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.

Restore and fact upserts share one prepared commit path, so their index bookkeeping cannot drift.

Source

pub fn try_upsert_subgraph( &mut self, file: String, sub: FileSubgraph, ) -> Result<()>

Atomically restore a persisted subgraph after validating its schema and ownership. On error neither the file store nor global index changes.

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

Return the full CodeGraph from stored resolved cross-file state.

Deterministic: file keys and pending ordinals are processed in sorted owner/ordinal order, regardless of upsert history.

Source

pub fn len(&self) -> usize

Number of files currently held.

Source

pub fn is_empty(&self) -> bool

Whether the store holds no files.

Source§

impl IncrementalGraph

Source

pub fn into_tracked( self, snapshot: ScopeSnapshotToken, ) -> TrackedIncrementalGraph

Bind this complete graph state to its consumer-provided snapshot token.

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.