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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! Small server helpers without a more natural home.
use *;
/// How many artifact-persist tasks may be in flight concurrently.
///
/// The daemon's persist path writes each cached artifact to disk via
/// `std::fs::write` inside `tokio::task::spawn_blocking`. On Windows with
/// Defender real-time protection, every write blocks until Defender finishes
/// scanning the file. The hardcoded default of 8 was retained because raising
/// it without other changes regressed wall-clock on this machine
/// (see `tests/persist_pool_bench.rs`). The env var gives operators a lever
/// when their workload differs — e.g. cache on a network mount, or a slow
/// AV setup that benefits from more in-flight writes.
///
/// Override with `ZCCACHE_STORE_WORKERS=<N>` (must be ≥ 1, clamped to 1024).
pub
/// Hash a file using the metadata cache (with watcher-assisted confidence).
pub
/// Hash a file using the CacheSystem's metadata cache.
///
/// This stat-verifies the file, hashes if needed (with TOCTOU protection),
/// and caches the result. The file watcher proactively downgrades confidence
/// on changes, ensuring stale hashes are re-computed.
///
/// `clock` should be snapped once at the start of each compile request so all
/// files in a single compilation see a consistent journal clock.
pub
/// Check if all files in a context's dependency list are unchanged since
/// the given clock. Uses per-file journal tracking instead of global clock
/// comparison, so output file changes (like .o writes) don't invalidate
/// fast-hit entries for unrelated source contexts.
pub
/// Look up an artifact by key, falling through to the on-disk
/// [`ArtifactStore`] when the in-memory [`SharedState::artifacts`] DashMap
/// has not yet been hydrated.
///
/// # Why the fallthrough is required
///
/// Daemon startup spawns a background task that copies every entry from
/// `state.artifact_store` (loaded synchronously by `ArtifactStore::open`)
/// into `state.artifacts`. The daemon begins accepting IPC requests
/// immediately, before that background task finishes. Without this
/// helper, the warm-after-restore window (`soldr load` → first compile)
/// reports MISS on every lookup until the DashMap catches up — measured
/// at 0/115 hits on the medium fixture's `cold-tar-untar-warm`
/// scenario (perf-cluster run 26255457227).
///
/// The DashMap is a cache *of* the on-disk store; the on-disk store is
/// the source of truth for artifact existence. Lookups now:
/// 1. Hit the in-memory DashMap (fast path; populated by stores +
/// background load).
/// 2. On miss, consult the in-memory hashmap that backs
/// [`ArtifactStore::open`] (also fast — already hydrated from
/// `index.bin` at daemon bind time).
/// 3. On disk-store hit, hydrate the DashMap so subsequent lookups
/// skip the fallback entirely.
///
/// # Why two `get_mut` calls
///
/// DashMap forbids holding a shard lock (`get_mut` returns a guard
/// holding it) across an `insert` on the same map — that would
/// deadlock. We release the first guard's `None` arm, do the
/// disk-store lookup + insert, then take a fresh `get_mut` to hand
/// back. The `insert` + re-`get_mut` is on the cold path (DashMap
/// miss + disk-store hit), so the extra hash is dwarfed by the
/// hardlink/write work that follows.
pub