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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// SPDX-License-Identifier: MIT OR Apache-2.0
// The `--limit` work budget, included from output.rs.
//
// The budget has two clocks on purpose. LIMIT_SPENT counts what the writer
// emitted, which is what the consumer can read. WORK_SPENT counts side effects
// a verb performs BEFORE it emits the record, so `--limit 1` on a rewrite verb
// rewrites one file instead of rewriting forty and printing one.
// `include!` places every item at the crate root, so `crate::arm_limit` and
// `crate::claim_work` resolve without a re-export.
/// Set once `--limit` made the writer drop a record.
///
/// Scanning verbs poll this to stop the walker at the point where more work
/// could not change the answer. It is process-wide because the writer and the
/// walk run on different threads and share no other state.
static LIMIT_REACHED: AtomicBool = new;
/// True once `--limit` has been reached in this process.
///
/// A verb that scans a tree uses it to quit the walk instead of reading files
/// whose records the writer would discard anyway.
/// Record that `--limit` dropped a record.
///
/// Scanning verbs poll [`limit_reached`] and quit their walk: the records the
/// walker would still produce could not change the answer.
/// Records the run is allowed to produce, as armed by [`arm_limit`].
///
/// `None` means `--limit` was not given (or was given as `0`, which disables it)
/// and the run is unbounded.
static LIMIT_CAP: AtomicU64 = new;
/// Records the run has already produced, as counted by the writer.
static LIMIT_SPENT: AtomicU64 = new;
/// Arm the process-wide work budget from `--limit`.
///
/// Called once, right after the CLI is parsed and before any verb runs. The
/// writer spends the budget as it emits ([`spend_budget`]), and every verb reads
/// what is left through [`remaining_budget`] so collection can be cut BEFORE the
/// side effect instead of after it.
/// The `--limit` cap armed for this process, or `None` when unbounded.
/// Records the budget still allows, or `None` when the run is unbounded.
/// Charge one produced record against the budget and report whether the cap is
/// now full.
///
/// Returns `true` when this record filled the cap, which is the moment a
/// scanning verb must stop: doing one more unit of work could not change the
/// answer the consumer is allowed to read.
/// Work units the run may still claim, counted apart from what the writer emits.
///
/// A verb that rewrites a file before its record is emitted cannot wait for the
/// writer to spend the budget: by then the write already happened. It claims the
/// unit here instead, so `--limit 1` really writes one file even with many walk
/// workers running.
static WORK_SPENT: AtomicU64 = new;
/// Claim one side effect against the `--limit` budget.
///
/// Returns `false` when the budget is already exhausted, in which case the
/// caller must NOT perform the side effect. The claim that fills the cap returns
/// `true` and marks the limit as reached, so the other walk workers quit instead
/// of starting work whose record could never be read.
/// Items the `--limit` budget cut from a collected list in this process.
///
/// `walker_stopped_early` says the run stopped; this says how much of the
/// answer the budget removed, which is the number a consumer needs to know
/// whether the page is the whole tree or a slice of it.
static BUDGET_DROPPED: AtomicU64 = new;
/// Items the `--limit` budget cut from collected lists in this process.
/// Charge one record the writer refused because the budget was already spent.
///
/// A streaming verb hands records to the writer one by one, so its cut happens
/// here and not in [`cap_collected`]. Both are the same `--limit` budget, so
/// both feed the same counter: two counters for one budget would let a summary
/// report only the half of the cut its verb happened to hit.
/// Cut a collected list down to the remaining budget.
///
/// Returns `true` when the list was truncated, and marks the limit as reached so
/// the terminal summary can report `walker_stopped_early`. Verbs that collect
/// everything before acting call this between the collection and the side
/// effect, which is what makes `--limit 1` touch exactly one target. The number
/// of items removed is charged to [`budget_dropped`], so the summary can say how
/// much of the answer the budget cut instead of only that it stopped.