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
//! Binary snapshot wire format: magic/version/opcode constants plus the
//! little-endian read/write primitives shared by the writer
//! (`crate::snapshot_write`) and the loader (`crate::snapshot_read`).
//! Split out of `lib.rs` to keep it under the 500-LOC house cap.
use ;
/// File magic + format version. Bump `VERSION` on any layout change.
///
/// Format v2 stored each entry's TTL as **remaining millis** (relative), so a
/// load re-anchored the deadline to load-time — a restart reset every key to a
/// fresh full TTL (a production incident class). v3 stores the **absolute** Unix-ms
/// deadline, so a load reconstructs the original instant. v4 appends a
/// consumer-group section to each `OP_STREAM` payload (groups + consumers
/// plus PEL) — before that, SAVE/reshard silently dropped group state. The
/// loader still accepts v2 (relative TTL) and v3 (no group section).
pub const MAGIC: & = b"KEVYSNAP";
pub const VERSION: u8 = 4;
/// Format version 5 carries a 16-byte feed cursor (`gen u64 LE` +
/// `offset u64 LE`) right after the version byte — the snapshot half
/// of the recovery-point contract (docs/cdc.md): snapshot S + feed
/// frames from S's cursor = exact restore. Writers emit v5 only when
/// a cursor is supplied; cursor-less writes stay at v4 so every
/// existing path is byte-identical.
pub const VERSION_FEED_CURSOR: u8 = 5;
/// Format version 6 additionally carries `OP_HFTTL` hash field-TTL
/// records after the entry stream. Written only when field TTLs
/// exist; the header still carries the (possibly zero) feed cursor.
pub const VERSION_HASH_TTL: u8 = 6;
/// Format version 7 additionally allows `OP_SEGSTUB` records: a
/// row-segment stub (`[seq u32][value_weight u32]`) whose data lives
/// in the segment directory beside the snapshot. Written only when
/// row segments exist; windowless stores stay at their prior version
/// byte-identically.
pub const VERSION_SEG_STUB: u8 = 7;
pub const VERSION_RELATIVE_TTL: u8 = 2;
pub const VERSION_ABSOLUTE_TTL: u8 = 3;
// Record opcodes (one per value type). Each record is:
// [op][ttl: u8 flag + optional u64][key][type payload]
pub const OP_EOF: u8 = 0;
pub const OP_STR: u8 = 1;
pub const OP_HASH: u8 = 2;
pub const OP_LIST: u8 = 3;
pub const OP_SET: u8 = 4;
pub const OP_ZSET: u8 = 5;
pub const OP_STREAM: u8 = 6;
/// Hash field TTL record: `[key][field][deadline_ms: u64 LE]`.
/// Appears only in format v6+ snapshots, after the entry stream's
/// records (before OP_EOF).
pub const OP_HFTTL: u8 = 7;
/// Row-segment stub record: `[key][seq u32 LE][value_weight u32 LE]`.
/// v7+ only.
pub const OP_SEGSTUB: u8 = 8;
/// BufWriter capacity for bulk snapshot / AOF-rewrite writes. The 8 KiB
/// default made SAVE ~12 % of disk bandwidth (tens of thousands of small
/// `write(2)`s); 1 MiB amortizes the syscalls toward disk speed.
pub const SNAPSHOT_BUF_CAP: usize = 1 << 20;
pub
pub
pub
/// Cap on how much a single untrusted length/count field may cause
/// the loader to reserve BEFORE the bytes behind it actually arrive.
/// A corrupt or hostile snapshot can declare up to `u32::MAX` for any
/// length; reserving that eagerly (`vec![0; len]` / `with_capacity`)
/// is a remote alloc-abort. We reserve at most this and grow as real
/// bytes land, so a lie costs one step, not gigabytes. Applies to
/// both byte lengths and element counts (see [`capped_capacity`]).
pub const SNAP_RESERVE_CAP: usize = 64 * 1024;
/// Initial reservation for an untrusted element count — clamped so a
/// forged count can't drive an unbounded `with_capacity`. The vec
/// still grows to the true count as elements are pushed; each push is
/// preceded by a read that fails cleanly (`io::Error`) once the
/// stream is exhausted, so a lie is caught within one step.
pub
pub
pub
pub
pub