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,156 +0,0 @@
1
- const std = @import("std");
2
- const builtin = @import("builtin");
3
- const assert = std.debug.assert;
4
- const mem = std.mem;
5
-
6
- const constants = @import("constants.zig");
7
-
8
- const vsr = @import("vsr.zig");
9
- const Header = vsr.Header;
10
-
11
- comptime {
12
- // message_size_max must be a multiple of sector_size for Direct I/O
13
- assert(constants.message_size_max % constants.sector_size == 0);
14
- }
15
-
16
- /// The number of full-sized messages allocated at initialization by the replica message pool.
17
- /// There must be enough messages to ensure that the replica can always progress, to avoid deadlock.
18
- pub const messages_max_replica = messages_max: {
19
- var sum: usize = 0;
20
-
21
- sum += constants.journal_iops_read_max; // Journal reads
22
- sum += constants.journal_iops_write_max; // Journal writes
23
- sum += constants.clients_max; // SuperBlock.client_table
24
- sum += 1; // Replica.loopback_queue
25
- sum += constants.pipeline_prepare_queue_max; // Replica.Pipeline{Queue|Cache}
26
- sum += constants.pipeline_request_queue_max; // Replica.Pipeline{Queue|Cache}
27
- sum += 1; // Replica.commit_prepare
28
- // Replica.do_view_change_from_all_replicas quorum:
29
- // Replica.recovery_response_quorum is only used for recovery and does not increase the limit.
30
- // All other quorums are bitsets.
31
- sum += constants.replicas_max;
32
- sum += constants.connections_max; // Connection.recv_message
33
- sum += constants.connections_max * constants.connection_send_queue_max_replica; // Connection.send_queue
34
- sum += 1; // Handle bursts (e.g. Connection.parse_message)
35
- // Handle Replica.commit_op's reply:
36
- // (This is separate from the burst +1 because they may occur concurrently).
37
- sum += 1;
38
-
39
- break :messages_max sum;
40
- };
41
-
42
- /// The number of full-sized messages allocated at initialization by the client message pool.
43
- pub const messages_max_client = messages_max: {
44
- var sum: usize = 0;
45
-
46
- sum += constants.replicas_max; // Connection.recv_message
47
- sum += constants.replicas_max * constants.connection_send_queue_max_client; // Connection.send_queue
48
- sum += constants.client_request_queue_max; // Client.request_queue
49
- // Handle bursts (e.g. Connection.parse_message, or sending a ping when the send queue is full).
50
- sum += 1;
51
-
52
- break :messages_max sum;
53
- };
54
-
55
- comptime {
56
- // These conditions are necessary (but not sufficient) to prevent deadlocks.
57
- assert(messages_max_replica > constants.replicas_max);
58
- assert(messages_max_client > constants.client_request_queue_max);
59
- }
60
-
61
- /// A pool of reference-counted Messages, memory for which is allocated only once during
62
- /// initialization and reused thereafter. The messages_max values determine the size of this pool.
63
- pub const MessagePool = struct {
64
- pub const Message = struct {
65
- // TODO: replace this with a header() function to save memory
66
- header: *Header,
67
- buffer: *align(constants.sector_size) [constants.message_size_max]u8,
68
- references: u32 = 0,
69
- next: ?*Message,
70
-
71
- /// Increment the reference count of the message and return the same pointer passed.
72
- pub fn ref(message: *Message) *Message {
73
- message.references += 1;
74
- return message;
75
- }
76
-
77
- pub fn body(message: *const Message) []align(@sizeOf(Header)) u8 {
78
- return message.buffer[@sizeOf(Header)..message.header.size];
79
- }
80
- };
81
-
82
- /// List of currently unused messages.
83
- free_list: ?*Message,
84
-
85
- messages_max: usize,
86
-
87
- pub fn init(allocator: mem.Allocator, process_type: vsr.ProcessType) error{OutOfMemory}!MessagePool {
88
- return MessagePool.init_capacity(allocator, switch (process_type) {
89
- .replica => messages_max_replica,
90
- .client => messages_max_client,
91
- });
92
- }
93
-
94
- pub fn init_capacity(allocator: mem.Allocator, messages_max: usize) error{OutOfMemory}!MessagePool {
95
- var pool: MessagePool = .{
96
- .free_list = null,
97
- .messages_max = messages_max,
98
- };
99
- {
100
- var i: usize = 0;
101
- while (i < messages_max) : (i += 1) {
102
- const buffer = try allocator.allocAdvanced(
103
- u8,
104
- constants.sector_size,
105
- constants.message_size_max,
106
- .exact,
107
- );
108
- const message = try allocator.create(Message);
109
- message.* = .{
110
- .header = mem.bytesAsValue(Header, buffer[0..@sizeOf(Header)]),
111
- .buffer = buffer[0..constants.message_size_max],
112
- .next = pool.free_list,
113
- };
114
- pool.free_list = message;
115
- }
116
- }
117
-
118
- return pool;
119
- }
120
-
121
- /// Frees all messages that were unused or returned to the pool via unref().
122
- pub fn deinit(pool: *MessagePool, allocator: mem.Allocator) void {
123
- var free_count: usize = 0;
124
- while (pool.free_list) |message| {
125
- pool.free_list = message.next;
126
- allocator.free(@as([]const u8, message.buffer));
127
- allocator.destroy(message);
128
- free_count += 1;
129
- }
130
- // If the MessagePool is being deinitialized, all messages should have already been
131
- // released to the pool.
132
- assert(free_count == pool.messages_max);
133
- }
134
-
135
- /// Get an unused message with a buffer of constants.message_size_max.
136
- /// The returned message has exactly one reference.
137
- pub fn get_message(pool: *MessagePool) *Message {
138
- const message = pool.free_list.?;
139
- pool.free_list = message.next;
140
- message.next = null;
141
- assert(message.references == 0);
142
-
143
- message.references = 1;
144
- return message;
145
- }
146
-
147
- /// Decrement the reference count of the message, possibly freeing it.
148
- pub fn unref(pool: *MessagePool, message: *Message) void {
149
- message.references -= 1;
150
- if (message.references == 0) {
151
- mem.set(u8, message.buffer, 0);
152
- message.next = pool.free_list;
153
- pool.free_list = message;
154
- }
155
- }
156
- };
@@ -1,399 +0,0 @@
1
- const std = @import("std");
2
- const assert = std.debug.assert;
3
- const math = std.math;
4
- const mem = std.mem;
5
-
6
- const stdx = @import("stdx.zig");
7
-
8
- /// A First In, First Out ring buffer holding at most `count_max` elements.
9
- pub fn RingBuffer(
10
- comptime T: type,
11
- comptime count_max_: usize,
12
- comptime buffer_type: enum { array, pointer },
13
- ) type {
14
- return struct {
15
- const Self = @This();
16
-
17
- pub const count_max = count_max_;
18
-
19
- buffer: switch (buffer_type) {
20
- .array => [count_max]T,
21
- .pointer => *[count_max]T,
22
- } = switch (buffer_type) {
23
- .array => undefined,
24
- .pointer => @compileError("init() must be used if buffer_type is .pointer!"),
25
- },
26
-
27
- /// The index of the slot with the first item, if any.
28
- index: usize = 0,
29
-
30
- /// The number of items in the buffer.
31
- count: usize = 0,
32
-
33
- pub usingnamespace switch (buffer_type) {
34
- .array => struct {},
35
- .pointer => struct {
36
- pub fn init(allocator: mem.Allocator) !Self {
37
- const buffer = try allocator.create([count_max]T);
38
- errdefer allocator.destroy(buffer);
39
- return Self{ .buffer = buffer };
40
- }
41
-
42
- pub fn deinit(self: *Self, allocator: mem.Allocator) void {
43
- allocator.destroy(self.buffer);
44
- }
45
- },
46
- };
47
-
48
- // TODO Add doc comments to these functions:
49
- pub inline fn head(self: Self) ?T {
50
- if (count_max == 0 or self.empty()) return null;
51
- return self.buffer[self.index];
52
- }
53
-
54
- pub inline fn head_ptr(self: *Self) ?*T {
55
- if (count_max == 0 or self.empty()) return null;
56
- return &self.buffer[self.index];
57
- }
58
-
59
- pub inline fn head_ptr_const(self: *const Self) ?*const T {
60
- if (count_max == 0 or self.empty()) return null;
61
- return &self.buffer[self.index];
62
- }
63
-
64
- pub inline fn tail(self: Self) ?T {
65
- if (count_max == 0 or self.empty()) return null;
66
- return self.buffer[(self.index + self.count - 1) % self.buffer.len];
67
- }
68
-
69
- pub inline fn tail_ptr(self: *Self) ?*T {
70
- if (count_max == 0 or self.empty()) return null;
71
- return &self.buffer[(self.index + self.count - 1) % self.buffer.len];
72
- }
73
-
74
- pub inline fn tail_ptr_const(self: *const Self) ?*const T {
75
- if (count_max == 0 or self.empty()) return null;
76
- return &self.buffer[(self.index + self.count - 1) % self.buffer.len];
77
- }
78
-
79
- pub inline fn get_ptr(self: *Self, index: usize) ?*T {
80
- if (count_max == 0) unreachable;
81
-
82
- if (index < self.count) {
83
- return &self.buffer[(self.index + index) % self.buffer.len];
84
- } else {
85
- assert(index < count_max);
86
- return null;
87
- }
88
- }
89
-
90
- pub inline fn next_tail(self: Self) ?T {
91
- if (count_max == 0 or self.full()) return null;
92
- return self.buffer[(self.index + self.count) % self.buffer.len];
93
- }
94
-
95
- pub inline fn next_tail_ptr(self: *Self) ?*T {
96
- if (count_max == 0 or self.full()) return null;
97
- return &self.buffer[(self.index + self.count) % self.buffer.len];
98
- }
99
-
100
- pub inline fn next_tail_ptr_const(self: *const Self) ?*const T {
101
- if (count_max == 0 or self.full()) return null;
102
- return &self.buffer[(self.index + self.count) % self.buffer.len];
103
- }
104
-
105
- pub inline fn advance_head(self: *Self) void {
106
- self.index += 1;
107
- self.index %= self.buffer.len;
108
- self.count -= 1;
109
- }
110
-
111
- pub inline fn advance_tail(self: *Self) void {
112
- assert(self.count < self.buffer.len);
113
- self.count += 1;
114
- }
115
-
116
- pub inline fn retreat_tail(self: *Self) void {
117
- self.count -= 1;
118
- }
119
-
120
- /// Returns whether the ring buffer is completely full.
121
- pub inline fn full(self: Self) bool {
122
- return self.count == self.buffer.len;
123
- }
124
-
125
- /// Returns whether the ring buffer is completely empty.
126
- pub inline fn empty(self: Self) bool {
127
- return self.count == 0;
128
- }
129
-
130
- // Higher level, less error-prone wrappers:
131
-
132
- /// Add an element to the RingBuffer. Returns an error if the buffer
133
- /// is already full and the element could not be added.
134
- pub fn push(self: *Self, item: T) error{NoSpaceLeft}!void {
135
- const ptr = self.next_tail_ptr() orelse return error.NoSpaceLeft;
136
- ptr.* = item;
137
- self.advance_tail();
138
- }
139
-
140
- /// Add an element to a RingBuffer, and assert that the capacity is sufficient.
141
- pub fn push_assume_capacity(self: *Self, item: T) void {
142
- self.push(item) catch |err| switch (err) {
143
- error.NoSpaceLeft => unreachable,
144
- };
145
- }
146
-
147
- pub fn push_slice(self: *Self, items: []const T) error{NoSpaceLeft}!void {
148
- if (count_max == 0) return error.NoSpaceLeft;
149
- if (self.count + items.len > self.buffer.len) return error.NoSpaceLeft;
150
-
151
- const pre_wrap_start = (self.index + self.count) % self.buffer.len;
152
- const pre_wrap_count = math.min(items.len, self.buffer.len - pre_wrap_start);
153
- const post_wrap_count = items.len - pre_wrap_count;
154
-
155
- stdx.copy_disjoint(.inexact, T, self.buffer[pre_wrap_start..], items[0..pre_wrap_count]);
156
- stdx.copy_disjoint(.exact, T, self.buffer[0..post_wrap_count], items[pre_wrap_count..]);
157
-
158
- self.count += items.len;
159
- }
160
-
161
- /// Remove and return the next item, if any.
162
- pub fn pop(self: *Self) ?T {
163
- const result = self.head() orelse return null;
164
- self.advance_head();
165
- return result;
166
- }
167
-
168
- /// Remove and return the last item, if any.
169
- pub fn pop_tail(self: *Self) ?T {
170
- const result = self.tail() orelse return null;
171
- self.retreat_tail();
172
- return result;
173
- }
174
-
175
- pub const Iterator = struct {
176
- ring: *const Self,
177
- count: usize = 0,
178
-
179
- pub fn next(it: *Iterator) ?T {
180
- if (count_max == 0) return null;
181
- // TODO Use next_ptr() internally to avoid duplicating this code.
182
- assert(it.count <= it.ring.count);
183
- if (it.count == it.ring.count) return null;
184
- defer it.count += 1;
185
- return it.ring.buffer[(it.ring.index + it.count) % it.ring.buffer.len];
186
- }
187
-
188
- pub fn next_ptr(it: *Iterator) ?*const T {
189
- assert(it.count <= it.ring.count);
190
- if (count_max == 0) return null;
191
- if (it.count == it.ring.count) return null;
192
- defer it.count += 1;
193
- return &it.ring.buffer[(it.ring.index + it.count) % it.ring.buffer.len];
194
- }
195
- };
196
-
197
- /// Returns an iterator to iterate through all `count` items in the ring buffer.
198
- /// The iterator is invalidated if the ring buffer is advanced.
199
- pub fn iterator(self: *const Self) Iterator {
200
- return .{ .ring = self };
201
- }
202
-
203
- pub const IteratorMutable = struct {
204
- ring: *Self,
205
- count: usize = 0,
206
-
207
- pub fn next_ptr(it: *IteratorMutable) ?*T {
208
- assert(it.count <= it.ring.count);
209
- if (count_max == 0) return null;
210
- if (it.count == it.ring.count) return null;
211
- defer it.count += 1;
212
- return &it.ring.buffer[(it.ring.index + it.count) % it.ring.buffer.len];
213
- }
214
- };
215
-
216
- // TODO Add to tests.
217
- pub fn iterator_mutable(self: *Self) IteratorMutable {
218
- return .{ .ring = self };
219
- }
220
- };
221
- }
222
-
223
- const testing = std.testing;
224
-
225
- fn test_iterator(comptime T: type, ring: *T, values: []const u32) !void {
226
- const ring_index = ring.index;
227
-
228
- var loops: usize = 0;
229
- while (loops < 2) : (loops += 1) {
230
- var iterator = ring.iterator();
231
- var index: usize = 0;
232
- while (iterator.next()) |item| {
233
- try testing.expectEqual(values[index], item);
234
- index += 1;
235
- }
236
- try testing.expectEqual(values.len, index);
237
- }
238
-
239
- try testing.expectEqual(ring_index, ring.index);
240
- }
241
-
242
- fn test_low_level_interface(comptime Ring: type, ring: *Ring) !void {
243
- try ring.push_slice(&[_]u32{});
244
- try test_iterator(Ring, ring, &[_]u32{});
245
-
246
- try testing.expectError(error.NoSpaceLeft, ring.push_slice(&[_]u32{ 1, 2, 3 }));
247
-
248
- try ring.push_slice(&[_]u32{1});
249
- try testing.expectEqual(@as(?u32, 1), ring.tail());
250
- try testing.expectEqual(@as(u32, 1), ring.tail_ptr().?.*);
251
- ring.advance_head();
252
-
253
- try testing.expectEqual(@as(usize, 1), ring.index);
254
- try testing.expectEqual(@as(usize, 0), ring.count);
255
- try ring.push_slice(&[_]u32{ 1, 2 });
256
- try test_iterator(Ring, ring, &[_]u32{ 1, 2 });
257
- ring.advance_head();
258
- ring.advance_head();
259
-
260
- try testing.expectEqual(@as(usize, 1), ring.index);
261
- try testing.expectEqual(@as(usize, 0), ring.count);
262
- try ring.push_slice(&[_]u32{1});
263
- try testing.expectEqual(@as(?u32, 1), ring.tail());
264
- try testing.expectEqual(@as(u32, 1), ring.tail_ptr().?.*);
265
- ring.advance_head();
266
-
267
- try testing.expectEqual(@as(?u32, null), ring.head());
268
- try testing.expectEqual(@as(?*u32, null), ring.head_ptr());
269
- try testing.expectEqual(@as(?u32, null), ring.tail());
270
- try testing.expectEqual(@as(?*u32, null), ring.tail_ptr());
271
-
272
- ring.next_tail_ptr().?.* = 0;
273
- ring.advance_tail();
274
- try testing.expectEqual(@as(?u32, 0), ring.tail());
275
- try testing.expectEqual(@as(u32, 0), ring.tail_ptr().?.*);
276
- try test_iterator(Ring, ring, &[_]u32{0});
277
-
278
- ring.next_tail_ptr().?.* = 1;
279
- ring.advance_tail();
280
- try testing.expectEqual(@as(?u32, 1), ring.tail());
281
- try testing.expectEqual(@as(u32, 1), ring.tail_ptr().?.*);
282
- try test_iterator(Ring, ring, &[_]u32{ 0, 1 });
283
-
284
- try testing.expectEqual(@as(?u32, null), ring.next_tail());
285
- try testing.expectEqual(@as(?*u32, null), ring.next_tail_ptr());
286
-
287
- try testing.expectEqual(@as(?u32, 0), ring.head());
288
- try testing.expectEqual(@as(u32, 0), ring.head_ptr().?.*);
289
- ring.advance_head();
290
- try test_iterator(Ring, ring, &[_]u32{1});
291
-
292
- ring.next_tail_ptr().?.* = 2;
293
- ring.advance_tail();
294
- try testing.expectEqual(@as(?u32, 2), ring.tail());
295
- try testing.expectEqual(@as(u32, 2), ring.tail_ptr().?.*);
296
- try test_iterator(Ring, ring, &[_]u32{ 1, 2 });
297
-
298
- ring.advance_head();
299
- try test_iterator(Ring, ring, &[_]u32{2});
300
-
301
- ring.next_tail_ptr().?.* = 3;
302
- ring.advance_tail();
303
- try testing.expectEqual(@as(?u32, 3), ring.tail());
304
- try testing.expectEqual(@as(u32, 3), ring.tail_ptr().?.*);
305
- try test_iterator(Ring, ring, &[_]u32{ 2, 3 });
306
-
307
- try testing.expectEqual(@as(?u32, 2), ring.head());
308
- try testing.expectEqual(@as(u32, 2), ring.head_ptr().?.*);
309
- ring.advance_head();
310
- try test_iterator(Ring, ring, &[_]u32{3});
311
-
312
- try testing.expectEqual(@as(?u32, 3), ring.head());
313
- try testing.expectEqual(@as(u32, 3), ring.head_ptr().?.*);
314
- ring.advance_head();
315
- try test_iterator(Ring, ring, &[_]u32{});
316
-
317
- try testing.expectEqual(@as(?u32, null), ring.head());
318
- try testing.expectEqual(@as(?*u32, null), ring.head_ptr());
319
- try testing.expectEqual(@as(?u32, null), ring.tail());
320
- try testing.expectEqual(@as(?*u32, null), ring.tail_ptr());
321
- }
322
-
323
- test "RingBuffer: low level interface" {
324
- const ArrayRing = RingBuffer(u32, 2, .array);
325
- var array_ring: ArrayRing = .{};
326
- try test_low_level_interface(ArrayRing, &array_ring);
327
-
328
- const PointerRing = RingBuffer(u32, 2, .pointer);
329
- var pointer_ring = try PointerRing.init(testing.allocator);
330
- defer pointer_ring.deinit(testing.allocator);
331
- try test_low_level_interface(PointerRing, &pointer_ring);
332
- }
333
-
334
- test "RingBuffer: push/pop high level interface" {
335
- var fifo = RingBuffer(u32, 3, .array){};
336
-
337
- try testing.expect(!fifo.full());
338
- try testing.expect(fifo.empty());
339
- try testing.expectEqual(@as(?*u32, null), fifo.get_ptr(0));
340
- try testing.expectEqual(@as(?*u32, null), fifo.get_ptr(1));
341
- try testing.expectEqual(@as(?*u32, null), fifo.get_ptr(2));
342
-
343
- try fifo.push(1);
344
- try testing.expectEqual(@as(?u32, 1), fifo.head());
345
- try testing.expectEqual(@as(u32, 1), fifo.get_ptr(0).?.*);
346
- try testing.expectEqual(@as(?*u32, null), fifo.get_ptr(1));
347
-
348
- try testing.expect(!fifo.full());
349
- try testing.expect(!fifo.empty());
350
-
351
- try fifo.push(2);
352
- try testing.expectEqual(@as(?u32, 1), fifo.head());
353
- try testing.expectEqual(@as(u32, 2), fifo.get_ptr(1).?.*);
354
-
355
- try fifo.push(3);
356
- try testing.expectError(error.NoSpaceLeft, fifo.push(4));
357
-
358
- try testing.expect(fifo.full());
359
- try testing.expect(!fifo.empty());
360
-
361
- try testing.expectEqual(@as(?u32, 1), fifo.head());
362
- try testing.expectEqual(@as(?u32, 1), fifo.pop());
363
- try testing.expectEqual(@as(u32, 2), fifo.get_ptr(0).?.*);
364
- try testing.expectEqual(@as(u32, 3), fifo.get_ptr(1).?.*);
365
- try testing.expectEqual(@as(?*u32, null), fifo.get_ptr(2));
366
-
367
- try testing.expect(!fifo.full());
368
- try testing.expect(!fifo.empty());
369
-
370
- try fifo.push(4);
371
-
372
- try testing.expectEqual(@as(?u32, 2), fifo.pop());
373
- try testing.expectEqual(@as(?u32, 3), fifo.pop());
374
- try testing.expectEqual(@as(?u32, 4), fifo.pop());
375
- try testing.expectEqual(@as(?u32, null), fifo.pop());
376
-
377
- try testing.expect(!fifo.full());
378
- try testing.expect(fifo.empty());
379
- }
380
-
381
- test "RingBuffer: pop_tail" {
382
- var lifo = RingBuffer(u32, 3, .array){};
383
- try lifo.push(1);
384
- try lifo.push(2);
385
- try lifo.push(3);
386
- try testing.expect(lifo.full());
387
-
388
- try testing.expectEqual(@as(?u32, 3), lifo.pop_tail());
389
- try testing.expectEqual(@as(?u32, 1), lifo.head());
390
- try testing.expectEqual(@as(?u32, 2), lifo.pop_tail());
391
- try testing.expectEqual(@as(?u32, 1), lifo.head());
392
- try testing.expectEqual(@as(?u32, 1), lifo.pop_tail());
393
- try testing.expectEqual(@as(?u32, null), lifo.pop_tail());
394
- try testing.expect(lifo.empty());
395
- }
396
-
397
- test "RingBuffer: count_max=0" {
398
- std.testing.refAllDecls(RingBuffer(u32, 0, .array));
399
- }