tigerbeetle-node 0.11.13 → 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 (146) hide show
  1. package/dist/bin/aarch64-linux-gnu/client.node +0 -0
  2. package/dist/bin/aarch64-linux-musl/client.node +0 -0
  3. package/dist/bin/aarch64-macos/client.node +0 -0
  4. package/dist/bin/x86_64-linux-gnu/client.node +0 -0
  5. package/dist/bin/x86_64-linux-musl/client.node +0 -0
  6. package/dist/bin/x86_64-macos/client.node +0 -0
  7. package/dist/index.js +33 -1
  8. package/dist/index.js.map +1 -1
  9. package/package-lock.json +66 -0
  10. package/package.json +6 -16
  11. package/src/index.ts +56 -1
  12. package/src/node.zig +9 -9
  13. package/dist/.client.node.sha256 +0 -1
  14. package/scripts/build_lib.sh +0 -61
  15. package/scripts/download_node_headers.sh +0 -32
  16. package/src/tigerbeetle/scripts/benchmark.bat +0 -55
  17. package/src/tigerbeetle/scripts/benchmark.sh +0 -66
  18. package/src/tigerbeetle/scripts/confirm_image.sh +0 -44
  19. package/src/tigerbeetle/scripts/fail_on_diff.sh +0 -9
  20. package/src/tigerbeetle/scripts/fuzz_loop.sh +0 -15
  21. package/src/tigerbeetle/scripts/fuzz_loop_hash_log.sh +0 -12
  22. package/src/tigerbeetle/scripts/fuzz_unique_errors.sh +0 -7
  23. package/src/tigerbeetle/scripts/install.bat +0 -7
  24. package/src/tigerbeetle/scripts/install.sh +0 -21
  25. package/src/tigerbeetle/scripts/install_zig.bat +0 -113
  26. package/src/tigerbeetle/scripts/install_zig.sh +0 -90
  27. package/src/tigerbeetle/scripts/lint.zig +0 -199
  28. package/src/tigerbeetle/scripts/pre-commit.sh +0 -9
  29. package/src/tigerbeetle/scripts/scripts/benchmark.bat +0 -55
  30. package/src/tigerbeetle/scripts/scripts/benchmark.sh +0 -66
  31. package/src/tigerbeetle/scripts/scripts/confirm_image.sh +0 -44
  32. package/src/tigerbeetle/scripts/scripts/fail_on_diff.sh +0 -9
  33. package/src/tigerbeetle/scripts/scripts/fuzz_loop.sh +0 -15
  34. package/src/tigerbeetle/scripts/scripts/fuzz_loop_hash_log.sh +0 -12
  35. package/src/tigerbeetle/scripts/scripts/fuzz_unique_errors.sh +0 -7
  36. package/src/tigerbeetle/scripts/scripts/install.bat +0 -7
  37. package/src/tigerbeetle/scripts/scripts/install.sh +0 -21
  38. package/src/tigerbeetle/scripts/scripts/install_zig.bat +0 -113
  39. package/src/tigerbeetle/scripts/scripts/install_zig.sh +0 -90
  40. package/src/tigerbeetle/scripts/scripts/lint.zig +0 -199
  41. package/src/tigerbeetle/scripts/scripts/pre-commit.sh +0 -9
  42. package/src/tigerbeetle/scripts/scripts/shellcheck.sh +0 -5
  43. package/src/tigerbeetle/scripts/scripts/tests_on_alpine.sh +0 -10
  44. package/src/tigerbeetle/scripts/scripts/tests_on_ubuntu.sh +0 -14
  45. package/src/tigerbeetle/scripts/scripts/upgrade_ubuntu_kernel.sh +0 -48
  46. package/src/tigerbeetle/scripts/scripts/validate_docs.sh +0 -23
  47. package/src/tigerbeetle/scripts/scripts/vr_state_enumerate +0 -46
  48. package/src/tigerbeetle/scripts/shellcheck.sh +0 -5
  49. package/src/tigerbeetle/scripts/tests_on_alpine.sh +0 -10
  50. package/src/tigerbeetle/scripts/tests_on_ubuntu.sh +0 -14
  51. package/src/tigerbeetle/scripts/upgrade_ubuntu_kernel.sh +0 -48
  52. package/src/tigerbeetle/scripts/validate_docs.sh +0 -23
  53. package/src/tigerbeetle/scripts/vr_state_enumerate +0 -46
  54. package/src/tigerbeetle/src/benchmark.zig +0 -336
  55. package/src/tigerbeetle/src/config.zig +0 -233
  56. package/src/tigerbeetle/src/constants.zig +0 -428
  57. package/src/tigerbeetle/src/ewah.zig +0 -286
  58. package/src/tigerbeetle/src/ewah_benchmark.zig +0 -120
  59. package/src/tigerbeetle/src/ewah_fuzz.zig +0 -130
  60. package/src/tigerbeetle/src/fifo.zig +0 -120
  61. package/src/tigerbeetle/src/io/benchmark.zig +0 -213
  62. package/src/tigerbeetle/src/io/darwin.zig +0 -814
  63. package/src/tigerbeetle/src/io/linux.zig +0 -1071
  64. package/src/tigerbeetle/src/io/test.zig +0 -643
  65. package/src/tigerbeetle/src/io/windows.zig +0 -1183
  66. package/src/tigerbeetle/src/io.zig +0 -34
  67. package/src/tigerbeetle/src/iops.zig +0 -107
  68. package/src/tigerbeetle/src/lsm/README.md +0 -308
  69. package/src/tigerbeetle/src/lsm/binary_search.zig +0 -341
  70. package/src/tigerbeetle/src/lsm/bloom_filter.zig +0 -125
  71. package/src/tigerbeetle/src/lsm/compaction.zig +0 -603
  72. package/src/tigerbeetle/src/lsm/composite_key.zig +0 -77
  73. package/src/tigerbeetle/src/lsm/direction.zig +0 -11
  74. package/src/tigerbeetle/src/lsm/eytzinger.zig +0 -587
  75. package/src/tigerbeetle/src/lsm/eytzinger_benchmark.zig +0 -330
  76. package/src/tigerbeetle/src/lsm/forest.zig +0 -205
  77. package/src/tigerbeetle/src/lsm/forest_fuzz.zig +0 -450
  78. package/src/tigerbeetle/src/lsm/grid.zig +0 -573
  79. package/src/tigerbeetle/src/lsm/groove.zig +0 -1036
  80. package/src/tigerbeetle/src/lsm/k_way_merge.zig +0 -474
  81. package/src/tigerbeetle/src/lsm/level_iterator.zig +0 -332
  82. package/src/tigerbeetle/src/lsm/manifest.zig +0 -617
  83. package/src/tigerbeetle/src/lsm/manifest_level.zig +0 -878
  84. package/src/tigerbeetle/src/lsm/manifest_log.zig +0 -789
  85. package/src/tigerbeetle/src/lsm/manifest_log_fuzz.zig +0 -691
  86. package/src/tigerbeetle/src/lsm/merge_iterator.zig +0 -106
  87. package/src/tigerbeetle/src/lsm/node_pool.zig +0 -235
  88. package/src/tigerbeetle/src/lsm/posted_groove.zig +0 -381
  89. package/src/tigerbeetle/src/lsm/segmented_array.zig +0 -1329
  90. package/src/tigerbeetle/src/lsm/segmented_array_benchmark.zig +0 -148
  91. package/src/tigerbeetle/src/lsm/segmented_array_fuzz.zig +0 -9
  92. package/src/tigerbeetle/src/lsm/set_associative_cache.zig +0 -850
  93. package/src/tigerbeetle/src/lsm/table.zig +0 -1009
  94. package/src/tigerbeetle/src/lsm/table_immutable.zig +0 -192
  95. package/src/tigerbeetle/src/lsm/table_iterator.zig +0 -340
  96. package/src/tigerbeetle/src/lsm/table_mutable.zig +0 -203
  97. package/src/tigerbeetle/src/lsm/test.zig +0 -439
  98. package/src/tigerbeetle/src/lsm/tree.zig +0 -1169
  99. package/src/tigerbeetle/src/lsm/tree_fuzz.zig +0 -479
  100. package/src/tigerbeetle/src/message_bus.zig +0 -1013
  101. package/src/tigerbeetle/src/message_pool.zig +0 -156
  102. package/src/tigerbeetle/src/ring_buffer.zig +0 -399
  103. package/src/tigerbeetle/src/simulator.zig +0 -580
  104. package/src/tigerbeetle/src/state_machine/auditor.zig +0 -578
  105. package/src/tigerbeetle/src/state_machine/workload.zig +0 -883
  106. package/src/tigerbeetle/src/state_machine.zig +0 -2099
  107. package/src/tigerbeetle/src/static_allocator.zig +0 -65
  108. package/src/tigerbeetle/src/stdx.zig +0 -171
  109. package/src/tigerbeetle/src/storage.zig +0 -393
  110. package/src/tigerbeetle/src/testing/cluster/message_bus.zig +0 -82
  111. package/src/tigerbeetle/src/testing/cluster/network.zig +0 -237
  112. package/src/tigerbeetle/src/testing/cluster/state_checker.zig +0 -169
  113. package/src/tigerbeetle/src/testing/cluster/storage_checker.zig +0 -202
  114. package/src/tigerbeetle/src/testing/cluster.zig +0 -444
  115. package/src/tigerbeetle/src/testing/fuzz.zig +0 -140
  116. package/src/tigerbeetle/src/testing/hash_log.zig +0 -66
  117. package/src/tigerbeetle/src/testing/id.zig +0 -99
  118. package/src/tigerbeetle/src/testing/packet_simulator.zig +0 -374
  119. package/src/tigerbeetle/src/testing/priority_queue.zig +0 -645
  120. package/src/tigerbeetle/src/testing/reply_sequence.zig +0 -139
  121. package/src/tigerbeetle/src/testing/state_machine.zig +0 -250
  122. package/src/tigerbeetle/src/testing/storage.zig +0 -757
  123. package/src/tigerbeetle/src/testing/table.zig +0 -247
  124. package/src/tigerbeetle/src/testing/time.zig +0 -84
  125. package/src/tigerbeetle/src/tigerbeetle.zig +0 -227
  126. package/src/tigerbeetle/src/time.zig +0 -112
  127. package/src/tigerbeetle/src/tracer.zig +0 -529
  128. package/src/tigerbeetle/src/unit_tests.zig +0 -40
  129. package/src/tigerbeetle/src/vopr.zig +0 -495
  130. package/src/tigerbeetle/src/vsr/README.md +0 -209
  131. package/src/tigerbeetle/src/vsr/client.zig +0 -544
  132. package/src/tigerbeetle/src/vsr/clock.zig +0 -855
  133. package/src/tigerbeetle/src/vsr/journal.zig +0 -2415
  134. package/src/tigerbeetle/src/vsr/journal_format_fuzz.zig +0 -111
  135. package/src/tigerbeetle/src/vsr/marzullo.zig +0 -309
  136. package/src/tigerbeetle/src/vsr/replica.zig +0 -6616
  137. package/src/tigerbeetle/src/vsr/replica_format.zig +0 -219
  138. package/src/tigerbeetle/src/vsr/superblock.zig +0 -1631
  139. package/src/tigerbeetle/src/vsr/superblock_client_table.zig +0 -256
  140. package/src/tigerbeetle/src/vsr/superblock_free_set.zig +0 -929
  141. package/src/tigerbeetle/src/vsr/superblock_free_set_fuzz.zig +0 -334
  142. package/src/tigerbeetle/src/vsr/superblock_fuzz.zig +0 -390
  143. package/src/tigerbeetle/src/vsr/superblock_manifest.zig +0 -615
  144. package/src/tigerbeetle/src/vsr/superblock_quorums.zig +0 -394
  145. package/src/tigerbeetle/src/vsr/superblock_quorums_fuzz.zig +0 -314
  146. package/src/tigerbeetle/src/vsr.zig +0 -1425
