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

Leaving the load scope builds the dependency authority once (it was not synced during the load; see authority_load_skips_closures).

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

Decision 27: a value cell has no vertex. A formula it replaces retires its id (value -> formula at the cell takes it back); the cell’s dependents are dirtied by position. Arrow holds the value.

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. A value cell gets no vertex (decision 27); a formula there retires.

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): value cells get no vertex (decision 27); a formula at such a cell retires. No dirty propagation (load paths).

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 plan_spill_region( &self, anchor: VertexId, target_cells: &[CellRef], ) -> Result<(), ExcelError>

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

A target cell blocks the spill when it is owned by another anchor’s spill, holds another formula (scalar or array), or holds a non-empty value. Evaluation turns a blocked plan into a #SPILL! anchor value.

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.

Precondition: target_cells is the full spill rectangle in row-major order, starting at the anchor cell. The registry stores the vector verbatim, and Self::spill_extent_for_anchor reads the rectangle from its first and last cells in O(1) (returning None for a vector that fails its shape check, such as a truncated snapshot).

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>

The vertex’s own arena formula root. None for a compressed family member (its formula is a shared template at an offset; use Self::formula_view or Self::get_formula).

Source

pub fn formula_view(&self, vertex_id: VertexId) -> Option<FormulaView>

The formula of a formula vertex as a template plus offset.

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.

Returns the id by value (0.10: it returned Option<&VertexId>, a borrow of the cell map, which no longer holds compressed family members).

Source

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

Check if a vertex has a #REF! error

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.