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
165
166
167
168
169
170
171
172
173
174
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2026-present, Dmitry Prudnikov
//! Bottommost sequence-number zeroing for compaction output.
//!
//! At the last level an entry whose seqno is already below the GC watermark (no
//! live snapshot needs it) can have its seqno set to `0` — "0" packs to a single
//! byte, and sequence numbers grow monotonically, so this saves space on the
//! coldest, largest level.
//!
//! ## Why a range-tombstone gate is required (MVCC / PITR safety)
//!
//! Range tombstones are applied at read time by sequence-number comparison: a
//! tombstone `RT@r` suppresses an entry `K@s` iff it covers `K` and `s < r`. If
//! we zero `K@s` to `K@0`, then **any** covering tombstone with `r > 0` would
//! suppress it — including:
//! - a tombstone older than the entry (`r < s`), which must NOT suppress it; and
//! - a tombstone newer than the entry (`r > s`) but with `r` above the
//! watermark, which must stay visible for snapshots in `[watermark, r)`.
//!
//! So a key is zeroed only when **no range tombstone in the whole version covers
//! it**. Tombstones are gathered from every level (not just this compaction's
//! inputs), so a tombstone in a level that is not part of this compaction still
//! blocks zeroing — the "beyond output level" case.
//!
//! ## Which reads this is allowed to be invisible to
//!
//! For KEY AND VALUE visibility: none above the watermark, which is the whole
//! of the permission. A rewritten entry answers snapshots between `0` and its
//! real seqno that it never answered before, and every entry rewritten here is
//! below the watermark, so the install's floor refuses AT LEAST those snapshots
//! after a reopen. A snapshot at or above the watermark resolves to the same
//! entry as before, since a zeroed seqno still loses to any real one.
//!
//! The seqno ITSELF is not covered by that, and deliberately so. A columnar
//! scan can project `COL_SEQNO`, which is returned in tree-global space, so a
//! scan at any snapshot reports `0` for a rewritten row where it used to report
//! the real seqno. That is the point of the rewrite (one byte instead of a
//! varint on the coldest level) and it is why the column is a physical
//! encoding detail rather than a value the engine promises to preserve. A
//! caller that needs a stable per-row seqno must store one of its own.
//!
//! At least, and usually more: the floor is `(watermark - 1)` capped at the
//! install's own seqno, derived from a boolean that says only THAT something
//! was rewritten. Zeroing one entry at seqno 10 under a watermark of 100 and
//! an install at 50 refuses every snapshot through 50, though only key/value
//! reads through 10 changed. That is the safe direction and the deliberate one;
//! the gate below is what keeps it safe, not the floor's precision.
//!
//! That coupling is why the gate is `seqno < gc_watermark` and not, say,
//! the output level's own bounds: an entry rewritten at or above the watermark
//! would change an answer the recorded floor still promises.
//!
//! Zeroing the bottom version itself is PITR-safe: it only applies to the
//! latest entry below the watermark (no snapshot reads below the watermark), and
//! a newer version (real seqno > 0) always wins the merge over the zeroed one.
//! Older-version ambiguity cannot arise at the last level for the same reason
//! [`CompactionStream::evict_tombstones`](crate::compaction::stream::CompactionStream::evict_tombstones) relies on: the last level is the
//! authoritative bottom.
use crateActiveTombstoneSet;
use crateRangeTombstone;
use crate::;
use Vec;
/// Wraps a sorted compaction output stream and zeroes the seqno of entries that
/// are GC-collapsible (below the watermark) and not covered by any range
/// tombstone. See the module docs for the correctness argument.
pub