tigerbeetle-node 0.11.12 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/README.md +212 -196
  2. package/dist/bin/aarch64-linux-gnu/client.node +0 -0
  3. package/dist/bin/aarch64-linux-musl/client.node +0 -0
  4. package/dist/bin/aarch64-macos/client.node +0 -0
  5. package/dist/bin/x86_64-linux-gnu/client.node +0 -0
  6. package/dist/bin/x86_64-linux-musl/client.node +0 -0
  7. package/dist/bin/x86_64-macos/client.node +0 -0
  8. package/dist/index.js +33 -1
  9. package/dist/index.js.map +1 -1
  10. package/package-lock.json +66 -0
  11. package/package.json +8 -17
  12. package/src/index.ts +56 -1
  13. package/src/node.zig +10 -9
  14. package/dist/.client.node.sha256 +0 -1
  15. package/scripts/build_lib.sh +0 -61
  16. package/scripts/download_node_headers.sh +0 -32
  17. package/src/tigerbeetle/scripts/benchmark.bat +0 -48
  18. package/src/tigerbeetle/scripts/benchmark.sh +0 -66
  19. package/src/tigerbeetle/scripts/confirm_image.sh +0 -44
  20. package/src/tigerbeetle/scripts/fuzz_loop.sh +0 -15
  21. package/src/tigerbeetle/scripts/fuzz_unique_errors.sh +0 -7
  22. package/src/tigerbeetle/scripts/install.bat +0 -7
  23. package/src/tigerbeetle/scripts/install.sh +0 -21
  24. package/src/tigerbeetle/scripts/install_zig.bat +0 -113
  25. package/src/tigerbeetle/scripts/install_zig.sh +0 -90
  26. package/src/tigerbeetle/scripts/lint.zig +0 -199
  27. package/src/tigerbeetle/scripts/pre-commit.sh +0 -9
  28. package/src/tigerbeetle/scripts/scripts/benchmark.bat +0 -48
  29. package/src/tigerbeetle/scripts/scripts/benchmark.sh +0 -66
  30. package/src/tigerbeetle/scripts/scripts/confirm_image.sh +0 -44
  31. package/src/tigerbeetle/scripts/scripts/fuzz_loop.sh +0 -15
  32. package/src/tigerbeetle/scripts/scripts/fuzz_unique_errors.sh +0 -7
  33. package/src/tigerbeetle/scripts/scripts/install.bat +0 -7
  34. package/src/tigerbeetle/scripts/scripts/install.sh +0 -21
  35. package/src/tigerbeetle/scripts/scripts/install_zig.bat +0 -113
  36. package/src/tigerbeetle/scripts/scripts/install_zig.sh +0 -90
  37. package/src/tigerbeetle/scripts/scripts/lint.zig +0 -199
  38. package/src/tigerbeetle/scripts/scripts/pre-commit.sh +0 -9
  39. package/src/tigerbeetle/scripts/scripts/shellcheck.sh +0 -5
  40. package/src/tigerbeetle/scripts/scripts/tests_on_alpine.sh +0 -10
  41. package/src/tigerbeetle/scripts/scripts/tests_on_ubuntu.sh +0 -14
  42. package/src/tigerbeetle/scripts/scripts/upgrade_ubuntu_kernel.sh +0 -48
  43. package/src/tigerbeetle/scripts/scripts/validate_docs.sh +0 -23
  44. package/src/tigerbeetle/scripts/scripts/vr_state_enumerate +0 -46
  45. package/src/tigerbeetle/scripts/shellcheck.sh +0 -5
  46. package/src/tigerbeetle/scripts/tests_on_alpine.sh +0 -10
  47. package/src/tigerbeetle/scripts/tests_on_ubuntu.sh +0 -14
  48. package/src/tigerbeetle/scripts/upgrade_ubuntu_kernel.sh +0 -48
  49. package/src/tigerbeetle/scripts/validate_docs.sh +0 -23
  50. package/src/tigerbeetle/scripts/vr_state_enumerate +0 -46
  51. package/src/tigerbeetle/src/benchmark.zig +0 -314
  52. package/src/tigerbeetle/src/config.zig +0 -234
  53. package/src/tigerbeetle/src/constants.zig +0 -436
  54. package/src/tigerbeetle/src/ewah.zig +0 -286
  55. package/src/tigerbeetle/src/ewah_benchmark.zig +0 -120
  56. package/src/tigerbeetle/src/ewah_fuzz.zig +0 -130
  57. package/src/tigerbeetle/src/fifo.zig +0 -120
  58. package/src/tigerbeetle/src/io/benchmark.zig +0 -213
  59. package/src/tigerbeetle/src/io/darwin.zig +0 -814
  60. package/src/tigerbeetle/src/io/linux.zig +0 -1062
  61. package/src/tigerbeetle/src/io/test.zig +0 -643
  62. package/src/tigerbeetle/src/io/windows.zig +0 -1183
  63. package/src/tigerbeetle/src/io.zig +0 -34
  64. package/src/tigerbeetle/src/iops.zig +0 -107
  65. package/src/tigerbeetle/src/lsm/README.md +0 -308
  66. package/src/tigerbeetle/src/lsm/binary_search.zig +0 -341
  67. package/src/tigerbeetle/src/lsm/bloom_filter.zig +0 -125
  68. package/src/tigerbeetle/src/lsm/compaction.zig +0 -603
  69. package/src/tigerbeetle/src/lsm/composite_key.zig +0 -77
  70. package/src/tigerbeetle/src/lsm/direction.zig +0 -11
  71. package/src/tigerbeetle/src/lsm/eytzinger.zig +0 -587
  72. package/src/tigerbeetle/src/lsm/eytzinger_benchmark.zig +0 -330
  73. package/src/tigerbeetle/src/lsm/forest.zig +0 -204
  74. package/src/tigerbeetle/src/lsm/forest_fuzz.zig +0 -401
  75. package/src/tigerbeetle/src/lsm/grid.zig +0 -573
  76. package/src/tigerbeetle/src/lsm/groove.zig +0 -972
  77. package/src/tigerbeetle/src/lsm/k_way_merge.zig +0 -474
  78. package/src/tigerbeetle/src/lsm/level_iterator.zig +0 -332
  79. package/src/tigerbeetle/src/lsm/manifest.zig +0 -617
  80. package/src/tigerbeetle/src/lsm/manifest_level.zig +0 -877
  81. package/src/tigerbeetle/src/lsm/manifest_log.zig +0 -789
  82. package/src/tigerbeetle/src/lsm/manifest_log_fuzz.zig +0 -691
  83. package/src/tigerbeetle/src/lsm/merge_iterator.zig +0 -106
  84. package/src/tigerbeetle/src/lsm/node_pool.zig +0 -235
  85. package/src/tigerbeetle/src/lsm/posted_groove.zig +0 -378
  86. package/src/tigerbeetle/src/lsm/segmented_array.zig +0 -1328
  87. package/src/tigerbeetle/src/lsm/segmented_array_benchmark.zig +0 -148
  88. package/src/tigerbeetle/src/lsm/segmented_array_fuzz.zig +0 -9
  89. package/src/tigerbeetle/src/lsm/set_associative_cache.zig +0 -850
  90. package/src/tigerbeetle/src/lsm/table.zig +0 -1031
  91. package/src/tigerbeetle/src/lsm/table_immutable.zig +0 -203
  92. package/src/tigerbeetle/src/lsm/table_iterator.zig +0 -340
  93. package/src/tigerbeetle/src/lsm/table_mutable.zig +0 -220
  94. package/src/tigerbeetle/src/lsm/test.zig +0 -438
  95. package/src/tigerbeetle/src/lsm/tree.zig +0 -1193
  96. package/src/tigerbeetle/src/lsm/tree_fuzz.zig +0 -474
  97. package/src/tigerbeetle/src/message_bus.zig +0 -1012
  98. package/src/tigerbeetle/src/message_pool.zig +0 -156
  99. package/src/tigerbeetle/src/ring_buffer.zig +0 -399
  100. package/src/tigerbeetle/src/simulator.zig +0 -569
  101. package/src/tigerbeetle/src/state_machine/auditor.zig +0 -577
  102. package/src/tigerbeetle/src/state_machine/workload.zig +0 -883
  103. package/src/tigerbeetle/src/state_machine.zig +0 -1881
  104. package/src/tigerbeetle/src/static_allocator.zig +0 -65
  105. package/src/tigerbeetle/src/stdx.zig +0 -162
  106. package/src/tigerbeetle/src/storage.zig +0 -393
  107. package/src/tigerbeetle/src/testing/cluster/message_bus.zig +0 -82
  108. package/src/tigerbeetle/src/testing/cluster/network.zig +0 -237
  109. package/src/tigerbeetle/src/testing/cluster/state_checker.zig +0 -169
  110. package/src/tigerbeetle/src/testing/cluster/storage_checker.zig +0 -202
  111. package/src/tigerbeetle/src/testing/cluster.zig +0 -443
  112. package/src/tigerbeetle/src/testing/fuzz.zig +0 -140
  113. package/src/tigerbeetle/src/testing/hash_log.zig +0 -66
  114. package/src/tigerbeetle/src/testing/id.zig +0 -99
  115. package/src/tigerbeetle/src/testing/packet_simulator.zig +0 -364
  116. package/src/tigerbeetle/src/testing/priority_queue.zig +0 -645
  117. package/src/tigerbeetle/src/testing/reply_sequence.zig +0 -139
  118. package/src/tigerbeetle/src/testing/state_machine.zig +0 -249
  119. package/src/tigerbeetle/src/testing/storage.zig +0 -757
  120. package/src/tigerbeetle/src/testing/table.zig +0 -247
  121. package/src/tigerbeetle/src/testing/time.zig +0 -84
  122. package/src/tigerbeetle/src/tigerbeetle.zig +0 -227
  123. package/src/tigerbeetle/src/time.zig +0 -112
  124. package/src/tigerbeetle/src/tracer.zig +0 -529
  125. package/src/tigerbeetle/src/unit_tests.zig +0 -42
  126. package/src/tigerbeetle/src/vopr.zig +0 -495
  127. package/src/tigerbeetle/src/vsr/README.md +0 -209
  128. package/src/tigerbeetle/src/vsr/client.zig +0 -544
  129. package/src/tigerbeetle/src/vsr/clock.zig +0 -853
  130. package/src/tigerbeetle/src/vsr/journal.zig +0 -2413
  131. package/src/tigerbeetle/src/vsr/journal_format_fuzz.zig +0 -111
  132. package/src/tigerbeetle/src/vsr/marzullo.zig +0 -309
  133. package/src/tigerbeetle/src/vsr/replica.zig +0 -6381
  134. package/src/tigerbeetle/src/vsr/replica_format.zig +0 -219
  135. package/src/tigerbeetle/src/vsr/superblock.zig +0 -1631
  136. package/src/tigerbeetle/src/vsr/superblock_client_table.zig +0 -256
  137. package/src/tigerbeetle/src/vsr/superblock_free_set.zig +0 -929
  138. package/src/tigerbeetle/src/vsr/superblock_free_set_fuzz.zig +0 -334
  139. package/src/tigerbeetle/src/vsr/superblock_fuzz.zig +0 -390
  140. package/src/tigerbeetle/src/vsr/superblock_manifest.zig +0 -615
  141. package/src/tigerbeetle/src/vsr/superblock_quorums.zig +0 -394
  142. package/src/tigerbeetle/src/vsr/superblock_quorums_fuzz.zig +0 -314
  143. package/src/tigerbeetle/src/vsr.zig +0 -1352
