Skip to main content

DependencyGraph

Struct DependencyGraph 

Source
pub struct DependencyGraph {
    pub tombstone_registry: TombstoneRegistry,
    /* private fields */
}
Expand description

SoA-based dependency graph implementation

Fields§

§tombstone_registry: TombstoneRegistry

Implementations§

Source§

impl DependencyGraph

Source

pub fn is_ast_dynamic(&self, ast: &ASTNode) -> bool

Source§

impl DependencyGraph

Source

pub fn define_name( &mut self, name: &str, definition: NamedDefinition, scope: NameScope, ) -> Result<(), ExcelError>

Define a new named range

Source

pub fn named_ranges_iter(&self) -> impl Iterator<Item = (&String, &NamedRange)>

Iterate workbook-scoped named ranges (for bindings/testing)

Source

pub fn sheet_named_ranges_iter( &self, ) -> impl Iterator<Item = (&(SheetId, String), &NamedRange)>

Iterate sheet-scoped named ranges (for bindings/testing)

Source

pub fn resolve_name_entry_in_scope( &self, name: &str, scope: NameScope, ) -> Option<&NamedRange>

Resolve a name in an explicit NameScope.

NameScope::Sheet looks in that sheet’s names first and falls back to workbook scope, matching Excel’s shadowing rules. NameScope::Workbook looks in workbook-scoped names only: a sheet-scoped name is invisible to a workbook-scope query even when it is scoped to the default sheet.

This is the single owned derivation for name scoping. A caller with no sheet context asks for NameScope::Workbook, never for the default sheet’s scope - substituting the default sheet for missing context is what leaked references onto unrelated sheets in issue #110.

Source

pub fn resolve_name_entry( &self, name: &str, current_sheet: SheetId, ) -> Option<&NamedRange>

Resolve a name as seen from current_sheet: sheet scope shadows workbook scope. Equivalent to Self::resolve_name_entry_in_scope with NameScope::Sheet.

Source

pub fn resolve_name( &self, name: &str, current_sheet: SheetId, ) -> Option<&NamedDefinition>

Resolve a named range to its definition

Source

pub fn named_range_by_vertex(&self, vertex: VertexId) -> Option<&NamedRange>

Source

pub fn update_name( &mut self, name: &str, new_definition: NamedDefinition, scope: NameScope, ) -> Result<(), ExcelError>

Update an existing named range definition

Source

pub fn delete_name( &mut self, name: &str, scope: NameScope, ) -> Result<(), ExcelError>

Delete a named range

Source

pub fn adjust_named_ranges( &mut self, operation: &ShiftOperation, ) -> Result<(), ExcelError>

Source

pub fn mark_as_name_error(&mut self, vertex_id: VertexId)

Mark a vertex as having a #NAME! error

Source§

impl DependencyGraph

Source

