tigerbeetle-node 0.4.2 → 0.5.2

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 (58) hide show
  1. package/README.md +19 -5
  2. package/dist/benchmark.js.map +1 -1
  3. package/dist/index.d.ts +18 -16
  4. package/dist/index.js +35 -13
  5. package/dist/index.js.map +1 -1
  6. package/dist/test.js +12 -0
  7. package/dist/test.js.map +1 -1
  8. package/package.json +2 -2
  9. package/scripts/postinstall.sh +2 -2
  10. package/src/benchmark.ts +2 -2
  11. package/src/index.ts +29 -4
  12. package/src/node.zig +120 -17
  13. package/src/test.ts +14 -0
  14. package/src/tigerbeetle/scripts/install.sh +1 -1
  15. package/src/tigerbeetle/scripts/install_zig.bat +109 -0
  16. package/src/tigerbeetle/scripts/install_zig.sh +4 -2
  17. package/src/tigerbeetle/scripts/lint.zig +8 -2
  18. package/src/tigerbeetle/scripts/vopr.bat +48 -0
  19. package/src/tigerbeetle/src/benchmark.zig +10 -8
  20. package/src/tigerbeetle/src/cli.zig +6 -4
  21. package/src/tigerbeetle/src/config.zig +2 -2
  22. package/src/tigerbeetle/src/demo.zig +119 -89
  23. package/src/tigerbeetle/src/demo_01_create_accounts.zig +5 -3
  24. package/src/tigerbeetle/src/demo_02_lookup_accounts.zig +2 -3
  25. package/src/tigerbeetle/src/demo_03_create_transfers.zig +5 -3
  26. package/src/tigerbeetle/src/demo_04_create_transfers_two_phase_commit.zig +5 -3
  27. package/src/tigerbeetle/src/demo_05_accept_transfers.zig +5 -3
  28. package/src/tigerbeetle/src/demo_06_reject_transfers.zig +5 -3
  29. package/src/tigerbeetle/src/demo_07_lookup_transfers.zig +7 -0
  30. package/src/tigerbeetle/src/io/benchmark.zig +238 -0
  31. package/src/tigerbeetle/src/{io_darwin.zig → io/darwin.zig} +89 -124
  32. package/src/tigerbeetle/src/io/linux.zig +933 -0
  33. package/src/tigerbeetle/src/io/test.zig +621 -0
  34. package/src/tigerbeetle/src/io.zig +7 -1328
  35. package/src/tigerbeetle/src/main.zig +18 -10
  36. package/src/tigerbeetle/src/message_bus.zig +43 -60
  37. package/src/tigerbeetle/src/message_pool.zig +3 -2
  38. package/src/tigerbeetle/src/ring_buffer.zig +135 -68
  39. package/src/tigerbeetle/src/simulator.zig +41 -37
  40. package/src/tigerbeetle/src/state_machine.zig +851 -26
  41. package/src/tigerbeetle/src/storage.zig +49 -46
  42. package/src/tigerbeetle/src/test/cluster.zig +2 -2
  43. package/src/tigerbeetle/src/test/message_bus.zig +6 -6
  44. package/src/tigerbeetle/src/test/network.zig +3 -3
  45. package/src/tigerbeetle/src/test/packet_simulator.zig +32 -29
  46. package/src/tigerbeetle/src/test/state_checker.zig +2 -2
  47. package/src/tigerbeetle/src/test/state_machine.zig +4 -0
  48. package/src/tigerbeetle/src/test/storage.zig +39 -19
  49. package/src/tigerbeetle/src/test/time.zig +2 -2
  50. package/src/tigerbeetle/src/tigerbeetle.zig +6 -129
  51. package/src/tigerbeetle/src/time.zig +6 -5
  52. package/src/tigerbeetle/src/vsr/client.zig +11 -11
  53. package/src/tigerbeetle/src/vsr/clock.zig +26 -43
  54. package/src/tigerbeetle/src/vsr/journal.zig +7 -6
  55. package/src/tigerbeetle/src/vsr/marzullo.zig +6 -3
  56. package/src/tigerbeetle/src/vsr/replica.zig +51 -48
  57. package/src/tigerbeetle/src/vsr.zig +24 -20
  58. package/src/translate.zig +55 -55