@@ -1,390 +0,0 @@
1
- //! Fuzz SuperBlock open()/checkpoint()/view_change().
2
- //!
3
- //! Invariants checked:
4
- //!
5
- //! - Crashing during a checkpoint() or view_change().
6
- //! - open() finds a quorum, even with the interference of disk faults.
7
- //! - open()'s quorum never regresses.
8
- //! - Calling checkpoint() and view_change() concurrently is safe.
9
- //! - VSRState will not leak before the corresponding checkpoint()/view_change().
10
- //! - Trailers will not leak before the corresponding checkpoint().
11
- //! - view_change_in_progress() reports the correct state.
12
- //!
13
- const std = @import("std");
14
- const assert = std.debug.assert;
15
- const log = std.log.scoped(.fuzz_vsr_superblock);
16
-
17
- const constants = @import("../constants.zig");
18
- const stdx = @import("../stdx.zig");
19
- const vsr = @import("../vsr.zig");
20
- const Storage = @import("../testing/storage.zig").Storage;
21
- const StorageFaultAtlas = @import("../testing/storage.zig").ClusterFaultAtlas;
22
- const MessagePool = @import("../message_pool.zig").MessagePool;
23
- const superblock_zone_size = @import("superblock.zig").superblock_zone_size;
24
- const data_file_size_min = @import("superblock.zig").data_file_size_min;
25
- const VSRState = @import("superblock.zig").SuperBlockHeader.VSRState;
26
- const SuperBlockType = @import("superblock.zig").SuperBlockType;
27
- const SuperBlock = SuperBlockType(Storage);
28
- const fuzz = @import("../testing/fuzz.zig");
29
-
30
- pub const tigerbeetle_config = @import("../config.zig").configs.test_min;
31
-
32
- const cluster = 0;
33
-
34
- pub fn main() !void {
35
- const allocator = std.testing.allocator;
36
- const args = try fuzz.parse_fuzz_args(allocator);
37
-
38
- // Total calls to checkpoint() + view_change().
39
- const transitions_count_total = args.events_max orelse 10;
40
-
41
- try run_fuzz(allocator, args.seed, transitions_count_total);
42
- }
43
-
44
- fn run_fuzz(allocator: std.mem.Allocator, seed: u64, transitions_count_total: usize) !void {
45
- var prng = std.rand.DefaultPrng.init(seed);
46
- const random = prng.random();
47
-
48
- const storage_fault_atlas = StorageFaultAtlas.init(1, random, .{
49
- .faulty_superblock = true,
50
- .faulty_wal_headers = false,
51
- .faulty_wal_prepares = false,
52
- });
53
-
54
- const storage_options = .{
55
- .replica_index = 0,
56
- .seed = random.int(u64),
57
- // SuperBlock's IO is all serial, so latencies never reorder reads/writes.
58
- .read_latency_min = 1,
59
- .read_latency_mean = 1,
60
- .write_latency_min = 1,
61
- .write_latency_mean = 1,
62
- // Storage will never inject more faults than the superblock is able to recover from,
63
- // so a 100% fault probability is allowed.
64
- .read_fault_probability = 25 + random.uintLessThan(u8, 76),
65
- .write_fault_probability = 25 + random.uintLessThan(u8, 76),
66
- .crash_fault_probability = 50 + random.uintLessThan(u8, 51),
67
- .fault_atlas = &storage_fault_atlas,
68
- };
69
-
70
- var storage = try Storage.init(allocator, superblock_zone_size, storage_options);
71
- defer storage.deinit(allocator);
72
-
73
- var storage_verify = try Storage.init(allocator, superblock_zone_size, storage_options);
74
- defer storage_verify.deinit(allocator);
75
-
76
- var message_pool = try MessagePool.init(allocator, .replica);
77
- defer message_pool.deinit(allocator);
78
-
79
- var superblock = try SuperBlock.init(allocator, .{
80
- .storage = &storage,
81
- .storage_size_limit = constants.storage_size_max,
82
- .message_pool = &message_pool,
83
- });
84
- defer superblock.deinit(allocator);
85
-
86
- var superblock_verify = try SuperBlock.init(allocator, .{
87
- .storage = &storage_verify,
88
- .storage_size_limit = constants.storage_size_max,
89
- .message_pool = &message_pool,
90
- });
91
- defer superblock_verify.deinit(allocator);
92
-
93
- var sequence_states = Environment.SequenceStates.init(allocator);
94
- defer sequence_states.deinit();
95
-
96
- var env = Environment{
97
- .sequence_states = sequence_states,
98
- .superblock = &superblock,
99
- .superblock_verify = &superblock_verify,
100
- };
101
-
102
- try env.format();
103
- while (env.pending.count() > 0) env.superblock.storage.tick();
104
-
105
- env.open();
106
- while (env.pending.count() > 0) env.superblock.storage.tick();
107
-
108
- try env.verify();
109
- assert(env.pending.count() == 0);
110
- assert(env.latest_sequence == 1);
111
-
112
- var transitions: usize = 0;
113
- while (transitions < transitions_count_total or env.pending.count() > 0) {
114
- if (transitions < transitions_count_total) {
115
- // TODO bias the RNG
116
- if (env.pending.count() == 0) {
117
- transitions += 1;
118
- if (random.boolean()) {
119
- try env.checkpoint();
120
- } else {
121
- try env.view_change();
122
- }
123
- }
124
-
125
- if (env.pending.count() == 1 and random.uintLessThan(u8, 6) == 0) {
126
- transitions += 1;
127
- if (env.pending.contains(.view_change)) {
128
- try env.checkpoint();
129
- } else {
130
- try env.view_change();
131
- }
132
- }
133
- }
134
-
135
- assert(env.pending.count() > 0);
136
- assert(env.pending.count() <= 2);
137
- try env.tick();
138
-
139
- // Trailers are only updated on-disk by checkpoint(), never view_change().
140
- // Trailers must not be mutated while a checkpoint() is in progress.
141
- if (!env.pending.contains(.checkpoint) and random.boolean()) {
142
- const range = env.superblock.free_set.reserve(1).?;
143
- _ = env.superblock.free_set.acquire(range).?;
144
- env.superblock.free_set.forfeit(range);
145
- }
146
- }
147
- }
148
-
149
- const Environment = struct {
150
- /// Track the expected value of parameters at a particular sequence.
151
- /// Indexed by sequence.
152
- const SequenceStates = std.ArrayList(struct {
153
- vsr_state: VSRState,
154
- vsr_headers: vsr.Headers.Array,
155
- /// Track the expected `checksum(free_set)`.
156
- /// Note that this is a checksum of the decoded free set; it is not the same as
157
- /// `SuperBlockHeader.free_set_checksum`.
158
- free_set: u128,
159
- });
160
-
161
- sequence_states: SequenceStates,
162
-
163
- superblock: *SuperBlock,
164
- superblock_verify: *SuperBlock,
165
-
166
- /// Verify that the working superblock after open() never regresses.
167
- latest_sequence: u64 = 0,
168
- latest_checksum: u128 = 0,
169
- latest_parent: u128 = 0,
170
- latest_vsr_state: VSRState = std.mem.zeroes(VSRState),
171
-
172
- context_format: SuperBlock.Context = undefined,
173
- context_open: SuperBlock.Context = undefined,
174
- context_checkpoint: SuperBlock.Context = undefined,
175
- context_view_change: SuperBlock.Context = undefined,
176
- context_verify: SuperBlock.Context = undefined,
177
-
178
- // Set bits indicate pending operations.
179
- pending: std.enums.EnumSet(SuperBlock.Context.Caller) = .{},
180
- pending_verify: bool = false,
181
-
182
- /// After every write to `superblock`'s storage, verify that the superblock can be opened,
183
- /// and the quorum never regresses.
184
- fn tick(env: *Environment) !void {
185
- assert(env.pending.count() <= 2);
186
- assert(env.superblock.storage.reads.len + env.superblock.storage.writes.len <= 1);
187
- assert(!env.pending.contains(.format));
188
- assert(!env.pending.contains(.open));
189
- assert(!env.pending_verify);
190
- assert(env.pending.contains(.view_change) == env.superblock.view_change_in_progress());
191
-
192
- const write = env.superblock.storage.writes.peek();
193
- env.superblock.storage.tick();
194
-
195
- if (write) |w| {
196
- if (w.done_at_tick <= env.superblock.storage.ticks) try env.verify();
197
- }
198
- }
199
-
200
- /// Verify that the superblock will recover safely if the replica crashes immediately after
201
- /// the most recent write.
202
- fn verify(env: *Environment) !void {
203
- assert(!env.pending_verify);
204
-
205
- {
206
- // Reset `superblock_verify` so that it can be reused.
207
- env.superblock_verify.opened = false;
208
- var free_set_iterator = env.superblock_verify.free_set.blocks.iterator(.{});
209
- while (free_set_iterator.next()) |block_bit| {
210
- const block_address = block_bit + 1;
211
- env.superblock_verify.free_set.release(block_address);
212
- }
213
- env.superblock_verify.free_set.checkpoint();
214
- }
215
-
216
- // Duplicate the `superblock`'s storage so it is not modified by `superblock_verify`'s
217
- // repairs. Immediately reset() it to simulate a crash (potentially injecting additional
218
- // faults for pending writes) and clear the read/write queues.
219
- env.superblock_verify.storage.copy(env.superblock.storage);
220
- env.superblock_verify.storage.reset();
221
- env.superblock_verify.open(verify_callback, &env.context_verify);
222
-
223
- env.pending_verify = true;
224
- while (env.pending_verify) env.superblock_verify.storage.tick();
225
-
226
- assert(env.superblock_verify.working.checksum == env.superblock.working.checksum or
227
- env.superblock_verify.working.checksum == env.superblock.staging.checksum);
228
-
229
- // Verify the sequence we read from disk is monotonically increasing.
230
- if (env.latest_sequence < env.superblock_verify.working.sequence) {
231
- assert(env.latest_sequence + 1 == env.superblock_verify.working.sequence);
232
-
233
- if (env.latest_checksum != 0) {
234
- if (env.latest_sequence + 1 == env.superblock_verify.working.sequence) {
235
- // After a checkpoint() or view_change(), the parent points to the previous
236
- // working header.
237
- assert(env.superblock_verify.working.parent == env.latest_checksum);
238
- }
239
- }
240
-
241
- assert(env.latest_vsr_state.monotonic(env.superblock_verify.working.vsr_state));
242
-
243
- const expect = env.sequence_states.items[env.superblock_verify.working.sequence];
244
- assert(std.meta.eql(expect.vsr_state, env.superblock_verify.working.vsr_state));
245
- assert(expect.free_set == checksum_free_set(env.superblock_verify));
246
-
247
- env.latest_sequence = env.superblock_verify.working.sequence;
248
- env.latest_checksum = env.superblock_verify.working.checksum;
249
- env.latest_parent = env.superblock_verify.working.parent;
250
- env.latest_vsr_state = env.superblock_verify.working.vsr_state;
251
- } else {
252
- assert(env.latest_sequence == env.superblock_verify.working.sequence);
253
- assert(env.latest_checksum == env.superblock_verify.working.checksum);
254
- assert(env.latest_parent == env.superblock_verify.working.parent);
255
- }
256
- }
257
-
258
- fn verify_callback(context: *SuperBlock.Context) void {
259
- const env = @fieldParentPtr(Environment, "context_verify", context);
260
- assert(env.pending_verify);
261
- env.pending_verify = false;
262
- }
263
-
264
- fn format(env: *Environment) !void {
265
- assert(env.pending.count() == 0);
266
- env.pending.insert(.format);
267
- env.superblock.format(format_callback, &env.context_format, .{
268
- .cluster = cluster,
269
- .replica = 0,
270
- });
271
-
272
- var vsr_headers = vsr.Headers.Array{ .buffer = undefined };
273
- vsr_headers.appendAssumeCapacity(vsr.Header.root_prepare(cluster));
274
-
275
- assert(env.sequence_states.items.len == 0);
276
- try env.sequence_states.append(undefined); // skip sequence=0
277
- try env.sequence_states.append(.{
278
- .vsr_state = VSRState.root(cluster),
279
- .vsr_headers = vsr_headers,
280
- .free_set = checksum_free_set(env.superblock),
281
- });
282
- }
283
-
284
- fn format_callback(context: *SuperBlock.Context) void {
285
- const env = @fieldParentPtr(Environment, "context_format", context);
286
- assert(env.pending.contains(.format));
287
- env.pending.remove(.format);
288
- }
289
-
290
- fn open(env: *Environment) void {
291
- assert(env.pending.count() == 0);
292
- env.pending.insert(.open);
293
- env.superblock.open(open_callback, &env.context_open);
294
- }
295
-
296
- fn open_callback(context: *SuperBlock.Context) void {
297
- const env = @fieldParentPtr(Environment, "context_open", context);
298
- assert(env.pending.contains(.open));
299
- env.pending.remove(.open);
300
-
301
- assert(env.superblock.working.sequence == 1);
302
- assert(env.superblock.working.replica == 0);
303
- assert(env.superblock.working.cluster == cluster);
304
- }
305
-
306
- fn view_change(env: *Environment) !void {
307
- assert(!env.pending.contains(.view_change));
308
- assert(env.pending.count() < 2);
309
-
310
- const vsr_state = .{
311
- .commit_min_checksum = env.superblock.staging.vsr_state.commit_min_checksum,
312
- .commit_min = env.superblock.staging.vsr_state.commit_min,
313
- .commit_max = env.superblock.staging.vsr_state.commit_max + 3,
314
- .log_view = env.superblock.staging.vsr_state.log_view + 4,
315
- .view = env.superblock.staging.vsr_state.view + 5,
316
- };
317
-
318
- var vsr_headers = vsr.Headers.Array{ .buffer = undefined };
319
- var vsr_head = std.mem.zeroInit(vsr.Header, .{
320
- .command = .prepare,
321
- .op = env.superblock.staging.vsr_state.commit_min,
322
- });
323
- vsr_head.set_checksum_body(&.{});
324
- vsr_head.set_checksum();
325
- vsr_headers.appendAssumeCapacity(vsr_head);
326
-
327
- assert(env.sequence_states.items.len == env.superblock.staging.sequence + 1);
328
- try env.sequence_states.append(.{
329
- .vsr_state = vsr_state,
330
- .vsr_headers = vsr_headers,
331
- .free_set = env.sequence_states.items[env.sequence_states.items.len - 1].free_set,
332
- });
333
-
334
- env.pending.insert(.view_change);
335
- env.superblock.view_change(view_change_callback, &env.context_view_change, .{
336
- .commit_max = vsr_state.commit_max,
337
- .log_view = vsr_state.log_view,
338
- .view = vsr_state.view,
339
- .headers = &.{ .array = vsr_headers },
340
- });
341
- }
342
-
343
- fn view_change_callback(context: *SuperBlock.Context) void {
344
- const env = @fieldParentPtr(Environment, "context_view_change", context);
345
- assert(env.pending.contains(.view_change));
346
- env.pending.remove(.view_change);
347
- }
348
-
349
- fn checkpoint(env: *Environment) !void {
350
- assert(!env.pending.contains(.checkpoint));
351
- assert(env.pending.count() < 2);
352
-
353
- const vsr_state = .{
354
- .commit_min_checksum = env.superblock.staging.vsr_state.commit_min_checksum + 1,
355
- .commit_min = env.superblock.staging.vsr_state.commit_min + 1,
356
- .commit_max = env.superblock.staging.vsr_state.commit_max + 1,
357
- .log_view = env.superblock.staging.vsr_state.log_view,
358
- .view = env.superblock.staging.vsr_state.view,
359
- };
360
-
361
- assert(env.sequence_states.items.len == env.superblock.staging.sequence + 1);
362
- try env.sequence_states.append(.{
363
- .vsr_state = vsr_state,
364
- .vsr_headers = vsr.Headers.Array.fromSlice(
365
- env.superblock.staging.vsr_headers().slice,
366
- ) catch unreachable,
367
- .free_set = checksum_free_set(env.superblock),
368
- });
369
-
370
- env.pending.insert(.checkpoint);
371
- env.superblock.checkpoint(checkpoint_callback, &env.context_checkpoint, .{
372
- .commit_min_checksum = vsr_state.commit_min_checksum,
373
- .commit_min = vsr_state.commit_min,
374
- .commit_max = vsr_state.commit_max,
375
- });
376
- }
377
-
378
- fn checkpoint_callback(context: *SuperBlock.Context) void {
379
- const env = @fieldParentPtr(Environment, "context_checkpoint", context);
380
- assert(env.pending.contains(.checkpoint));
381
- env.pending.remove(.checkpoint);
382
- }
383
- };
384
-
385
- fn checksum_free_set(superblock: *const SuperBlock) u128 {
386
- const mask_bits = @bitSizeOf(std.DynamicBitSetUnmanaged.MaskInt);
387
- const count_bits = superblock.free_set.blocks.bit_length;
388
- const count_words = stdx.div_ceil(count_bits, mask_bits);
389
- return vsr.checksum(std.mem.sliceAsBytes(superblock.free_set.blocks.masks[0..count_words]));
390
- }