tigerbeetle-node 0.11.8 → 0.11.9
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.
- package/dist/.client.node.sha256 +1 -1
- package/package.json +4 -3
- package/scripts/build_lib.sh +29 -0
- package/src/node.zig +1 -1
- package/src/tigerbeetle/scripts/validate_docs.sh +7 -1
- package/src/tigerbeetle/src/benchmark.zig +3 -3
- package/src/tigerbeetle/src/config.zig +29 -16
- package/src/tigerbeetle/src/constants.zig +30 -9
- package/src/tigerbeetle/src/ewah.zig +5 -5
- package/src/tigerbeetle/src/ewah_fuzz.zig +1 -1
- package/src/tigerbeetle/src/lsm/binary_search.zig +1 -1
- package/src/tigerbeetle/src/lsm/bloom_filter.zig +1 -1
- package/src/tigerbeetle/src/lsm/compaction.zig +34 -21
- package/src/tigerbeetle/src/lsm/forest_fuzz.zig +85 -103
- package/src/tigerbeetle/src/lsm/grid.zig +19 -13
- package/src/tigerbeetle/src/lsm/manifest_log.zig +8 -10
- package/src/tigerbeetle/src/lsm/manifest_log_fuzz.zig +12 -8
- package/src/tigerbeetle/src/lsm/merge_iterator.zig +1 -1
- package/src/tigerbeetle/src/lsm/segmented_array.zig +17 -17
- package/src/tigerbeetle/src/lsm/segmented_array_fuzz.zig +1 -1
- package/src/tigerbeetle/src/lsm/set_associative_cache.zig +1 -1
- package/src/tigerbeetle/src/lsm/table.zig +8 -20
- package/src/tigerbeetle/src/lsm/table_immutable.zig +1 -1
- package/src/tigerbeetle/src/lsm/table_iterator.zig +3 -3
- package/src/tigerbeetle/src/lsm/table_mutable.zig +14 -2
- package/src/tigerbeetle/src/lsm/tree.zig +31 -5
- package/src/tigerbeetle/src/lsm/tree_fuzz.zig +86 -114
- package/src/tigerbeetle/src/message_bus.zig +4 -4
- package/src/tigerbeetle/src/message_pool.zig +7 -10
- package/src/tigerbeetle/src/ring_buffer.zig +22 -12
- package/src/tigerbeetle/src/simulator.zig +360 -214
- package/src/tigerbeetle/src/state_machine/auditor.zig +5 -5
- package/src/tigerbeetle/src/state_machine/workload.zig +3 -3
- package/src/tigerbeetle/src/state_machine.zig +190 -178
- package/src/tigerbeetle/src/{util.zig → stdx.zig} +2 -0
- package/src/tigerbeetle/src/storage.zig +13 -6
- package/src/tigerbeetle/src/{test → testing/cluster}/message_bus.zig +3 -3
- package/src/tigerbeetle/src/{test → testing/cluster}/network.zig +46 -22
- package/src/tigerbeetle/src/testing/cluster/state_checker.zig +169 -0
- package/src/tigerbeetle/src/testing/cluster/storage_checker.zig +202 -0
- package/src/tigerbeetle/src/testing/cluster.zig +537 -0
- package/src/tigerbeetle/src/{test → testing}/fuzz.zig +0 -0
- package/src/tigerbeetle/src/testing/hash_log.zig +66 -0
- package/src/tigerbeetle/src/{test → testing}/id.zig +0 -0
- package/src/tigerbeetle/src/testing/packet_simulator.zig +365 -0
- package/src/tigerbeetle/src/{test → testing}/priority_queue.zig +1 -1
- package/src/tigerbeetle/src/testing/reply_sequence.zig +139 -0
- package/src/tigerbeetle/src/{test → testing}/state_machine.zig +3 -1
- package/src/tigerbeetle/src/testing/storage.zig +754 -0
- package/src/tigerbeetle/src/{test → testing}/table.zig +21 -0
- package/src/tigerbeetle/src/{test → testing}/time.zig +0 -0
- package/src/tigerbeetle/src/tigerbeetle.zig +2 -0
- package/src/tigerbeetle/src/tracer.zig +3 -3
- package/src/tigerbeetle/src/unit_tests.zig +4 -4
- package/src/tigerbeetle/src/vopr.zig +2 -2
- package/src/tigerbeetle/src/vsr/client.zig +5 -2
- package/src/tigerbeetle/src/vsr/clock.zig +93 -53
- package/src/tigerbeetle/src/vsr/journal.zig +29 -14
- package/src/tigerbeetle/src/vsr/journal_format_fuzz.zig +2 -2
- package/src/tigerbeetle/src/vsr/replica.zig +1383 -774
- package/src/tigerbeetle/src/vsr/replica_format.zig +2 -2
- package/src/tigerbeetle/src/vsr/superblock.zig +59 -43
- package/src/tigerbeetle/src/vsr/superblock_client_table.zig +7 -7
- package/src/tigerbeetle/src/vsr/superblock_free_set.zig +1 -1
- package/src/tigerbeetle/src/vsr/superblock_free_set_fuzz.zig +1 -1
- package/src/tigerbeetle/src/vsr/superblock_fuzz.zig +15 -7
- package/src/tigerbeetle/src/vsr/superblock_manifest.zig +38 -19
- package/src/tigerbeetle/src/vsr/superblock_quorums_fuzz.zig +1 -1
- package/src/tigerbeetle/src/vsr.zig +6 -4
- package/src/tigerbeetle/src/demo.zig +0 -132
- package/src/tigerbeetle/src/demo_01_create_accounts.zig +0 -35
- package/src/tigerbeetle/src/demo_02_lookup_accounts.zig +0 -7
- package/src/tigerbeetle/src/demo_03_create_transfers.zig +0 -37
- package/src/tigerbeetle/src/demo_04_create_pending_transfers.zig +0 -61
- package/src/tigerbeetle/src/demo_05_post_pending_transfers.zig +0 -37
- package/src/tigerbeetle/src/demo_06_void_pending_transfers.zig +0 -24
- package/src/tigerbeetle/src/demo_07_lookup_transfers.zig +0 -7
- package/src/tigerbeetle/src/test/cluster.zig +0 -352
- package/src/tigerbeetle/src/test/conductor.zig +0 -366
- package/src/tigerbeetle/src/test/packet_simulator.zig +0 -398
- package/src/tigerbeetle/src/test/state_checker.zig +0 -169
- package/src/tigerbeetle/src/test/storage.zig +0 -864
- package/src/tigerbeetle/src/test/storage_checker.zig +0 -204
package/dist/.client.node.sha256
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
ed71bbee01e27a1f4638bfc2b0542414c1fc8b503bce5bbcc45ae2b80b1edb26 dist/client.node
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tigerbeetle-node",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.9",
|
|
4
4
|
"description": "TigerBeetle Node.js client",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
@@ -18,13 +18,14 @@
|
|
|
18
18
|
"package.json",
|
|
19
19
|
"package-lock.json",
|
|
20
20
|
"scripts/download_node_headers.sh",
|
|
21
|
+
"scripts/build_lib.sh",
|
|
21
22
|
"src/c.zig",
|
|
22
23
|
"src/benchmark.ts",
|
|
23
24
|
"src/index.ts",
|
|
24
25
|
"src/node.zig",
|
|
25
26
|
"src/test.ts",
|
|
26
27
|
"src/tigerbeetle/src/*.zig",
|
|
27
|
-
"src/tigerbeetle/src/{c,io,lsm,
|
|
28
|
+
"src/tigerbeetle/src/{c,io,lsm,testing,vsr,state_machine}",
|
|
28
29
|
"src/tigerbeetle/scripts",
|
|
29
30
|
"src/translate.zig",
|
|
30
31
|
"tsconfig.json"
|
|
@@ -40,7 +41,7 @@
|
|
|
40
41
|
"download_node_headers": "sh ./scripts/download_node_headers.sh",
|
|
41
42
|
"build": "npm run build_tsc && npm run build_lib",
|
|
42
43
|
"build_tsc": "./node_modules/typescript/bin/tsc",
|
|
43
|
-
"build_lib": "
|
|
44
|
+
"build_lib": "sh ./scripts/build_lib.sh",
|
|
44
45
|
"prepack": "npm run build_tsc",
|
|
45
46
|
"clean": "rm -rf build dist node_modules src/zig-cache zig"
|
|
46
47
|
},
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
# macOS 13 Ventura is not supported on Zig 0.9.x.
|
|
6
|
+
# Overriding -target is one workaround Andrew suggests.
|
|
7
|
+
# https://github.com/ziglang/zig/issues/10478#issuecomment-1294313967
|
|
8
|
+
# Cut everything after the first `.` in the target query result
|
|
9
|
+
# because the rest of it doesn't always seem to be valid when passed
|
|
10
|
+
# back in to `-target`.
|
|
11
|
+
target="$(./zig/zig targets | grep triple |cut -d '"' -f 4 | cut -d '.' -f 1)"
|
|
12
|
+
if [ "$(./zig/zig targets | grep triple |cut -d '"' -f 4 | cut -d '.' -f 1,2)" = "aarch64-macos.13" ]; then
|
|
13
|
+
target="native-macos.11"
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
echo "Building for $target"
|
|
17
|
+
|
|
18
|
+
mkdir -p dist
|
|
19
|
+
|
|
20
|
+
./zig/zig build-lib \
|
|
21
|
+
-mcpu=baseline \
|
|
22
|
+
-OReleaseSafe \
|
|
23
|
+
-dynamic \
|
|
24
|
+
-lc \
|
|
25
|
+
-isystem build/node-"$(node --version)"/include/node \
|
|
26
|
+
-fallow-shlib-undefined \
|
|
27
|
+
-femit-bin=dist/client.node \
|
|
28
|
+
-target "$target" \
|
|
29
|
+
src/node.zig
|
package/src/node.zig
CHANGED
|
@@ -13,5 +13,11 @@ if [[ -z "$BRANCH" ]]; then
|
|
|
13
13
|
# Otherwise fall back to git rev-parse
|
|
14
14
|
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
|
15
15
|
fi
|
|
16
|
-
|
|
16
|
+
|
|
17
|
+
REPO="https://github.com/tigerbeetledb/tigerbeetle"
|
|
18
|
+
if [[ -n "$SOURCE_REPO" ]]; then
|
|
19
|
+
REPO="${SOURCE_REPO}"
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
( cd docs_website && npm install && ./scripts/build.sh "$BRANCH" "$REPO" )
|
|
17
23
|
rm -rf docs_website
|
|
@@ -8,7 +8,7 @@ pub const log_level: std.log.Level = .err;
|
|
|
8
8
|
|
|
9
9
|
const IO = @import("io.zig").IO;
|
|
10
10
|
|
|
11
|
-
const
|
|
11
|
+
const stdx = @import("stdx.zig");
|
|
12
12
|
const Storage = @import("storage.zig").Storage;
|
|
13
13
|
const MessagePool = @import("message_pool.zig").MessagePool;
|
|
14
14
|
const MessageBus = @import("message_bus.zig").MessageBusClient;
|
|
@@ -211,7 +211,7 @@ const TimedQueue = struct {
|
|
|
211
211
|
const message = self.client.get_message();
|
|
212
212
|
defer self.client.unref(message);
|
|
213
213
|
|
|
214
|
-
|
|
214
|
+
stdx.copy_disjoint(
|
|
215
215
|
.inexact,
|
|
216
216
|
u8,
|
|
217
217
|
message.buffer[@sizeOf(vsr.Header)..],
|
|
@@ -279,7 +279,7 @@ const TimedQueue = struct {
|
|
|
279
279
|
const message = self.client.get_message();
|
|
280
280
|
defer self.client.unref(message);
|
|
281
281
|
|
|
282
|
-
|
|
282
|
+
stdx.copy_disjoint(
|
|
283
283
|
.inexact,
|
|
284
284
|
u8,
|
|
285
285
|
message.buffer[@sizeOf(vsr.Header)..],
|
|
@@ -1,8 +1,18 @@
|
|
|
1
|
+
//! Raw configuration values.
|
|
2
|
+
//!
|
|
3
|
+
//! Code which needs these values should use `constants.zig` instead.
|
|
4
|
+
//! Configuration values are set from a combination of:
|
|
5
|
+
//! - default values
|
|
6
|
+
//! - `root.tigerbeetle_config`
|
|
7
|
+
//! - `@import("tigerbeetle_options")`
|
|
8
|
+
|
|
1
9
|
const builtin = @import("builtin");
|
|
2
10
|
const std = @import("std");
|
|
3
11
|
|
|
4
|
-
const build_options = @import("tigerbeetle_build_options");
|
|
5
12
|
const root = @import("root");
|
|
13
|
+
// Allow setting build-time config either via `build.zig` `Options`, or via a struct in the root file.
|
|
14
|
+
const build_options =
|
|
15
|
+
if (@hasDecl(root, "vsr_options")) root.vsr_options else @import("vsr_options");
|
|
6
16
|
|
|
7
17
|
const vsr = @import("vsr.zig");
|
|
8
18
|
const sector_size = @import("constants.zig").sector_size;
|
|
@@ -25,6 +35,7 @@ pub const Config = struct {
|
|
|
25
35
|
const ConfigProcess = struct {
|
|
26
36
|
log_level: std.log.Level = .info,
|
|
27
37
|
tracer_backend: TracerBackend = .none,
|
|
38
|
+
hash_log_mode: HashLogMode = .none,
|
|
28
39
|
verify: bool,
|
|
29
40
|
port: u16 = 3001,
|
|
30
41
|
address: []const u8 = "127.0.0.1",
|
|
@@ -68,6 +79,7 @@ const ConfigProcess = struct {
|
|
|
68
79
|
const ConfigCluster = struct {
|
|
69
80
|
cache_line_size: comptime_int = 64,
|
|
70
81
|
clients_max: usize,
|
|
82
|
+
pipeline_prepare_queue_max: usize = 8,
|
|
71
83
|
quorum_replication_max: u8 = 3,
|
|
72
84
|
journal_slot_count: usize = 1024,
|
|
73
85
|
message_size_max: usize = 1 * 1024 * 1024,
|
|
@@ -80,7 +92,6 @@ const ConfigCluster = struct {
|
|
|
80
92
|
lsm_batch_multiple: comptime_int = 4,
|
|
81
93
|
lsm_snapshots_max: usize = 32,
|
|
82
94
|
lsm_value_to_key_layout_ratio_min: comptime_int = 16,
|
|
83
|
-
state_machine: StateMachine = .accounting,
|
|
84
95
|
|
|
85
96
|
/// The WAL requires at least two sectors of redundant headers — otherwise we could lose them all to
|
|
86
97
|
/// a single torn write. A replica needs at least one valid redundant header to determine an
|
|
@@ -91,7 +102,7 @@ const ConfigCluster = struct {
|
|
|
91
102
|
pub const clients_max_min = 1;
|
|
92
103
|
|
|
93
104
|
/// The smallest possible message_size_max (for use in the simulator to improve performance).
|
|
94
|
-
/// The message body must have room for
|
|
105
|
+
/// The message body must have room for pipeline_prepare_queue_max headers in the DVC.
|
|
95
106
|
pub fn message_size_max_min(clients_max: usize) usize {
|
|
96
107
|
return std.math.max(
|
|
97
108
|
sector_size,
|
|
@@ -118,9 +129,10 @@ pub const TracerBackend = enum {
|
|
|
118
129
|
tracy,
|
|
119
130
|
};
|
|
120
131
|
|
|
121
|
-
pub const
|
|
122
|
-
|
|
123
|
-
|
|
132
|
+
pub const HashLogMode = enum {
|
|
133
|
+
none,
|
|
134
|
+
create,
|
|
135
|
+
check,
|
|
124
136
|
};
|
|
125
137
|
|
|
126
138
|
pub const configs = struct {
|
|
@@ -166,10 +178,11 @@ pub const configs = struct {
|
|
|
166
178
|
.verify = true,
|
|
167
179
|
},
|
|
168
180
|
.cluster = .{
|
|
169
|
-
.clients_max = 4,
|
|
181
|
+
.clients_max = 4 + 3,
|
|
182
|
+
.pipeline_prepare_queue_max = 4,
|
|
170
183
|
.journal_slot_count = Config.Cluster.journal_slot_count_min,
|
|
171
|
-
.message_size_max = Config.Cluster.message_size_max_min(
|
|
172
|
-
.storage_size_max = 1024 * 1024 * 1024,
|
|
184
|
+
.message_size_max = Config.Cluster.message_size_max_min(4),
|
|
185
|
+
.storage_size_max = 4 * 1024 * 1024 * 1024,
|
|
173
186
|
|
|
174
187
|
.block_size = sector_size,
|
|
175
188
|
.lsm_growth_factor = 4,
|
|
@@ -196,13 +209,6 @@ pub const configs = struct {
|
|
|
196
209
|
.test_min => test_min,
|
|
197
210
|
};
|
|
198
211
|
|
|
199
|
-
base.cluster.state_machine = if (@hasDecl(root, "decode_events"))
|
|
200
|
-
// TODO(DJ) This is a hack to work around the absense of tigerbeetle_build_options.
|
|
201
|
-
// This should be removed once the node client is built using `zig build`.
|
|
202
|
-
.accounting
|
|
203
|
-
else
|
|
204
|
-
@intToEnum(StateMachine, @enumToInt(build_options.config_cluster_state_machine));
|
|
205
|
-
|
|
206
212
|
// TODO Use additional build options to overwrite other fields.
|
|
207
213
|
base.process.tracer_backend = if (@hasDecl(root, "tracer_backend"))
|
|
208
214
|
// TODO(jamii)
|
|
@@ -214,6 +220,13 @@ pub const configs = struct {
|
|
|
214
220
|
// but a different type from a nominal typing perspective.
|
|
215
221
|
@intToEnum(TracerBackend, @enumToInt(build_options.tracer_backend));
|
|
216
222
|
|
|
223
|
+
base.process.hash_log_mode = if (@hasDecl(root, "decode_events"))
|
|
224
|
+
// TODO(DJ) This is a hack to work around the absense of tigerbeetle_build_options.
|
|
225
|
+
// This should be removed once the node client is built using `zig build`.
|
|
226
|
+
.none
|
|
227
|
+
else
|
|
228
|
+
@intToEnum(HashLogMode, @enumToInt(build_options.hash_log_mode));
|
|
229
|
+
|
|
217
230
|
break :current base;
|
|
218
231
|
};
|
|
219
232
|
};
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
//! Constants are the configuration that the code actually imports — they include:
|
|
2
|
+
//! - all of the configuration values (flattened)
|
|
3
|
+
//! - derived configuration values,
|
|
4
|
+
|
|
1
5
|
const std = @import("std");
|
|
2
6
|
const assert = std.debug.assert;
|
|
3
7
|
const vsr = @import("vsr.zig");
|
|
@@ -18,15 +22,12 @@ else
|
|
|
18
22
|
// Default is `.none`.
|
|
19
23
|
pub const tracer_backend = config.process.tracer_backend;
|
|
20
24
|
|
|
25
|
+
// Which mode to use for ./testing/hash_log.zig.
|
|
26
|
+
pub const hash_log_mode = config.process.hash_log_mode;
|
|
27
|
+
|
|
21
28
|
/// The maximum number of replicas allowed in a cluster.
|
|
22
29
|
pub const replicas_max = 6;
|
|
23
30
|
|
|
24
|
-
pub const state_machine = config.cluster.state_machine;
|
|
25
|
-
pub const StateMachineType = switch (config.cluster.state_machine) {
|
|
26
|
-
.accounting => @import("state_machine.zig").StateMachineType,
|
|
27
|
-
.testing => @import("test/state_machine.zig").StateMachineType,
|
|
28
|
-
};
|
|
29
|
-
|
|
30
31
|
/// The maximum number of clients allowed per cluster, where each client has a unique 128-bit ID.
|
|
31
32
|
/// This impacts the amount of memory allocated at initialization by the server.
|
|
32
33
|
/// This determines the size of the VR client table used to cache replies to clients by client ID.
|
|
@@ -131,7 +132,7 @@ comptime {
|
|
|
131
132
|
assert(journal_slot_count >= Config.Cluster.journal_slot_count_min);
|
|
132
133
|
assert(journal_slot_count >= lsm_batch_multiple * 2);
|
|
133
134
|
assert(journal_slot_count % lsm_batch_multiple == 0);
|
|
134
|
-
assert(
|
|
135
|
+
assert(journal_slot_count > pipeline_prepare_queue_max);
|
|
135
136
|
|
|
136
137
|
assert(journal_size_max == journal_size_headers + journal_size_prepares);
|
|
137
138
|
}
|
|
@@ -161,7 +162,27 @@ comptime {
|
|
|
161
162
|
/// The maximum number of Viewstamped Replication prepare messages that can be inflight at a time.
|
|
162
163
|
/// This is immutable once assigned per cluster, as replicas need to know how many operations might
|
|
163
164
|
/// possibly be uncommitted during a view change, and this must be constant for all replicas.
|
|
164
|
-
pub const
|
|
165
|
+
pub const pipeline_prepare_queue_max = config.cluster.pipeline_prepare_queue_max;
|
|
166
|
+
|
|
167
|
+
/// The maximum number of Viewstamped Replication request messages that can be queued at a primary,
|
|
168
|
+
/// waiting to prepare.
|
|
169
|
+
// TODO(Zig): After 0.10, change this to simply "clients_max -| pipeline_prepare_queue_max".
|
|
170
|
+
// In Zig 0.9 compilation fails with "operation caused overflow" despite the saturating subtraction.
|
|
171
|
+
// See: https://github.com/ziglang/zig/issues/10870
|
|
172
|
+
pub const pipeline_request_queue_max =
|
|
173
|
+
if (clients_max < pipeline_prepare_queue_max)
|
|
174
|
+
0
|
|
175
|
+
else
|
|
176
|
+
clients_max - pipeline_prepare_queue_max;
|
|
177
|
+
|
|
178
|
+
comptime {
|
|
179
|
+
// A prepare-queue capacity larger than clients_max is wasted.
|
|
180
|
+
assert(pipeline_prepare_queue_max <= clients_max);
|
|
181
|
+
// A total queue capacity larger than clients_max is wasted.
|
|
182
|
+
assert(pipeline_prepare_queue_max + pipeline_request_queue_max <= clients_max);
|
|
183
|
+
assert(pipeline_prepare_queue_max > 0);
|
|
184
|
+
assert(pipeline_request_queue_max >= 0);
|
|
185
|
+
}
|
|
165
186
|
|
|
166
187
|
/// The minimum and maximum amount of time in milliseconds to wait before initiating a connection.
|
|
167
188
|
/// Exponential backoff and jitter are applied within this range.
|
|
@@ -263,7 +284,7 @@ pub const iops_write_max = journal_iops_write_max;
|
|
|
263
284
|
/// The maximum number of concurrent WAL read I/O operations to allow at once.
|
|
264
285
|
pub const journal_iops_read_max = config.process.journal_iops_read_max;
|
|
265
286
|
/// The maximum number of concurrent WAL write I/O operations to allow at once.
|
|
266
|
-
/// Ideally this is at least as high as
|
|
287
|
+
/// Ideally this is at least as high as pipeline_prepare_queue_max, but it is safe to be lower.
|
|
267
288
|
pub const journal_iops_write_max = config.process.journal_iops_write_max;
|
|
268
289
|
|
|
269
290
|
/// The number of redundant copies of the superblock in the superblock storage zone.
|
|
@@ -2,9 +2,9 @@ const std = @import("std");
|
|
|
2
2
|
const assert = std.debug.assert;
|
|
3
3
|
const math = std.math;
|
|
4
4
|
const mem = std.mem;
|
|
5
|
-
const
|
|
6
|
-
const div_ceil =
|
|
7
|
-
const disjoint_slices =
|
|
5
|
+
const stdx = @import("stdx.zig");
|
|
6
|
+
const div_ceil = stdx.div_ceil;
|
|
7
|
+
const disjoint_slices = stdx.disjoint_slices;
|
|
8
8
|
|
|
9
9
|
/// Encode or decode a bitset using Daniel Lemire's EWAH codec.
|
|
10
10
|
/// ("Histogram-Aware Sorting for Enhanced Word-Aligned Compression in Bitmap Indexes")
|
|
@@ -78,7 +78,7 @@ pub fn ewah(comptime Word: type) type {
|
|
|
78
78
|
if (marker.uniform_bit == 1) ~@as(Word, 0) else 0,
|
|
79
79
|
);
|
|
80
80
|
target_index += marker.uniform_word_count;
|
|
81
|
-
|
|
81
|
+
stdx.copy_disjoint(
|
|
82
82
|
.exact,
|
|
83
83
|
Word,
|
|
84
84
|
target_words[target_index..][0..marker.literal_word_count],
|
|
@@ -129,7 +129,7 @@ pub fn ewah(comptime Word: type) type {
|
|
|
129
129
|
.literal_word_count = @intCast(MarkerLiteralCount, literal_word_count),
|
|
130
130
|
});
|
|
131
131
|
target_index += 1;
|
|
132
|
-
|
|
132
|
+
stdx.copy_disjoint(
|
|
133
133
|
.exact,
|
|
134
134
|
Word,
|
|
135
135
|
target_words[target_index..][0..literal_word_count],
|
|
@@ -4,7 +4,7 @@ const assert = std.debug.assert;
|
|
|
4
4
|
const log = std.log.scoped(.fuzz_ewah);
|
|
5
5
|
|
|
6
6
|
const ewah = @import("./ewah.zig");
|
|
7
|
-
const fuzz = @import("./
|
|
7
|
+
const fuzz = @import("./testing/fuzz.zig");
|
|
8
8
|
|
|
9
9
|
pub const tigerbeetle_config = @import("config.zig").configs.test_min;
|
|
10
10
|
|
|
@@ -82,7 +82,7 @@ test {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
const test_bloom_filter = struct {
|
|
85
|
-
const fuzz = @import("../
|
|
85
|
+
const fuzz = @import("../testing/fuzz.zig");
|
|
86
86
|
const block_size = @import("../constants.zig").block_size;
|
|
87
87
|
|
|
88
88
|
fn random_keys(random: std.rand.Random, iter: usize) !void {
|
|
@@ -62,7 +62,12 @@ pub fn CompactionType(
|
|
|
62
62
|
const BlockWrite = struct {
|
|
63
63
|
write: Grid.Write = undefined,
|
|
64
64
|
block: *BlockPtr = undefined,
|
|
65
|
-
|
|
65
|
+
state: BlockState = .building,
|
|
66
|
+
};
|
|
67
|
+
const BlockState = enum {
|
|
68
|
+
building,
|
|
69
|
+
writable,
|
|
70
|
+
writing,
|
|
66
71
|
};
|
|
67
72
|
|
|
68
73
|
const Manifest = ManifestType(Table, Storage);
|
|
@@ -241,9 +246,9 @@ pub fn CompactionType(
|
|
|
241
246
|
.level_a_input = if (table_a) |table| table.* else null,
|
|
242
247
|
};
|
|
243
248
|
|
|
244
|
-
assert(
|
|
245
|
-
assert(
|
|
246
|
-
assert(
|
|
249
|
+
assert(compaction.index.state == .building);
|
|
250
|
+
assert(compaction.filter.state == .building);
|
|
251
|
+
assert(compaction.data.state == .building);
|
|
247
252
|
|
|
248
253
|
// TODO Implement manifest.move_table() optimization if there's only range.table_count == 1.
|
|
249
254
|
// This would do update_tables + insert_tables inline without going through the iterators.
|
|
@@ -342,6 +347,14 @@ pub fn CompactionType(
|
|
|
342
347
|
const write_callback = struct {
|
|
343
348
|
fn callback(write: *Grid.Write) void {
|
|
344
349
|
const block_write = @fieldParentPtr(BlockWrite, "write", write);
|
|
350
|
+
|
|
351
|
+
assert(block_write.state == .writing);
|
|
352
|
+
block_write.state = .building;
|
|
353
|
+
|
|
354
|
+
if (constants.verify) {
|
|
355
|
+
// We've finished writing so the block should now be zeroed.
|
|
356
|
+
assert(mem.allEqual(u8, block_write.block.*, 0));
|
|
357
|
+
}
|
|
345
358
|
block_write.block = undefined;
|
|
346
359
|
|
|
347
360
|
const _compaction = @fieldParentPtr(Compaction, @tagName(field), block_write);
|
|
@@ -350,8 +363,8 @@ pub fn CompactionType(
|
|
|
350
363
|
}.callback;
|
|
351
364
|
|
|
352
365
|
const block_write: *BlockWrite = &@field(compaction, @tagName(field));
|
|
353
|
-
if (block_write.writable) {
|
|
354
|
-
block_write.
|
|
366
|
+
if (block_write.state == .writable) {
|
|
367
|
+
block_write.state = .writing;
|
|
355
368
|
|
|
356
369
|
compaction.io_start();
|
|
357
370
|
compaction.grid.write_block(
|
|
@@ -405,9 +418,9 @@ pub fn CompactionType(
|
|
|
405
418
|
assert(!compaction.merge_iterator.?.empty());
|
|
406
419
|
}
|
|
407
420
|
|
|
408
|
-
assert(
|
|
409
|
-
assert(
|
|
410
|
-
assert(
|
|
421
|
+
assert(compaction.data.state == .building);
|
|
422
|
+
assert(compaction.filter.state == .building);
|
|
423
|
+
assert(compaction.index.state == .building);
|
|
411
424
|
|
|
412
425
|
if (!compaction.merge_iterator.?.empty()) {
|
|
413
426
|
compaction.cpu_merge();
|
|
@@ -444,9 +457,9 @@ pub fn CompactionType(
|
|
|
444
457
|
// Ensure there are values to merge and that is it safe to do so.
|
|
445
458
|
const merge_iterator = &compaction.merge_iterator.?;
|
|
446
459
|
assert(!merge_iterator.empty());
|
|
447
|
-
assert(
|
|
448
|
-
assert(
|
|
449
|
-
assert(
|
|
460
|
+
assert(compaction.data.state == .building);
|
|
461
|
+
assert(compaction.filter.state == .building);
|
|
462
|
+
assert(compaction.index.state == .building);
|
|
450
463
|
|
|
451
464
|
// Build up a data block with values merged from the read iterators.
|
|
452
465
|
// This skips tombstone values if compaction was started with the intent to drop them.
|
|
@@ -470,8 +483,8 @@ pub fn CompactionType(
|
|
|
470
483
|
|
|
471
484
|
// Mark the finished data block as writable for the next compact_tick() call.
|
|
472
485
|
compaction.data.block = &compaction.table_builder.data_block;
|
|
473
|
-
assert(
|
|
474
|
-
compaction.data.
|
|
486
|
+
assert(compaction.data.state == .building);
|
|
487
|
+
compaction.data.state = .writable;
|
|
475
488
|
}
|
|
476
489
|
|
|
477
490
|
// Finalize the filter block if it's full or if it contains pending data blocks
|
|
@@ -487,8 +500,8 @@ pub fn CompactionType(
|
|
|
487
500
|
|
|
488
501
|
// Mark the finished filter block as writable for the next compact_tick() call.
|
|
489
502
|
compaction.filter.block = &compaction.table_builder.filter_block;
|
|
490
|
-
assert(
|
|
491
|
-
compaction.filter.
|
|
503
|
+
assert(compaction.filter.state == .building);
|
|
504
|
+
compaction.filter.state = .writable;
|
|
492
505
|
}
|
|
493
506
|
|
|
494
507
|
// Finalize the index block if it's full or if it contains pending data blocks
|
|
@@ -507,8 +520,8 @@ pub fn CompactionType(
|
|
|
507
520
|
|
|
508
521
|
// Mark the finished index block as writable for the next compact_tick() call.
|
|
509
522
|
compaction.index.block = &compaction.table_builder.index_block;
|
|
510
|
-
assert(
|
|
511
|
-
compaction.index.
|
|
523
|
+
assert(compaction.index.state == .building);
|
|
524
|
+
compaction.index.state = .writable;
|
|
512
525
|
|
|
513
526
|
compaction.tables_output_count += 1;
|
|
514
527
|
assert(compaction.tables_output_count <= compaction.range.table_count);
|
|
@@ -524,9 +537,9 @@ pub fn CompactionType(
|
|
|
524
537
|
|
|
525
538
|
// Ensure merging is truly finished.
|
|
526
539
|
assert(compaction.merge_iterator.?.empty());
|
|
527
|
-
assert(
|
|
528
|
-
assert(
|
|
529
|
-
assert(
|
|
540
|
+
assert(compaction.data.state == .building);
|
|
541
|
+
assert(compaction.filter.state == .building);
|
|
542
|
+
assert(compaction.index.state == .building);
|
|
530
543
|
|
|
531
544
|
// Double check the iterators are finished as well.
|
|
532
545
|
const stream_empty = struct {
|