package/src/index.ts CHANGED
@@ -130,7 +130,6 @@ export enum CommitTransferError {
130
130
  transfer_not_found,
131
131
  transfer_not_two_phase_commit,
132
132
  transfer_expired,
133
- already_auto_committed,
134
133
  already_committed,
135
134
  already_committed_but_accepted,
136
135
  already_committed_but_rejected,
@@ -151,16 +150,18 @@ export type CommitTransfersError = {
151
150
  }
152
151
 
153
152
  export type AccountID = bigint // u128
153
+ export type TransferID = bigint // u128
154
154
 
155
- export type Event = Account | Transfer | Commit | AccountID
156
- export type Result = CreateAccountsError | CreateTransfersError | CommitTransfersError | Account
155
+ export type Event = Account | Transfer | Commit | AccountID | TransferID
156
+ export type Result = CreateAccountsError | CreateTransfersError | CommitTransfersError | Account | Transfer
157
157
  export type ResultCallback = (error: undefined | Error, results: Result[]) => void
158
158
 
159
159
  export enum Operation {
160
160
  CREATE_ACCOUNT = 3,
161
161
  CREATE_TRANSFER,
162
162
  COMMIT_TRANSFER,
163
- ACCOUNT_LOOKUP
163
+ ACCOUNT_LOOKUP,
164
+ TRANSFER_LOOKUP
164
165
  }
165
166
 
166
167
  export interface Client {
@@ -168,6 +169,7 @@ export interface Client {
168
169
  createTransfers: (batch: Transfer[]) => Promise<CreateTransfersError[]>
169
170
  commitTransfers: (batch: Commit[]) => Promise<CommitTransfersError[]>
170
171
  lookupAccounts: (batch: AccountID[]) => Promise<Account[]>
172
+ lookupTransfers: (batch: TransferID[]) => Promise<Transfer[]>
171
173
  request: (operation: Operation, batch: Event[], callback: ResultCallback) => void
172
174
  rawRequest: (operation: Operation, rawBatch: Buffer, callback: ResultCallback) => void
173
175
  destroy: () => void
@@ -237,6 +239,7 @@ export function createClient (args: InitArgs): Client {
237
239
  const callback = (error: undefined | Error, results: CreateAccountsError[]) => {
238
240
  if (error) {
239
241
  reject(error)
242
+ return
240
243
  }
241
244
  resolve(results)
242
245
  }
@@ -263,6 +266,7 @@ export function createClient (args: InitArgs): Client {
263
266
  const callback = (error: undefined | Error, results: CreateTransfersError[]) => {
264
267
  if (error) {
265
268
  reject(error)
269
+ return
266
270
  }
267
271
  resolve(results)
268
272
  }
@@ -289,6 +293,7 @@ export function createClient (args: InitArgs): Client {
289
293
  const callback = (error: undefined | Error, results: CommitTransfersError[]) => {
290
294
  if (error) {
291
295
  reject(error)
296
+ return
292
297
  }
293
298
  resolve(results)
294
299
  }
@@ -306,6 +311,7 @@ export function createClient (args: InitArgs): Client {
306
311
  const callback = (error: undefined | Error, results: Account[]) => {
307
312
  if (error) {
308
313
  reject(error)
314
+ return
309
315
  }
310
316
  resolve(results)
311
317
  }
@@ -318,6 +324,24 @@ export function createClient (args: InitArgs): Client {
318
324
  })
319
325
  }
320
326
 
327
+ const lookupTransfers = async (batch: TransferID[]): Promise<Transfer[]> => {
328
+ return new Promise((resolve, reject) => {
329
+ const callback = (error: undefined | Error, results: Transfer[]) => {
330
+ if (error) {
331
+ reject(error)
332
+ return
333
+ }
334
+ resolve(results)
335
+ }
336
+
337
+ try {
338
+ binding.request(context, Operation.TRANSFER_LOOKUP, batch, callback)
339
+ } catch (error) {
340
+ reject(error)
341
+ }
342
+ })
343
+ }
344
+
321
345
  const destroy = (): void => {
322
346
  binding.deinit(context)
323
347
  if (_interval){
@@ -331,6 +355,7 @@ export function createClient (args: InitArgs): Client {
331
355
  createTransfers,
332
356
  commitTransfers,
333
357
  lookupAccounts,
358
+ lookupTransfers,
334
359
  request,
335
360
  rawRequest,
336
361
  destroy
package/src/node.zig CHANGED
@@ -45,7 +45,7 @@ export fn napi_register_module_v1(env: c.napi_env, exports: c.napi_value) c.napi
45
45
 
46
46
  const allocator = std.heap.c_allocator;
47
47
  var global = Globals.init(allocator, env) catch {
48
- std.log.emerg("Failed to initialise environment.\n", .{});
48
+ std.log.err("Failed to initialise environment.\n", .{});
49
49
  return null;
50
50
  };
51
51
  errdefer global.deinit();
@@ -57,7 +57,7 @@ export fn napi_register_module_v1(env: c.napi_env, exports: c.napi_value) c.napi
57
57
  // state.
58
58
  translate.set_instance_data(
59
59
  env,
60
- @ptrCast(*c_void, @alignCast(@alignOf(u8), global)),
60
+ @ptrCast(*anyopaque, @alignCast(@alignOf(u8), global)),
61
61
  Globals.destroy,
62
62
  ) catch {
63
63
  global.deinit();
@@ -68,11 +68,11 @@ export fn napi_register_module_v1(env: c.napi_env, exports: c.napi_value) c.napi
68
68
  }
69
69
 
70
70
  const Globals = struct {
71
- allocator: *std.mem.Allocator,
71
+ allocator: std.mem.Allocator,
72
72
  io: IO,
73
73
  napi_undefined: c.napi_value,
74
74
 
75
- pub fn init(allocator: *std.mem.Allocator, env: c.napi_env) !*Globals {
75
+ pub fn init(allocator: std.mem.Allocator, env: c.napi_env) !*Globals {
76
76
  const self = try allocator.create(Globals);
77
77
  errdefer allocator.destroy(self);
78
78
 
@@ -93,7 +93,7 @@ const Globals = struct {
93
93
  };
94
94
  errdefer self.io.deinit();
95
95
 
96
- if (c.napi_get_undefined(env, &self.napi_undefined) != .napi_ok) {
96
+ if (c.napi_get_undefined(env, &self.napi_undefined) != c.napi_ok) {
97
97
  return translate.throw(env, "Failed to capture the value of \"undefined\".");
98
98
  }
99
99
 
@@ -105,13 +105,16 @@ const Globals = struct {
105
105
  self.allocator.destroy(self);
106
106
  }
107
107
 
108
- pub fn destroy(env: c.napi_env, data: ?*c_void, hint: ?*c_void) callconv(.C) void {
108
+ pub fn destroy(env: c.napi_env, data: ?*anyopaque, hint: ?*anyopaque) callconv(.C) void {
109
+ _ = env;
110
+ _ = hint;
111
+
109
112
  const self = globalsCast(data.?);
110
113
  self.deinit();
111
114
  }
112
115
  };
113
116
 
114
- fn globalsCast(globals_raw: *c_void) *Globals {
117
+ fn globalsCast(globals_raw: *anyopaque) *Globals {
115
118
  return @ptrCast(*Globals, @alignCast(@alignOf(Globals), globals_raw));
116
119
  }
117
120
 
@@ -123,7 +126,7 @@ const Context = struct {
123
126
 
124
127
  fn create(
125
128
  env: c.napi_env,
126
- allocator: *std.mem.Allocator,
129
+ allocator: std.mem.Allocator,
127
130
  io: *IO,
128
131
  cluster: u32,
129
132
  addresses_raw: []const u8,
@@ -163,7 +166,7 @@ const Context = struct {
163
166
  }
164
167
  };
165
168
 
166
- fn contextCast(context_raw: *c_void) !*Context {
169
+ fn contextCast(context_raw: *anyopaque) !*Context {
167
170
  return @ptrCast(*Context, @alignCast(@alignOf(Context), context_raw));
168
171
  }
169
172
 
@@ -213,7 +216,7 @@ fn decode_from_object(comptime T: type, env: c.napi_env, object: c.napi_value) !
213
216
  .credits_accepted = try translate.u64_from_object(env, object, "credits_accepted"),
214
217
  .timestamp = try validate_timestamp(env, object),
215
218
  },
216
- u128 => try translate.u128_from_value(env, object, "Account lookup"),
219
+ u128 => try translate.u128_from_value(env, object, "lookup"),
217
220
  else => unreachable,
218
221
  };
219
222
  }
@@ -229,6 +232,7 @@ pub fn decode_events(
229
232
  .create_transfers => try decode_events_from_array(env, array, Transfer, output),
230
233
  .commit_transfers => try decode_events_from_array(env, array, Commit, output),
231
234
  .lookup_accounts => try decode_events_from_array(env, array, u128, output),
235
+ .lookup_transfers => try decode_events_from_array(env, array, u128, output),
232
236
  else => unreachable,
233
237
  };
234
238
  }
@@ -307,7 +311,7 @@ fn encode_napi_results_array(
307
311
  );
308
312
  }
309
313
  },
310
- else => {
314
+ Account => {
311
315
  var i: u32 = 0;
312
316
  while (i < results.len) : (i += 1) {
313
317
  const result = results[i];
@@ -413,6 +417,105 @@ fn encode_napi_results_array(
413
417
  );
414
418
  }
415
419
  },
420
+ Transfer => {
421
+ var i: u32 = 0;
422
+ while (i < results.len) : (i += 1) {
423
+ const result = results[i];
424
+ const napi_object = try translate.create_object(
425
+ env,
426
+ "Failed to create transfer lookup result object.",
427
+ );
428
+
429
+ try translate.u128_into_object(
430
+ env,
431
+ napi_object,
432
+ "id",
433
+ result.id,
434
+ "Failed to set property \"id\" of transfer lookup result.",
435
+ );
436
+
437
+ try translate.u128_into_object(
438
+ env,
439
+ napi_object,
440
+ "debit_account_id",
441
+ result.debit_account_id,
442
+ "Failed to set property \"debit_account_id\" of transfer lookup result.",
443
+ );
444
+
445
+ try translate.u128_into_object(
446
+ env,
447
+ napi_object,
448
+ "credit_account_id",
449
+ result.credit_account_id,
450
+ "Failed to set property \"credit_account_id\" of transfer lookup result.",
451
+ );
452
+
453
+ try translate.u128_into_object(
454
+ env,
455
+ napi_object,
456
+ "user_data",
457
+ result.user_data,
458
+ "Failed to set property \"user_data\" of transfer lookup result.",
459
+ );
460
+
461
+ try translate.byte_slice_into_object(
462
+ env,
463
+ napi_object,
464
+ "reserved",
465
+ &result.reserved,
466
+ "Failed to set property \"reserved\" of transfer lookup result.",
467
+ );
468
+
469
+ try translate.u64_into_object(
470
+ env,
471
+ napi_object,
472
+ "timeout",
473
+ result.timeout,
474
+ "Failed to set property \"timeout\" of transfer lookup result.",
475
+ );
476
+
477
+ try translate.u32_into_object(
478
+ env,
479
+ napi_object,
480
+ "code",
481
+ @intCast(u32, result.code),
482
+ "Failed to set property \"code\" of transfer lookup result.",
483
+ );
484
+
485
+ try translate.u32_into_object(
486
+ env,
487
+ napi_object,
488
+ "flags",
489
+ @bitCast(u32, result.flags),
490
+ "Failed to set property \"flags\" of transfer lookup result.",
491
+ );
492
+
493
+ try translate.u64_into_object(
494
+ env,
495
+ napi_object,
496
+ "amount",
497
+ result.amount,
498
+ "Failed to set property \"amount\" of transfer lookup result.",
499
+ );
500
+
501
+ try translate.u64_into_object(
502
+ env,
503
+ napi_object,
504
+ "timestamp",
505
+ result.timestamp,
506
+ "Failed to set property \"timestamp\" of transfer lookup result.",
507
+ );
508
+
509
+ try translate.set_array_element(
510
+ env,
511
+ napi_array,
512
+ i,
513
+ napi_object,
514
+ "Failed to set element in results array.",
515
+ );
516
+ }
517
+ },
518
+ else => unreachable,
416
519
  }
417
520
 
418
521
  return napi_array;
@@ -422,7 +525,7 @@ fn encode_napi_results_array(
422
525
  fn init(env: c.napi_env, info: c.napi_callback_info) callconv(.C) c.napi_value {
423
526
  var argc: usize = 1;
424
527
  var argv: [1]c.napi_value = undefined;
425
- if (c.napi_get_cb_info(env, info, &argc, &argv, null, null) != .napi_ok) {
528
+ if (c.napi_get_cb_info(env, info, &argc, &argv, null, null) != c.napi_ok) {
426
529
  translate.throw(env, "Failed to get args.") catch return null;
427
530
  }
428
531
  if (argc != 1) translate.throw(
@@ -455,7 +558,7 @@ fn init(env: c.napi_env, info: c.napi_callback_info) callconv(.C) c.napi_value {
455
558
  fn request(env: c.napi_env, info: c.napi_callback_info) callconv(.C) c.napi_value {
456
559
  var argc: usize = 4;
457
560
  var argv: [4]c.napi_value = undefined;
458
- if (c.napi_get_cb_info(env, info, &argc, &argv, null, null) != .napi_ok) {
561
+ if (c.napi_get_cb_info(env, info, &argc, &argv, null, null) != c.napi_ok) {
459
562
  translate.throw(env, "Failed to get args.") catch return null;
460
563
  }
461
564
 
@@ -509,7 +612,7 @@ fn request(env: c.napi_env, info: c.napi_callback_info) callconv(.C) c.napi_valu
509
612
  fn raw_request(env: c.napi_env, info: c.napi_callback_info) callconv(.C) c.napi_value {
510
613
  var argc: usize = 4;
511
614
  var argv: [4]c.napi_value = undefined;
512
- if (c.napi_get_cb_info(env, info, &argc, &argv, null, null) != .napi_ok) {
615
+ if (c.napi_get_cb_info(env, info, &argc, &argv, null, null) != c.napi_ok) {
513
616
  translate.throw(env, "Failed to get args.") catch return null;
514
617
  }
515
618
 
@@ -610,6 +713,7 @@ fn on_result(user_data: u128, operation: Operation, results: Client.Error![]cons
610
713
  value,
611
714
  ) catch return,
612
715
  .lookup_accounts => encode_napi_results_array(Account, env, value) catch return,
716
+ .lookup_transfers => encode_napi_results_array(Transfer, env, value) catch return,
613
717
  };
614
718
 
615
719
  argv[0] = globals.napi_undefined;
@@ -629,11 +733,10 @@ fn on_result(user_data: u128, operation: Operation, results: Client.Error![]cons
629
733
  fn tick(env: c.napi_env, info: c.napi_callback_info) callconv(.C) c.napi_value {
630
734
  var argc: usize = 1;
631
735
  var argv: [1]c.napi_value = undefined;
632
- if (c.napi_get_cb_info(env, info, &argc, &argv, null, null) != .napi_ok) {
736
+ if (c.napi_get_cb_info(env, info, &argc, &argv, null, null) != c.napi_ok) {
633
737
  translate.throw(env, "Failed to get args.") catch return null;
634
738
  }
635
739
 
636
- const allocator = std.heap.c_allocator;
637
740
  if (argc != 1) translate.throw(
638
741
  env,
639
742
  "Function tick() requires 1 argument exactly.",
@@ -659,7 +762,7 @@ fn tick(env: c.napi_env, info: c.napi_callback_info) callconv(.C) c.napi_value {
659
762
  fn deinit(env: c.napi_env, info: c.napi_callback_info) callconv(.C) c.napi_value {
660
763
  var argc: usize = 1;
661
764
  var argv: [1]c.napi_value = undefined;
662
- if (c.napi_get_cb_info(env, info, &argc, &argv, null, null) != .napi_ok) {
765
+ if (c.napi_get_cb_info(env, info, &argc, &argv, null, null) != c.napi_ok) {
663
766
  translate.throw(env, "Failed to get args.") catch return null;
664
767
  }
665
768
 
package/src/test.ts CHANGED
@@ -176,6 +176,20 @@ test('can create a two-phase transfer', async (): Promise<void> => {
176
176
  assert.strictEqual(accounts[1].credits_reserved, 0n)
177
177
  assert.strictEqual(accounts[1].debits_accepted, 100n)
178
178
  assert.strictEqual(accounts[1].debits_reserved, 50n)
179
+
180
+ // Lookup the transfer
181
+ const transfers = await client.lookupTransfers([transfer.id])
182
+ assert.strictEqual(transfers.length, 1)
183
+ assert.strictEqual(transfers[0].id, 1n)
184
+ assert.strictEqual(transfers[0].debit_account_id, accountB.id)
185
+ assert.strictEqual(transfers[0].credit_account_id, accountA.id)
186
+ assert.strictEqual(transfers[0].user_data, 0n)
187
+ assert.notStrictEqual(transfers[0].reserved, Zeroed32Bytes)
188
+ assert.strictEqual(transfers[0].timeout > 0, true)
189
+ assert.strictEqual(transfers[0].code, 1)
190
+ assert.strictEqual(transfers[0].flags, 2)
191
+ assert.strictEqual(transfers[0].amount, 50n)
192
+ assert.strictEqual(transfers[0].timestamp > 0, true)
179
193
  })
180
194
 
181
195
  test('can commit a two-phase transfer', async (): Promise<void> => {
@@ -1,6 +1,6 @@
1
1
  #!/bin/bash
2
2
  set -e
3
- scripts/install_zig.sh 0.8.0
3
+ scripts/install_zig.sh
4
4
  echo "Building TigerBeetle..."
5
5
  zig/zig build -Dcpu=baseline -Drelease-safe
6
6
  mv zig-out/bin/tigerbeetle .
@@ -0,0 +1,109 @@
1
+ @echo off
2
+
3
+ set ZIG_RELEASE_DEFAULT=0.9.0
4
+
5
+ :: Determine the Zig build:
6
+ if "%~1"=="" (
7
+ set ZIG_RELEASE=%ZIG_RELEASE_DEFAULT%
8
+ ) else if "%~1"=="latest" (
9
+ set ZIG_RELEASE=builds
10
+ ) else (
11
+ set ZIG_RELEASE=%~1
12
+ )
13
+
14
+ :: Checks format of release version.
15
+ echo.%ZIG_RELEASE% | findstr /b /r /c:"builds" /c:"^[0-9][0-9]*.[0-9][0-9]*.[0-9][0-9]*">nul || (echo.Unexpected release format. && exit 1)
16
+
17
+ set ZIG_OS=windows
18
+ set ZIG_ARCH=x86_64
19
+
20
+ set ZIG_TARGET=zig-%ZIG_OS%-%ZIG_ARCH%
21
+
22
+ :: Determine the build, split the JSON line on whitespace and extract the 2nd field:
23
+ for /f "tokens=2" %%a in ('curl --silent https://ziglang.org/download/index.json ^| findstr %ZIG_TARGET% ^| findstr %ZIG_RELEASE%' ) do (
24
+ set ZIG_URL=%%a
25
+ )
26
+
27
+ :: Then remove quotes and commas:
28
+ for /f %%b in ("%ZIG_URL:,=%") do (
29
+ set ZIG_URL=%%~b
30
+ )
31
+
32
+ :: Checks the ZIG_URL variable follows the expected format.
33
+ echo.%ZIG_URL% | findstr /b /r /c:"https://ziglang.org/builds/" /c:"https://ziglang.org/download/%ZIG_RELEASE%">nul || (echo.Unexpected release URL format. && exit 1)
34
+
35
+ if "%ZIG_RELEASE%"=="builds" (
36
+ echo Installing Zig latest build...
37
+ ) else (
38
+ echo Installing Zig %ZIG_RELEASE% release build...
39
+ )
40
+
41
+ :: Using variable modifiers to determine the directory and filename from the URL:
42
+ :: %~ni Expands %i to a file name only and %~xi Expands %i to a file name extension only.
43
+ for /f %%i in ("%ZIG_URL%") do (
44
+ set ZIG_DIRECTORY=%%~ni
45
+ set ZIG_TARBALL=%%~nxi
46
+ )
47
+
48
+ :: Checks the ZIG_DIRECTORY variable follows the expected format.
49
+ echo.%ZIG_DIRECTORY% | findstr /b /r /c:"zig-win64-" /c:"zig-windows-x86_64-">nul || (echo.Unexpected zip directory name format. && exit 1)
50
+
51
+ :: Making sure we download to the same output document, without wget adding "-1" etc. if the file was previously partially downloaded:
52
+ if exist %ZIG_TARBALL% (
53
+ del /q %ZIG_TARBALL%
54
+ if exist %ZIG_TARBALL% (
55
+ echo Failed to delete %ZIG_TARBALL%.
56
+ exit 1
57
+ )
58
+ )
59
+
60
+ echo Downloading %ZIG_URL%...
61
+ curl --silent --progress-bar --output %ZIG_TARBALL% %ZIG_URL%
62
+ if not exist %ZIG_TARBALL% (
63
+ echo Failed to download Zig zip file.
64
+ exit 1
65
+ )
66
+
67
+ :: Replace any existing Zig installation so that we can install or upgrade:
68
+ echo Removing any existing 'zig' and %ZIG_DIRECTORY% folders before extracting.
69
+ if exist zig\ (
70
+ rd /s /q zig\
71
+ :: Ensure the directory has been deleted.
72
+ if exist zig\ (
73
+ echo The ‘zig’ directory could not be deleted.
74
+ exit 1
75
+ )
76
+ )
77
+
78
+ if exist %ZIG_DIRECTORY%\ (
79
+ rd /s /q %ZIG_DIRECTORY%
80
+ :: Ensure the directory has been deleted.
81
+ if exist %ZIG_DIRECTORY% (
82
+ echo The %ZIG_DIRECTORY% directory could not be deleted.
83
+ exit 1
84
+ )
85
+ )
86
+
87
+ :: Extract and then remove the downloaded tarball:
88
+ echo Extracting %ZIG_TARBALL%...
89
+ powershell -Command "Expand-Archive %ZIG_TARBALL% -DestinationPath ."
90
+ if not exist %ZIG_TARBALL% (
91
+ echo Failed to extract zip file.
92
+ exit 1
93
+ )
94
+
95
+ echo Installing %ZIG_DIRECTORY% to 'zig' in current working directory...
96
+ ren %ZIG_DIRECTORY% zig
97
+ if exist %ZIG_DIRECTORY% (
98
+ echo Failed to rename %ZIG_DIRECTORY% to zig.
99
+ exit 1
100
+ )
101
+
102
+ :: Removes the zip file
103
+ del /q %ZIG_TARBALL%
104
+ if exist %ZIG_TARBALL% (
105
+ echo Failed to delete %ZIG_TARBALL% file.
106
+ exit 1
107
+ )
108
+
109
+ echo "Congratulations, you have successfully installed Zig version %ZIG_RELEASE%. Enjoy!"
@@ -1,9 +1,11 @@
1
1
  #!/bin/bash
2
2
  set -e
3
3
 
4
- # Default to the 0.8.1 build, or allow the latest dev build, or an explicit release version:
4
+ ZIG_RELEASE_DEFAULT="0.9.0"
5
+
6
+ # Default to the release build, or allow the latest dev build, or an explicit release version:
5
7
  if [ -z "$1" ]; then
6
- ZIG_RELEASE="0.8.1"
8
+ ZIG_RELEASE=$ZIG_RELEASE_DEFAULT
7
9
  elif [ "$1" == "latest" ]; then
8
10
  ZIG_RELEASE="builds"
9
11
  else
@@ -23,7 +23,7 @@ var file_stats = std.ArrayListUnmanaged(Stats){};
23
23
  var seen = std.AutoArrayHashMapUnmanaged(fs.File.INode, void){};
24
24
 
25
25
  var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
26
- const gpa = &general_purpose_allocator.allocator;
26
+ const gpa = general_purpose_allocator.allocator();
27
27
 
28
28
  pub fn main() !void {
29
29
  const argv = std.os.argv;
@@ -119,7 +119,13 @@ fn lint_file(file_path: []const u8, dir: fs.Dir, sub_path: []const u8) LintError
119
119
  // Add to set after no longer possible to get error.IsDir.
120
120
  if (try seen.fetchPut(gpa, stat.inode, {})) |_| return;
121
121
 
122
- const source = try source_file.readToEndAlloc(gpa, math.maxInt(usize));
122
+ const source = try source_file.readToEndAllocOptions(
123
+ gpa,
124
+ math.maxInt(usize),
125
+ null,
126
+ @alignOf(u8),
127
+ 0,
128
+ );
123
129
  try check_line_length(source, file_path);
124
130
 
125
131
  var tree = try std.zig.parse(gpa, source);
@@ -0,0 +1,48 @@
1
+ :: Installs Zig if needed and runs the VOPR
2
+ @echo off
3
+
4
+ :: Install Zig if a zig folder does not already exist:
5
+ if not exist zig\ (
6
+ :: Installs the latest version of Zig
7
+ call scripts\install_zig.bat
8
+ :: Checks that the Zig folder now exists
9
+ if not exist zig\ (
10
+ echo The Zig installation failed.
11
+ exit 1
12
+ )
13
+ echo Running the TigerBeetle VOPR for the first time...
14
+ echo Visit https://www.tigerbeetle.com
15
+ )
16
+
17
+ :: If a seed is provided as an argument then replay the seed, otherwise test 1,000 seeds:
18
+ if not "%~1"=="" (
19
+ :: Build in fast ReleaseSafe mode if required, useful where you don't need debug logging:
20
+ if "%~2"=="-OReleaseSafe" (
21
+ echo Replaying seed %~1 in ReleaseSafe mode...
22
+ call zig\zig run src\simulator.zig -OReleaseSafe -- %~1
23
+ if not %ERRORLEVEL%==0 (
24
+ echo Cannot replay the %~1 seed using the VOPR.
25
+ exit 1
26
+ )
27
+ ) else (
28
+ echo Replaying seed %~1 in Debug mode with full debug logging enabled...
29
+ call zig\zig run src\simulator.zig -ODebug -- %~1
30
+ if not %ERRORLEVEL%==0 (
31
+ echo Cannot run the VOPR.
32
+ exit 1
33
+ )
34
+ )
35
+ ) else (
36
+ call zig\zig build-exe src\simulator.zig -OReleaseSafe
37
+ if not %ERRORLEVEL%==0 (
38
+ echo Cannot run the VOPR.
39
+ exit 1
40
+ )
41
+ for %%i in (1,1,1000) do (
42
+ call simulator
43
+ if not %ERRORLEVEL%==0 (
44
+ echo Cannot run a seed using the VOPR.
45
+ exit 1
46
+ )
47
+ )
48
+ )
@@ -1,4 +1,5 @@
1
1
  const std = @import("std");
2
+ const builtin = @import("builtin");
2
3
  const assert = std.debug.assert;
3
4
  const config = @import("config.zig");
4
5
 
@@ -30,7 +31,7 @@ const BATCHES: f32 = MAX_TRANSFERS / BATCH_SIZE;
30
31
  const TOTAL_BATCHES = @ceil(BATCHES);
31
32
 
32
33
  const log = std.log;
33
- pub const log_level: std.log.Level = .notice;
34
+ pub const log_level: std.log.Level = .info;
34
35
 
35
36
  var accounts = [_]Account{
36
37
  Account{
@@ -65,13 +66,14 @@ pub fn main() !void {
65
66
  const stdout = std.io.getStdOut().writer();
66
67
  const stderr = std.io.getStdErr().writer();
67
68
 
68
- if (std.builtin.mode != .ReleaseSafe and std.builtin.mode != .ReleaseFast) {
69
+ if (builtin.mode != .ReleaseSafe and builtin.mode != .ReleaseFast) {
69
70
  try stderr.print("Benchmark must be built as ReleaseSafe for minimum performance.\n", .{});
70
71
  }
71
72
 
72
73
  var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
73
74
  defer arena.deinit();
74
- const allocator = &arena.allocator;
75
+
76
+ const allocator = arena.allocator();
75
77
 
76
78
  const client_id = std.crypto.random.int(u128);
77
79
  const cluster_id: u32 = 0;
@@ -90,7 +92,7 @@ pub fn main() !void {
90
92
  message_bus.set_on_message(*Client, &client, Client.on_message);
91
93
 
92
94
  // Pre-allocate a million transfers:
93
- var transfers = try arena.allocator.alloc(Transfer, MAX_TRANSFERS);
95
+ const transfers = try arena.allocator().alloc(Transfer, MAX_TRANSFERS);
94
96
  for (transfers) |*transfer, index| {
95
97
  transfer.* = .{
96
98
  .id = index,
@@ -106,7 +108,7 @@ pub fn main() !void {
106
108
  }
107
109
 
108
110
  // Pre-allocate a million commits:
109
- var commits: ?[]Commit = if (IS_TWO_PHASE_COMMIT) try arena.allocator.alloc(Commit, MAX_TRANSFERS) else null;
111
+ const commits: ?[]Commit = if (IS_TWO_PHASE_COMMIT) try arena.allocator().alloc(Commit, MAX_TRANSFERS) else null;
110
112
  if (commits) |all_commits| {
111
113
  for (all_commits) |*commit, index| {
112
114
  commit.* = .{
@@ -223,7 +225,7 @@ const TimedQueue = struct {
223
225
 
224
226
  const now = std.time.milliTimestamp();
225
227
  self.start = now;
226
- if (self.batches.peek_ptr()) |starting_batch| {
228
+ if (self.batches.head_ptr()) |starting_batch| {
227
229
  log.debug("sending first batch...", .{});
228
230
  self.batch_start = now;
229
231
  var message = self.client.get_message() orelse {
@@ -254,7 +256,7 @@ const TimedQueue = struct {
254
256
  pub fn lap(user_data: u128, operation: Operation, results: Client.Error![]const u8) void {
255
257
  const now = std.time.milliTimestamp();
256
258
  const value = results catch |err| {
257
- log.emerg("Client returned error={o}", .{@errorName(err)});
259
+ log.err("Client returned error={o}", .{@errorName(err)});
258
260
  @panic("Client returned error during benchmarking.");
259
261
  };
260
262
 
@@ -285,7 +287,7 @@ const TimedQueue = struct {
285
287
  else => unreachable,
286
288
  }
287
289
 
288
- if (self.batches.peek_ptr()) |next_batch| {
290
+ if (self.batches.head_ptr()) |next_batch| {
289
291
  var message = self.client.get_message() orelse {
290
292
  @panic("Client message pool has been exhausted.");
291
293
  };