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
175
176
177
178
179
180
// SPDX-License-Identifier: BUSL-1.1
//! Per-engine "already durable through LSN X" floors recovered from on-disk
//! checkpoints at boot, consulted by WAL replay so a restored checkpoint is not
//! re-derived from records it already contains.
//!
//! ## Why replaying ABOVE the floor is safe
//!
//! Every KV WAL record replays either as an absolute overwrite (`kv_put`,
//! `kv_batch_put`, `kv_delete`, `kv_truncate`) or as a delta re-executed against
//! the engine's current state (`kv_incr`, `kv_cas`, `kv_field_set`,
//! `kv_transfer`, ...). Restoring a checkpoint durable through LSN F reproduces
//! exactly the engine state that existed after record F was applied, so feeding
//! the records above F back through the same replay paths — in LSN order, on top
//! of that state — reaches the state a full from-zero replay would.
//!
//! It is records at or below F that MUST be skipped. For the absolute-overwrite
//! records re-applying is merely redundant, but for the delta records it is
//! corruption: an increment already folded into the checkpoint would be counted
//! twice.
//!
//! ## Why a floor is engine-wide rather than per-collection
//!
//! A KV record can span two collections (`kv_transfer_item` moves a row between
//! them). With per-collection floors those two collections could disagree —
//! source covered, destination not — and the record is then unrepresentable:
//! skipping it drops the destination's insert, applying it double-debits the
//! source. Publishing every collection's file under one generation, named by a
//! single manifest, makes disagreement unreachable by construction: all live
//! collections advance to one LSN together or none do.
//!
//! ## Adding an engine
//!
//! Add a field to [`ReplayFloors`], populate it from that engine's
//! `load_*_checkpoints` boot path, and consult it from that engine's replay
//! arms. Nothing here needs reshaping — engines do not share a floor.
//!
//! ## Which engines need one
//!
//! Only those whose WAL records are DELTAS against current state. A floor is not
//! a general "I restored a checkpoint" marker, and adding one where replay is
//! already idempotent gates records for no reason.
//!
//! Four checkpointed engines deliberately have no field here:
//!
//! * Sparse vector — `SparseVectorPut` is an upsert keyed by `doc_id` and
//! `SparseVectorDelete` is a no-op against an absent document, so a record
//! re-applied over the restored index reproduces it.
//! * The sync idempotency gate — `SyncSeqAdvance` advances both its maps by
//! max-wins, so re-folding a record already contained in the restored state
//! cannot change it. What that restore needs instead is for replay to MERGE
//! into it rather than replace it; see `install_sync_hwm_maps`.
//! * Graph node labels — `GraphNodeLabelSet` ORs a bit on and
//! `GraphNodeLabelRemove` ANDs it off, both keyed by `(node, label)` NAME, so
//! a record re-applied over the restored bitset lands on the same bit. The
//! names are why: the restore keys by name rather than by local node id
//! precisely because ids are not stable across restarts, and replay uses the
//! same `add_node_label` / `remove_node_label` entry points as the live
//! handler.
//! * The array engine — `ArrayPut` / `ArrayDelete` replay through
//! `put_cells` / `delete_cells`, which write into a map keyed by the encoded
//! coordinate inside the tile version named by the record's OWN
//! `system_from_ms` (never the local clock — `recovery.rs` states this as an
//! invariant). A record whose cell is already in a restored segment therefore
//! writes the identical version back rather than appending a second one.
use crateLsn;
/// Checkpoint-restored replay floors for every engine on one core.
///
/// Lives on `CoreLoop` rather than being threaded through `replay_all_wal` as a
/// parameter because it is restored core state, exactly like the watermark: the
/// `load_*_checkpoints` boot methods produce it and every replay path reads it
/// through `&self`. Default (all-unset) means "no checkpoint restored", which
/// gates nothing and replays the full WAL — the safe direction.
pub
/// The LSN an engine's restored checkpoint is durable through.
///
/// `None` means no checkpoint was restored, so nothing is gated and the full WAL
/// replays. Shared by every engine in [`ReplayFloors`]: the gating rule (an
/// inclusive `record_lsn <= durable_through` check) is identical across
/// engines — what differs between them is WHY they need one at all, which is
/// documented on each field above rather than on this type.
pub