1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// Copyright 2025 the Invalidation Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT
//! Reusable scratch buffers for graph traversals.
//!
//! `TraversalScratch` is the simplest way to keep repeated eager traversals
//! from allocating on every call.
//!
//! ```
//! use invalidation::{
//! Channel, CycleHandling, EagerPolicy, InvalidationGraph, InvalidationSet, TraversalScratch,
//! };
//!
//! const LAYOUT: Channel = Channel::new(0);
//!
//! let mut graph = InvalidationGraph::<u32>::new();
//! graph.add_dependency(2, 1, LAYOUT, CycleHandling::Error).unwrap();
//! graph.add_dependency(3, 2, LAYOUT, CycleHandling::Error).unwrap();
//!
//! let mut invalidated = InvalidationSet::new();
//! let mut scratch = TraversalScratch::with_capacity(8);
//!
//! for root in [1, 2] {
//! EagerPolicy.propagate_with_scratch(root, LAYOUT, &graph, &mut invalidated, &mut scratch);
//! }
//!
//! assert!(invalidated.is_invalidated(1, LAYOUT));
//! assert!(invalidated.is_invalidated(2, LAYOUT));
//! assert!(invalidated.is_invalidated(3, LAYOUT));
//! ```
use Vec;
use Hash;
use HashSet;
/// Reusable scratch storage for graph traversals.
///
/// This is useful in tight loops (many marks per frame) to avoid allocating
/// temporary `Vec`/`HashSet` state on every traversal.
///
/// The scratch buffers retain capacity across calls. Callers should reuse a
/// single scratch instance per thread / update pass.
///
/// # See Also
///
/// - [`InvalidationGraph::for_each_transitive_dependent`](crate::InvalidationGraph::for_each_transitive_dependent):
/// Scratch-powered traversal.
/// - [`EagerPolicy::propagate_with_scratch`](crate::EagerPolicy::propagate_with_scratch):
/// Scratch-powered eager propagation.