@@ -1,479 +0,0 @@
1
- const std = @import("std");
2
- const testing = std.testing;
3
- const allocator = testing.allocator;
4
- const assert = std.debug.assert;
5
-
6
- const constants = @import("../constants.zig");
7
- const fuzz = @import("../testing/fuzz.zig");
8
- const vsr = @import("../vsr.zig");
9
-
10
- const log = std.log.scoped(.lsm_tree_fuzz);
11
- const tracer = @import("../tracer.zig");
12
-
13
- const MessagePool = @import("../message_pool.zig").MessagePool;
14
- const Transfer = @import("../tigerbeetle.zig").Transfer;
15
- const Account = @import("../tigerbeetle.zig").Account;
16
- const Storage = @import("../testing/storage.zig").Storage;
17
- const StateMachine = @import("../state_machine.zig").StateMachineType(Storage, .{
18
- .message_body_size_max = constants.message_body_size_max,
19
- .lsm_batch_multiple = constants.lsm_batch_multiple,
20
- });
21
-
22
- const GridType = @import("grid.zig").GridType;
23
- const NodePool = @import("node_pool.zig").NodePool(constants.lsm_manifest_node_size, 16);
24
- const TableUsage = @import("table.zig").TableUsage;
25
- const TableType = @import("table.zig").TableType;
26
-
27
- const Grid = GridType(Storage);
28
- const SuperBlock = vsr.SuperBlockType(Storage);
29
-
30
- pub const tigerbeetle_config = @import("../config.zig").configs.test_min;
31
-
32
- const Key = packed struct {
33
- id: u64 align(@alignOf(u64)),
34
-
35
- const Value = packed struct {
36
- id: u64,
37
- value: u63,
38
- tombstone: u1 = 0,
39
- };
40
-
41
- inline fn compare_keys(a: Key, b: Key) std.math.Order {
42
- return std.math.order(a.id, b.id);
43
- }
44
-
45
- inline fn key_from_value(value: *const Key.Value) Key {
46
- return Key{ .id = value.id };
47
- }
48
-
49
- const sentinel_key = Key{
50
- .id = std.math.maxInt(u64),
51
- };
52
-
53
- inline fn tombstone(value: *const Key.Value) bool {
54
- return value.tombstone != 0;
55
- }
56
-
57
- inline fn tombstone_from_key(key: Key) Key.Value {
58
- return Key.Value{
59
- .id = key.id,
60
- .value = 0,
61
- .tombstone = 1,
62
- };
63
- }
64
- };
65
-
66
- const FuzzOpTag = std.meta.Tag(FuzzOp);
67
- const FuzzOp = union(enum) {
68
- // TODO Test range queries.
69
- compact: struct {
70
- op: u64,
71
- checkpoint: bool,
72
- },
73
- put: Key.Value,
74
- remove: Key.Value,
75
- get: Key,
76
- };
77
-
78
- const batch_size_max = constants.message_size_max - @sizeOf(vsr.Header);
79
- const commit_entries_max = @divFloor(batch_size_max, @sizeOf(Key.Value));
80
- const value_count_max = constants.lsm_batch_multiple * commit_entries_max;
81
-
82
- const cluster = 32;
83
- const replica = 4;
84
- const node_count = 1024;
85
- const tree_options = .{
86
- // This is the smallest size that set_associative_cache will allow us.
87
- .cache_entries_max = 2048,
88
- };
89
-
90
- // We must call compact after every 'batch'.
91
- // Every `lsm_batch_multiple` batches may put/remove `value_count_max` values.
92
- // Every `FuzzOp.put` issues one remove and one put.
93
- const puts_since_compact_max = @divTrunc(commit_entries_max, 2);
94
- const compacts_per_checkpoint = std.math.divCeil(
95
- usize,
96
- constants.journal_slot_count,
97
- constants.lsm_batch_multiple,
98
- ) catch unreachable;
99
-
100
- fn EnvironmentType(comptime table_usage: TableUsage) type {
101
- return struct {
102
- const Environment = @This();
103
-
104
- const Tree = @import("tree.zig").TreeType(Table, Storage, "Key.Value");
105
- const Table = TableType(
106
- Key,
107
- Key.Value,
108
- Key.compare_keys,
109
- Key.key_from_value,
110
- Key.sentinel_key,
111
- Key.tombstone,
112
- Key.tombstone_from_key,
113
- value_count_max,
114
- table_usage,
115
- );
116
-
117
- const State = enum {
118
- init,
119
- superblock_format,
120
- superblock_open,
121
- tree_init,
122
- tree_open,
123
- fuzzing,
124
- tree_compact,
125
- tree_checkpoint,
126
- superblock_checkpoint,
127
- tree_lookup,
128
- };
129
-
130
- state: State,
131
- storage: *Storage,
132
- message_pool: MessagePool,
133
- superblock: SuperBlock,
134
- superblock_context: SuperBlock.Context,
135
- grid: Grid,
136
- node_pool: NodePool,
137
- tree: Tree,
138
- lookup_context: Tree.LookupContext,
139
- lookup_value: ?*const Key.Value,
140
- checkpoint_op: ?u64,
141
-
142
- pub fn run(storage: *Storage, fuzz_ops: []const FuzzOp) !void {
143
- var env: Environment = undefined;
144
- env.state = .init;
145
- env.storage = storage;
146
-
147
- env.message_pool = try MessagePool.init(allocator, .replica);
148
- defer env.message_pool.deinit(allocator);
149
-
150
- env.superblock = try SuperBlock.init(allocator, .{
151
- .storage = env.storage,
152
- .storage_size_limit = constants.storage_size_max,
153
- .message_pool = &env.message_pool,
154
- });
155
- defer env.superblock.deinit(allocator);
156
-
157
- env.grid = try Grid.init(allocator, &env.superblock);
158
- defer env.grid.deinit(allocator);
159
-
160
- env.node_pool = try NodePool.init(allocator, node_count);
161
- defer env.node_pool.deinit(allocator);
162
-
163
- env.tree = undefined;
164
- env.lookup_value = null;
165
- env.checkpoint_op = null;
166
-
167
- try env.open_then_apply(fuzz_ops);
168
- }
169
-
170
- fn change_state(env: *Environment, current_state: State, next_state: State) void {
171
- assert(env.state == current_state);
172
- env.state = next_state;
173
- }
174
-
175
- fn tick_until_state_change(env: *Environment, current_state: State, next_state: State) void {
176
- // Sometimes operations complete synchronously so we might already be in next_state before ticking.
177
- //assert(env.state == current_state or env.state == next_state);
178
- while (env.state == current_state) env.storage.tick();
179
- assert(env.state == next_state);
180
- }
181
-
182
- pub fn open_then_apply(env: *Environment, fuzz_ops: []const FuzzOp) !void {
183
- env.change_state(.init, .superblock_format);
184
- env.superblock.format(superblock_format_callback, &env.superblock_context, .{
185
- .cluster = cluster,
186
- .replica = replica,
187
- });
188
-
189
- env.tick_until_state_change(.superblock_format, .superblock_open);
190
- env.superblock.open(superblock_open_callback, &env.superblock_context);
191
-
192
- env.tick_until_state_change(.superblock_open, .tree_init);
193
- env.tree = try Tree.init(allocator, &env.node_pool, &env.grid, tree_options);
194
- defer env.tree.deinit(allocator);
195
-
196
- env.change_state(.tree_init, .tree_open);
197
- env.tree.open(tree_open_callback);
198
-
199
- env.tick_until_state_change(.tree_open, .fuzzing);
200
- try env.apply(fuzz_ops);
201
- }
202
-
203
- fn superblock_format_callback(superblock_context: *SuperBlock.Context) void {
204
- const env = @fieldParentPtr(@This(), "superblock_context", superblock_context);
205
- env.change_state(.superblock_format, .superblock_open);
206
- }
207
-
208
- fn superblock_open_callback(superblock_context: *SuperBlock.Context) void {
209
- const env = @fieldParentPtr(@This(), "superblock_context", superblock_context);
210
- env.change_state(.superblock_open, .tree_init);
211
- }
212
-
213
- fn tree_open_callback(tree: *Tree) void {
214
- const env = @fieldParentPtr(@This(), "tree", tree);
215
- env.change_state(.tree_open, .fuzzing);
216
- }
217
-
218
- pub fn compact(env: *Environment, op: u64) void {
219
- env.change_state(.fuzzing, .tree_compact);
220
- env.tree.compact(tree_compact_callback, op);
221
- env.tick_until_state_change(.tree_compact, .fuzzing);
222
- }
223
-
224
- fn tree_compact_callback(tree: *Tree) void {
225
- const env = @fieldParentPtr(@This(), "tree", tree);
226
- env.change_state(.tree_compact, .fuzzing);
227
- }
228
-
229
- pub fn checkpoint(env: *Environment, op: u64) void {
230
- assert(env.checkpoint_op == null);
231
- env.checkpoint_op = op - constants.lsm_batch_multiple;
232
-
233
- env.change_state(.fuzzing, .tree_checkpoint);
234
- env.tree.checkpoint(tree_checkpoint_callback);
235
- env.tick_until_state_change(.tree_checkpoint, .superblock_checkpoint);
236
- env.tick_until_state_change(.superblock_checkpoint, .fuzzing);
237
- }
238
-
239
- fn tree_checkpoint_callback(tree: *Tree) void {
240
- const env = @fieldParentPtr(@This(), "tree", tree);
241
- const op = env.checkpoint_op.?;
242
- env.checkpoint_op = null;
243
-
244
- env.change_state(.tree_checkpoint, .superblock_checkpoint);
245
- env.superblock.checkpoint(superblock_checkpoint_callback, &env.superblock_context, .{
246
- .commit_min_checksum = env.superblock.working.vsr_state.commit_min_checksum + 1,
247
- .commit_min = op,
248
- .commit_max = op + 1,
249
- });
250
- }
251
-
252
- fn superblock_checkpoint_callback(superblock_context: *SuperBlock.Context) void {
253
- const env = @fieldParentPtr(@This(), "superblock_context", superblock_context);
254
- env.change_state(.superblock_checkpoint, .fuzzing);
255
- }
256
-
257
- pub fn get(env: *Environment, key: Key) ?*const Key.Value {
258
- env.change_state(.fuzzing, .tree_lookup);
259
-
260
- if (env.tree.lookup_from_memory(env.tree.lookup_snapshot_max, key)) |value| {
261
- env.change_state(.tree_lookup, .fuzzing);
262
- return Tree.unwrap_tombstone(value);
263
- }
264
-
265
- env.lookup_value = null;
266
- env.tree.lookup_from_levels(get_callback, &env.lookup_context, env.tree.lookup_snapshot_max, key);
267
- env.tick_until_state_change(.tree_lookup, .fuzzing);
268
- return env.lookup_value;
269
- }
270
-
271
- fn get_callback(lookup_context: *Tree.LookupContext, value: ?*const Key.Value) void {
272
- const env = @fieldParentPtr(Environment, "lookup_context", lookup_context);
273
- assert(env.lookup_value == null);
274
- env.lookup_value = value;
275
- env.change_state(.tree_lookup, .fuzzing);
276
- }
277
-
278
- pub fn apply(env: *Environment, fuzz_ops: []const FuzzOp) !void {
279
- // The tree should behave like a simple key-value data-structure.
280
- // We'll compare it to a hash map.
281
- var model = std.hash_map.AutoHashMap(Key, Key.Value).init(allocator);
282
- defer model.deinit();
283
-
284
- for (fuzz_ops) |fuzz_op, fuzz_op_index| {
285
- assert(env.state == .fuzzing);
286
- log.debug("Running fuzz_ops[{}/{}] == {}", .{ fuzz_op_index, fuzz_ops.len, fuzz_op });
287
-
288
- const storage_size_used = env.storage.size_used();
289
- log.debug("storage.size_used = {}/{}", .{ storage_size_used, env.storage.size });
290
-
291
- const model_size = model.count() * @sizeOf(Key.Value);
292
- log.debug("space_amplification = {d:.2}", .{
293
- @intToFloat(f64, storage_size_used) / @intToFloat(f64, model_size),
294
- });
295
-
296
- // Apply fuzz_op to the tree and the model.
297
- switch (fuzz_op) {
298
- .compact => |compact| {
299
- env.compact(compact.op);
300
- if (compact.checkpoint) env.checkpoint(compact.op);
301
- },
302
- .put => |value| {
303
- if (table_usage == .secondary_index) {
304
- if (model.get(Key.key_from_value(&value))) |old_value| {
305
- // Not allowed to put a present key without removing the old value first.
306
- env.tree.remove(&old_value);
307
- }
308
- }
309
- env.tree.put(&value);
310
- try model.put(Key.key_from_value(&value), value);
311
- },
312
- .remove => |value| {
313
- if (table_usage == .secondary_index and !model.contains((Key.key_from_value(&value)))) {
314
- // Not allowed to remove non-present keys
315
- } else {
316
- env.tree.remove(&value);
317
- }
318
- _ = model.remove(Key.key_from_value(&value));
319
- },
320
- .get => |key| {
321
- // Get account from lsm.
322
- const tree_value = env.get(key);
323
-
324
- // Compare result to model.
325
- const model_value = model.get(key);
326
- if (model_value == null) {
327
- assert(tree_value == null);
328
- } else {
329
- switch (table_usage) {
330
- .general => {
331
- assert(std.mem.eql(
332
- u8,
333
- std.mem.asBytes(&model_value.?),
334
- std.mem.asBytes(tree_value.?),
335
- ));
336
- },
337
- .secondary_index => {
338
- // secondary_index only preserves keys - may return old values
339
- assert(std.mem.eql(
340
- u8,
341
- std.mem.asBytes(&Key.key_from_value(&model_value.?)),
342
- std.mem.asBytes(&Key.key_from_value(tree_value.?)),
343
- ));
344
- },
345
- }
346
- }
347
- },
348
- }
349
- }
350
- }
351
- };
352
- }
353
-
354
- fn random_id(random: std.rand.Random, comptime Int: type) Int {
355
- // We have two opposing desires for random ids:
356
- const avg_int: Int = if (random.boolean())
357
- // 1. We want to cause many collisions.
358
- //8
359
- 100 * constants.lsm_growth_factor * tree_options.cache_entries_max
360
- else
361
- // 2. We want to generate enough ids that the cache can't hold them all.
362
- constants.lsm_growth_factor * tree_options.cache_entries_max;
363
- return fuzz.random_int_exponential(random, Int, avg_int);
364
- }
365
-
366
- pub fn generate_fuzz_ops(random: std.rand.Random, fuzz_op_count: usize) ![]const FuzzOp {
367
- log.info("fuzz_op_count = {}", .{fuzz_op_count});
368
-
369
- const fuzz_ops = try allocator.alloc(FuzzOp, fuzz_op_count);
370
- errdefer allocator.free(fuzz_ops);
371
-
372
- var fuzz_op_distribution = fuzz.Distribution(FuzzOpTag){
373
- // Maybe compact more often than forced to by `puts_since_compact`.
374
- .compact = if (random.boolean()) 0 else 1,
375
- // Always do puts, and always more puts than removes.
376
- .put = constants.lsm_batch_multiple * 2,
377
- // Maybe do some removes.
378
- .remove = if (random.boolean()) 0 else constants.lsm_batch_multiple,
379
- // Maybe do some gets.
380
- .get = if (random.boolean()) 0 else constants.lsm_batch_multiple,
381
- };
382
- log.info("fuzz_op_distribution = {d:.2}", .{fuzz_op_distribution});
383
-
384
- log.info("puts_since_compact_max = {}", .{puts_since_compact_max});
385
- log.info("compacts_per_checkpoint = {}", .{compacts_per_checkpoint});
386
-
387
- var op: u64 = 1;
388
- var puts_since_compact: usize = 0;
389
- for (fuzz_ops) |*fuzz_op| {
390
- const fuzz_op_tag = if (puts_since_compact >= puts_since_compact_max)
391
- // We have to compact before doing any other operations.
392
- FuzzOpTag.compact
393
- else
394
- // Otherwise pick a random FuzzOp.
395
- fuzz.random_enum(random, FuzzOpTag, fuzz_op_distribution);
396
- fuzz_op.* = switch (fuzz_op_tag) {
397
- .compact => compact: {
398
- const compact_op = op;
399
- op += 1;
400
- const is_checkpoint =
401
- // Can only checkpoint on the last beat of the bar.
402
- compact_op % constants.lsm_batch_multiple == constants.lsm_batch_multiple - 1 and
403
- compact_op > constants.lsm_batch_multiple and
404
- // Checkpoint at roughly the same rate as log wraparound.
405
- random.uintLessThan(usize, compacts_per_checkpoint) == 0;
406
- break :compact FuzzOp{
407
- .compact = .{
408
- .op = compact_op,
409
- .checkpoint = is_checkpoint,
410
- },
411
- };
412
- },
413
- .put => FuzzOp{ .put = .{
414
- .id = random_id(random, u64),
415
- .value = random.int(u63),
416
- } },
417
- .remove => FuzzOp{ .remove = .{
418
- .id = random_id(random, u64),
419
- .value = random.int(u63),
420
- } },
421
- .get => FuzzOp{ .get = .{
422
- .id = random_id(random, u64),
423
- } },
424
- };
425
- switch (fuzz_op.*) {
426
- .compact => puts_since_compact = 0,
427
- // Tree.remove() works by inserting a tombstone, so it counts as a put.
428
- .put, .remove => puts_since_compact += 1,
429
- .get => {},
430
- }
431
- }
432
-
433
- return fuzz_ops;
434
- }
435
-
436
- pub fn main() !void {
437
- try tracer.init(allocator);
438
- defer tracer.deinit(allocator);
439
-
440
- const fuzz_args = try fuzz.parse_fuzz_args(allocator);
441
-
442
- var rng = std.rand.DefaultPrng.init(fuzz_args.seed);
443
- const random = rng.random();
444
-
445
- const table_usage = random.enumValue(TableUsage);
446
- log.info("table_usage={}", .{table_usage});
447
-
448
- const storage_options = .{
449
- .seed = random.int(u64),
450
- .read_latency_min = 0,
451
- .read_latency_mean = 0 + fuzz.random_int_exponential(random, u64, 20),
452
- .write_latency_min = 0,
453
- .write_latency_mean = 0 + fuzz.random_int_exponential(random, u64, 20),
454
- };
455
-
456
- const fuzz_op_count = @minimum(
457
- fuzz_args.events_max orelse @as(usize, 1E7),
458
- fuzz.random_int_exponential(random, usize, 1E6),
459
- );
460
-
461
- const fuzz_ops = try generate_fuzz_ops(random, fuzz_op_count);
462
- defer allocator.free(fuzz_ops);
463
-
464
- // Init mocked storage.
465
- var storage = try Storage.init(allocator, constants.storage_size_max, storage_options);
466
- defer storage.deinit(allocator);
467
-
468
- // TODO Use inline switch after upgrading to zig 0.10
469
- switch (table_usage) {
470
- .general => {
471
- try EnvironmentType(.general).run(&storage, fuzz_ops);
472
- },
473
- .secondary_index => {
474
- try EnvironmentType(.secondary_index).run(&storage, fuzz_ops);
475
- },
476
- }
477
-
478
- log.info("Passed!", .{});
479
- }