pub fn add_range_edges( &mut self, dependent: VertexId, ranges: &[SharedRangeRef<'static>], current_sheet_id: SheetId, )

Public wrapper to add range-dependent edges.

Source

pub fn get_range_dependencies( &self, vertex: VertexId, ) -> Option<&Vec<SharedRangeRef<'static>>>

Return the compressed range dependencies recorded for a formula vertex, if any. These are SharedRangeRef entries that were not expanded into explicit cell edges due to range_expansion_limit or due to infinite/partial bounds.

Source

pub fn add_range_deps_from_keys( &mut self, dependent: VertexId, keys: &[RangeKey], current_sheet_id: SheetId, )

Fast-path: add range dependencies using compact RangeKey.

Source§

impl DependencyGraph

Source

pub fn add_sheet(&mut self, name: &str) -> Result<SheetId, ExcelError>

Add a new sheet to the workbook.

Creates a new sheet with the given name. If a sheet with this name already exists, returns its ID without error (idempotent operation).

Source

pub fn remove_sheet(&mut self, sheet_id: SheetId) -> Result<(), ExcelError>

Remove a sheet from the workbook.

Source

pub fn rename_sheet( &mut self, sheet_id: SheetId, new_name: &str, ) -> Result<(), ExcelError>

Rename an existing sheet.

Source

pub fn duplicate_sheet( &mut self, source_sheet_id: SheetId, new_name: &str, ) -> Result<SheetId, ExcelError>

Duplicate an existing sheet.

Source§

impl DependencyGraph

Source

pub fn resolve_source_scalar_entry( &self, name: &str, ) -> Option<&SourceScalarEntry>

Source

pub fn resolve_source_table_entry( &self, name: &str, ) -> Option<&SourceTableEntry>

Source

pub fn define_source_scalar( &mut self, name: &str, version: Option<u64>, ) -> Result<(), ExcelError>

Source

pub fn define_source_table( &mut self, name: &str, version: Option<u64>, ) -> Result<(), ExcelError>

Source

pub fn set_source_scalar_version( &mut self, name: &str, version: Option<u64>, ) -> Result<(), ExcelError>

Source

pub fn set_source_table_version( &mut self, name: &str, version: Option<u64>, ) -> Result<(), ExcelError>

Source

pub fn invalidate_source(&mut self, name: &str) -> Result<(), ExcelError>

Source§

impl DependencyGraph

Source

pub fn table_names(&self) -> Vec<String>

Canonical names of every defined table, sorted for deterministic output.

Source

pub fn define_table( &mut self, name: &str, range: RangeRef, header_row: bool, headers: Vec<String>, totals_row: bool, ) -> Result<(), ExcelError>

Source

pub fn update_table( &mut self, name: &str, new_range: RangeRef, header_row: bool, headers: Vec<String>, totals_row: bool, ) -> Result<(), ExcelError>

Source

pub fn delete_table(&mut self, name: &str) -> Result<(), ExcelError>

Source§

impl DependencyGraph

Source

pub fn range_expansion_limit(&self) -> usize

Expose range expansion limit for planners

Source

pub fn get_config(&self) -> &EvalConfig

Source

pub fn baseline_stats(&self) -> GraphBaselineStats

Return read-only baseline counters for FormulaPlane/dispatch benchmarking.

Source

pub fn plan_dependencies<'a, I>( &mut self, items: I, policy: &CollectPolicy, volatile: Option<&[bool]>, ) -> Result<DependencyPlan, ExcelError>
where I: IntoIterator<Item = (&'a str, u32, u32, &'a ASTNode)>,

Build a dependency plan for a set of formulas on sheets

Source

pub fn plan_dependencies_mixed<'a, I>( &mut self, items: I, policy: &CollectPolicy, volatile: Option<&[bool]>, ) -> Result<DependencyPlan, ExcelError>
where I: IntoIterator<Item = (&'a str, u32, u32, DependencyPlanAst<'a>)>,

Source

pub fn ensure_vertices_batch( &mut self, coords: &[(SheetId, AbsCoord)], ) -> Vec<(VertexAddr, u32)>

Ensure vertices exist for given coords; allocate missing in contiguous batches and add to edges/index. Returns a list suitable for edges.add_vertices_batch.

Source

pub fn ensure_vertices_batch_packed_ordered( &mut self, packed_cells: &[PackedSheetCell], ) -> (Vec<VertexId>, Vec<(VertexAddr, u32)>)

Ensure vertices exist for given packed absolute cells and return vertex ids aligned to the input order, plus the newly allocated (coord, raw_vid) items suitable for edge/index population.

Source

pub fn ensure_vertices_batch_ordered( &mut self, coords: &[(SheetId, AbsCoord)], ) -> (Vec<VertexId>, Vec<(VertexAddr, u32)>)

Ensure vertices exist for given coords and return vertex ids aligned to the input order, plus the newly allocated (coord, raw_vid) items suitable for edge/index population.

Source

pub fn set_first_load_assume_new(&mut self, enabled: bool)

Enable/disable the first-load fast path for value inserts.

Source

pub fn reset_ensure_touched(&mut self)

Reset the per-sheet ensure touch tracking.

Source

pub fn store_ast(&mut self, ast: &ASTNode) -> AstNodeId

Store an AST and return its arena id.

Source

pub fn store_asts_batch<'a, I>(&mut self, asts: I) -> Vec<AstNodeId>
where I: IntoIterator<Item = &'a ASTNode>,

Store ASTs in batch and return their arena ids

Source

pub fn reserve_formula_metadata(&mut self, additional: usize)

Reserve metadata structures for upcoming formula assignments during bulk load.

Source

pub fn vid_for_sid_pc(&self, sid: SheetId, pc: AbsCoord) -> Option<VertexId>

Lookup VertexId for a (SheetId, AbsCoord)

Source

pub fn vid_for_plan_idx( &self, plan: &DependencyPlan, idx: u32, ) -> Option<VertexId>

Helper to map a global cell index in a plan to a VertexId

Source

pub fn assign_formula_vertex( &mut self, vid: VertexId, ast_id: AstNodeId, volatile: bool, dynamic: bool, )

Assign a formula to an existing vertex, removing prior edges and setting flags

Source

pub fn assign_formula_vertex_load_fast( &mut self, vid: VertexId, ast_id: AstNodeId, volatile: bool, dynamic: bool, )

Fast path for initial workbook load: assign a formula to a vertex that is known not to already own dependency edges in the graph. Dirtiness is batched separately.

Source

pub fn add_edges_nobatch( &mut self, dependent: VertexId, dependencies: &[VertexId], )

Public wrapper for adding edges without beginning a batch (caller manages batch)

Source

pub fn iter_vertex_ids(&self) -> impl Iterator<Item = VertexId> + '_

Iterate all normal vertex ids

Source

pub fn vertex_addr(&self, vid: VertexId) -> VertexAddr

Get the current address of a vertex: a grid position, or a symbol identity for names, tables and external sources.

Source

pub fn vertex_grid_addr(&self, vid: VertexId) -> Option<GridAddr>

Get the current grid position of a vertex, or None when it is a symbol.

Source

pub fn vertex_count(&self) -> usize

Total number of allocated vertices (including deleted)

Source

pub fn build_edges_from_adjacency( &mut self, adjacency: Vec<(u32, Vec<u32>)>, coords: Vec<VertexAddr>, vertex_ids: Vec<u32>, )

Replace CSR edges in one shot from adjacency and coords

Source

pub fn used_row_bounds_for_columns( &self, sheet_id: SheetId, start_col: u32, end_col: u32, ) -> Option<(u32, u32)>

Compute min/max used row among vertices within [start_col..=end_col] on a sheet.

Source

pub fn finalize_sheet_index(&mut self, sheet: &str)

Build (or rebuild) the sheet index for a given sheet.

Source

pub fn set_sheet_index_mode(&mut self, mode: SheetIndexMode)

Source

pub fn used_col_bounds_for_rows( &self, sheet_id: SheetId, start_row: u32, end_row: u32, ) -> Option<(u32, u32)>

Compute min/max used column among vertices within [start_row..=end_row] on a sheet.

Source

pub fn sheet_has_formulas(&self, sheet_id: SheetId) -> bool

Returns true if the given sheet currently contains any formula vertices.

Source

pub fn new() -> Self

Source

pub fn new_with_config(config: EvalConfig) -> Self

Source

pub fn begin_batch(&mut self)

Begin batch operations - defer CSR rebuilds until end_batch() is called

Source

pub fn end_batch(&mut self)

End batch operations and trigger CSR rebuild if needed

Source

pub fn default_sheet_id(&self) -> SheetId

Source

pub fn default_sheet_name(&self) -> &str

Source

pub fn set_default_sheet_by_name(&mut self, name: &str)

Source

pub fn set_default_sheet_by_id(&mut self, id: SheetId)

Source

pub fn sheet_id_mut(&mut self, name: &str) -> SheetId

Returns the ID for a sheet name, creating one if it doesn’t exist.

Source

pub fn sheet_id(&self, name: &str) -> Option<SheetId>

Source

pub fn sheet_name(&self, id: SheetId) -> &str

Returns the name of a sheet given its ID.

Source

pub fn sheet_reg(&self) -> &SheetRegistry

Access the sheet registry (read-only) for external bindings

Source

pub fn to_a1(&self, cell_ref: CellRef) -> String

Converts a CellRef to a fully qualified A1-style string (e.g., “SheetName!A1”).

Source

pub fn sheet_index_mut(&mut self, sheet_id: SheetId) -> &mut SheetIndex

Get mutable access to a sheet’s index, creating it if it doesn’t exist This is the primary way VertexEditor and internal operations access the index

Source

pub fn sheet_index(&self, sheet_id: SheetId) -> Option<&SheetIndex>

Get immutable access to a sheet’s index, returns None if not initialized

Source

pub fn set_cell_value( &mut self, sheet: &str, row: u32, col: u32, value: LiteralValue, ) -> Result<OperationSummary, ExcelError>

Set a value in a cell, returns affected vertex IDs

Source

pub fn reserve_cells(&mut self, additional: usize)

Reserve capacity hints for upcoming bulk cell inserts (values only for now).

Source

pub fn set_cell_value_bulk_untracked( &mut self, sheet: &str, row: u32, col: u32, value: LiteralValue, ) -> Result<(), ExcelError>

Fast path for initial bulk load of value cells: avoids dirty propagation & dependency work.

Source

pub fn bulk_insert_values<I>( &mut self, sheet: &str, cells: I, ) -> Result<(), ExcelError>
where I: IntoIterator<Item = (u32, u32, LiteralValue)>,

Bulk insert a collection of plain value cells (no formulas) more efficiently.

Source

pub fn set_cell_formula( &mut self, sheet: &str, row: u32, col: u32, ast: ASTNode, ) -> Result<OperationSummary, ExcelError>

Set a formula in a cell, returns affected vertex IDs

Source

pub fn set_cell_formula_with_volatility( &mut self, sheet: &str, row: u32, col: u32, ast: ASTNode, _volatile: bool, ) -> Result<OperationSummary, ExcelError>

Set a formula in a cell. The volatility argument is retained for API compatibility; dependency flags now come from IngestPipeline.

Source

pub fn set_cell_value_ref( &mut self, cell: SheetCellRef<'_>, value: LiteralValue, ) -> Result<OperationSummary, ExcelError>

Source

pub fn set_cell_formula_ref( &mut self, cell: SheetCellRef<'_>, ast: ASTNode, ) -> Result<OperationSummary, ExcelError>

Source

pub fn get_cell_value_ref(&self, cell: SheetCellRef<'_>) -> Option<LiteralValue>

Source

pub fn get_cell_value( &self, sheet: &str, row: u32, col: u32, ) -> Option<LiteralValue>

Get current value from a cell

Source

pub fn begin_deferred_dirty(&mut self)

Begin a deferred-dirty scope for a multi-edit batch.

While active, mark_dirty / mark_dirty_many / mark_dirty_many_value_cells queue their sources instead of running a BFS per call; the outermost end_deferred_dirty flushes the queued union with ONE multi-source mark_dirty_many. Union semantics equal the sequential per-edit calls (pinned by mark_dirty_many_equals_sequential_single_source_marks plus the deferred-scope tests): any dependent edge removed mid-batch belongs to a vertex that was itself edited mid-batch, and edited vertices are themselves pending sources, so the flush covers everything a per-edit propagation would have reached.

Nesting is depth-counted. The scope also enters the CSR edge batch (begin_batch) so edge-heavy batches amortize delta rebuilds (#127).

Callers MUST guarantee end_deferred_dirty runs on every exit path (including ? early returns): a leaked scope would silently swallow future propagations. Evaluation entry points debug_assert that no scope is active.

Source

pub fn end_deferred_dirty(&mut self) -> Vec<VertexId>

End a deferred-dirty scope. When the outermost scope ends, runs ONE multi-source propagation over every source queued while deferred and returns its full affected set (sources pointing at vertices deleted mid-batch are skipped). Inner (nested) ends return an empty set.

Source

pub fn deferred_dirty_active(&self) -> bool

True while a deferred-dirty scope is active (see begin_deferred_dirty). Evaluation must never start in this state.

Source

pub fn get_evaluation_vertices(&self) -> Vec<VertexId>

Get all vertices that need evaluation

Source

pub fn clear_dirty_flags(&mut self, vertices: &[VertexId])

Clear dirty flags after successful evaluation

Source

pub fn clear_volatile_flags(&mut self)

🔮 Scalability Hook: Clear volatile vertices after evaluation cycle

Source

pub fn bulk_set_formulas<I>( &mut self, sheet: &str, items: I, ) -> Result<usize, ExcelError>
where I: IntoIterator<Item = (u32, u32, ASTNode)>,

Bulk set formulas on a sheet using a single dependency plan and batched edge updates.

Source

pub fn bulk_set_formulas_with_volatility( &mut self, sheet: &str, collected: Vec<(u32, u32, ASTNode)>, _vol_flags: Vec<bool>, ) -> Result<usize, ExcelError>

Source

pub fn add_dependency_edge( &mut self, dependent: VertexId, dependency: VertexId, ) -> Result<(), ExcelError>

Public (crate) helper to add a single dependency edge (dependent -> dependency) used for restoration/undo.

Source

pub fn plan_spill_region( &self, anchor: VertexId, target_cells: &[CellRef], ) -> Result<(), ExcelError>

Plan a spill region for an anchor; returns #SPILL! if blocked

Source

pub fn commit_spill_region_atomic_with_fault( &mut self, anchor: VertexId, target_cells: Vec<CellRef>, values: Vec<Vec<LiteralValue>>, fault_after_ops: Option<usize>, ) -> Result<(), ExcelError>

Commit a spill atomically with an internal shadow buffer and optional fault injection. If a fault is injected partway through, all changes are rolled back to the pre-commit state. This does not change behavior under normal operation; it’s primarily for Phase 3 guarantees and tests.

Source

pub fn clear_spill_region(&mut self, anchor: VertexId)

Clear an existing spill region for an anchor (set cells to Empty and forget ownership)

Source

pub fn clear_spill_region_bulk(&mut self, anchor: VertexId) -> Vec<CellRef>

Bulk clear an existing spill region for an anchor.

This avoids calling set_cell_value() per spill child (which can trigger O(N*V) dependent scans when edges.delta_size() > 0). Instead, it clears values directly and performs a single dirty propagation over the affected spill children.

Returns the previously registered spill cells (including the anchor cell) for callers that want to mirror/record deltas.

Source

pub fn get_formula_id(&self, vertex_id: VertexId) -> Option<AstNodeId>

Source

pub fn get_formula_id_and_volatile( &self, vertex_id: VertexId, ) -> Option<(AstNodeId, bool)>

Source

pub fn get_formula_node(&self, vertex_id: VertexId) -> Option<&AstNodeData>

Source

pub fn get_formula_node_and_volatile( &self, vertex_id: VertexId, ) -> Option<(&AstNodeData, bool)>

Source

pub fn get_formula(&self, vertex_id: VertexId) -> Option<ASTNode>

Get the formula AST for a vertex.

Not used in hot paths; reconstructs from arena.

Source

pub fn get_value(&self, vertex_id: VertexId) -> Option<LiteralValue>

Get the value stored for a vertex

Source

pub fn make_cell_ref(&self, sheet_name: &str, row: u32, col: u32) -> CellRef

Create a cell reference from sheet name and Excel 1-based coordinates.

Source

pub fn get_vertex_id_for_address(&self, addr: &CellRef) -> Option<&VertexId>

Get vertex ID for a cell address

Source

pub fn is_ref_error(&self, id: VertexId) -> bool

Check if a vertex has a #REF! error

Source

pub fn flush_pending_edge_deltas(&mut self)

Fold pending edge deltas into the CSR base ahead of a read-heavy phase (scheduling/evaluation), restoring the zero-allocation slice fast paths. No-op when no deltas are pending. This is the read-side half of the #125 amortization: writes defer rebuilds, read bursts pay for at most one.

Source

pub fn get_vertex_for_cell(&self, addr: &CellRef) -> Option<VertexId>

Get vertex ID for specific cell address

Source

pub fn get_grid_addr(&self, id: VertexId) -> Option<GridAddr>

Get the grid position of a vertex (public for VertexEditor).

None for symbol vertices, which have no position. Structural operations iterate grid positions, so this is what keeps them away from names, tables and sources.

Source

pub fn get_sheet_id(&self, id: VertexId) -> SheetId

Get sheet_id for a vertex (public for VertexEditor)

Source

pub fn grid_vertices_in_sheet( &self, sheet_id: SheetId, ) -> impl Iterator<Item = (VertexId, GridAddr)> + '_

Get every grid-resident vertex on a sheet, paired with its position.

Symbol vertices (names, tables, external sources) are structurally absent: they have no grid position, so they cannot be produced here. Structural edits drive off this iterator, which is why a row or column operation can no longer delete or shift a name vertex (#302, #304).

Source

pub fn vertex_has_formula(&self, id: VertexId) -> bool

Does a vertex have a formula associated

Source

pub fn vertices_with_formulas(&self) -> impl Iterator<Item = VertexId> + '_

Get all vertices with formulas

Source

pub fn update_vertex_formula( &mut self, id: VertexId, ast: ASTNode, ) -> Result<(), ExcelError>

Update a vertex’s formula

Source

pub fn mark_vertex_dirty(&mut self, vertex_id: VertexId)

Mark a vertex as dirty without propagation (for VertexEditor)

Source

pub fn mark_vertices_dirty_batch(&mut self, vertices: &[VertexId])

Batch-mark vertices dirty without propagation.

Source

pub fn update_cell_mapping( &mut self, id: VertexId, old_addr: Option<CellRef>, new_addr: CellRef, )

Update cell mapping for a vertex (for VertexEditor)

Source

pub fn remove_cell_mapping(&mut self, addr: &CellRef)

Remove cell mapping (for VertexEditor)

Source

pub fn get_cell_ref_for_vertex(&self, id: VertexId) -> Option<CellRef>

Get the cell reference for a vertex

Trait Implementations§

Source§

impl Debug for DependencyGraph

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for DependencyGraph

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Allocation for T
where T: RefUnwindSafe + Send + Sync,

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

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

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.