pub struct SolverState<E: BodyEvaluator> { /* private fields */ }Expand description
Live state of the solver.
Implementations§
Source§impl<E: BodyEvaluator> SolverState<E>
impl<E: BodyEvaluator> SolverState<E>
Sourcepub fn new(graph: ModuleGraph, evaluator: E) -> Self
pub fn new(graph: ModuleGraph, evaluator: E) -> Self
Construct a fresh solver for graph. Builds the reverse-
dependency index up-front so per-iteration scheduling is O(1)
per dirty path.
Sourcepub fn env(&self) -> &EnvSnapshot
pub fn env(&self) -> &EnvSnapshot
Borrow the current env snapshot.
Sourcepub fn graph(&self) -> &ModuleGraph
pub fn graph(&self) -> &ModuleGraph
Borrow the compiled graph back out.
Sourcepub fn setter_count(&self) -> usize
pub fn setter_count(&self) -> usize
Total setter count across all modules.
Sourcepub fn schedule_for_dirty(
&self,
dirty_paths: &[ConfigPath],
) -> BTreeSet<GlobalSetterId>
pub fn schedule_for_dirty( &self, dirty_paths: &[ConfigPath], ) -> BTreeSet<GlobalSetterId>
Find every CONSUMER setter that needs to fire because at least
one of dirty_paths matches a prefix of its slice.
“Matches a prefix” means: if a setter’s slice is
[["services", "atticd"]] and dirty_paths contains
["services", "atticd", "enable"], the setter is scheduled —
a slice over a subtree fires on any descendant change.
Writers are deliberately not included here. A writer’s own
re-firing happens only when its OWN slice changes (covered by
the readers lookup that finds it as a consumer of its
upstream’s outputs). Multi-writer conflict resolution happens
at the evaluator layer via ConfigSetter::priority —
firing each writer once per topo pass is enough.
Sourcepub fn topological_order(&self) -> Result<Vec<GlobalSetterId>, SolverError>
pub fn topological_order(&self) -> Result<Vec<GlobalSetterId>, SolverError>
Topological order of all setters by writes→reads dependency. Kahn’s algorithm.
§Errors
SolverError::Cycle if the writes→reads graph has a cycle
(which is a module-author bug — cppnix would also fail here).
Sourcepub fn fire(&mut self, gid: GlobalSetterId) -> Result<ConfigPath, SolverError>
pub fn fire(&mut self, gid: GlobalSetterId) -> Result<ConfigPath, SolverError>
Fire one setter, write its result into the env, mark it fired.
Returns the setter’s own assigns_path so callers can register
it as newly-dirty.
§Errors
SolverError::BodyEval when the body evaluator rejects.
Sourcepub fn run(
&mut self,
initial_dirty: &[ConfigPath],
) -> Result<Vec<GlobalSetterId>, SolverError>
pub fn run( &mut self, initial_dirty: &[ConfigPath], ) -> Result<Vec<GlobalSetterId>, SolverError>
Run the solver to quiescence starting from initial_dirty.
Returns the firing order in temporal sequence. Caller can
inspect Self::env afterward for the final config attrset.
On a cold rebuild (no env, no prior dirty), pass an empty
initial_dirty and the solver runs every setter in topological
order. On a warm rebuild where only services.atticd.enable
changed, pass [vec!["services", "atticd", "enable"]] and only
the setters depending on that slice fire.
§Errors
Cycles or body-eval failures surface as SolverError.
Auto Trait Implementations§
impl<E> Freeze for SolverState<E>where
E: Freeze,
impl<E> RefUnwindSafe for SolverState<E>where
E: RefUnwindSafe,
impl<E> Send for SolverState<E>where
E: Send,
impl<E> Sync for SolverState<E>where
E: Sync,
impl<E> Unpin for SolverState<E>where
E: Unpin,
impl<E> UnsafeUnpin for SolverState<E>where
E: UnsafeUnpin,
impl<E> UnwindSafe for SolverState<E>where
E: UnwindSafe,
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
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> LayoutRaw for T
impl<T> LayoutRaw for T
Source§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Source§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
Source§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
out indicating that a T is niched.