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
//! Thread-local scratch pool for n-ary all-different singleton collection.
//!
//! The plain [`AllDifferent`](super::all_different::AllDifferent) and the
//! small-scope [`AllDifferentExcept`](super::all_different_except::AllDifferentExcept)
//! path both take a *snapshot* of which scope variables are singletons before
//! pruning peers. Allocating that `Vec<(VarId, Value)>` on every `revise()` was
//! the dominant malloc source on generation / large-board workloads (86% / 75%
//! / ~55% on gen_holedig / sudoku16 / futoshiki7, per the L26 profile). This
//! pool reuses one thread-local buffer per value type instead, preserving the
//! snapshot-then-prune semantics **exactly** (byte-identical domains) — it is a
//! pure allocation optimization, not a behavioral change.
//!
//! The buffer is borrowed only for the duration of the supplied closure and
//! released before it returns; callers MUST NOT hold it across a re-entrant
//! call into another scratch-borrowing path — notably
//! [`propagate_gac_core`](crate::solver::gac::propagate_gac_core), which
//! borrows its own thread-local. It is a distinct structure from that core's
//! `assigned_ns`, so the two never alias.
use Any;
use RefCell;
use VarId;
thread_local!
/// Run `f` with a cleared, reused thread-local `Vec<(VarId, V)>` scratch.
///
/// The buffer is cleared on entry and the borrow is released when `f` returns.
pub ) where
V: 'static,