From c71dda70b2a49c92bf640b1e979c40c0043f1070 Mon Sep 17 00:00:00 2001 From: jLevere Date: Mon, 18 Nov 2024 14:15:15 -0500 Subject: [PATCH 1/2] added ring buff and some tests --- shared/main.zig | 143 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/shared/main.zig b/shared/main.zig index 4061e18..1800bd4 100644 --- a/shared/main.zig +++ b/shared/main.zig @@ -86,3 +86,146 @@ const MXCErrors = enum(c_int) { E_NOT_SUPPORTED = -17, E_FAIL = -255, }; + +pub fn RingBuffer(comptime T: type, comptime capacity: usize) type { + return struct { + const Self = @This(); + + buffer: [capacity]T, + head: usize = 0, + tail: usize = 0, + count: usize = 0, + + pub fn init() Self { + return Self{ + .buffer = undefined, + }; + } + + pub fn isEmpty(self: *Self) bool { + return self.count == 0; + } + + pub fn isFull(self: *Self) bool { + return self.count == capacity; + } + + pub fn push(self: *Self, item: T) !void { + if (self.isFull()) { + return error.BufferFull; + } + + self.buffer[self.tail] = item; + self.tail = @mod((self.tail + 1), capacity); + self.count += 1; + } + + pub fn pop(self: *Self) !T { + if (self.isEmpty()) { + return error.BufferEmpty; + } + + const item = self.buffer[self.head]; + self.head = @mod((self.head) + 1, capacity); + self.count -= 1; + return item; + } + + pub fn peek(self: *Self) !T { + if (self.isEmpty()) { + return error.BufferEmpty; + } + + return self.buffer[self.head]; + } + }; +} + +test "ring buf simple operations" { + var rb = RingBuffer(i32, 4).init(); + + try rb.push(1); + try rb.push(2); + try rb.push(3); + + try std.testing.expectEqual(@as(usize, 3), rb.count); + try std.testing.expectEqual(@as(i32, 1), try rb.pop()); + try std.testing.expectEqual(@as(i32, 2), try rb.pop()); + + try rb.push(4); + try rb.push(5); + + try std.testing.expectEqual(@as(usize, 3), rb.count); + try std.testing.expectEqual(@as(i32, 3), try rb.pop()); +} + +test "ring buf wrap around" { + var rb = RingBuffer(i32, 3).init(); + + try rb.push(1); + try rb.push(2); + try rb.push(3); + + try std.testing.expectError(error.BufferFull, rb.push(4)); + + try std.testing.expectEqual(@as(i32, 1), try rb.pop()); + try rb.push(4); + + try std.testing.expectEqual(@as(i32, 2), try rb.pop()); + try std.testing.expectEqual(@as(i32, 3), try rb.pop()); + try std.testing.expectEqual(@as(i32, 4), try rb.pop()); +} + +test "ring buf isEmpty and isFull checks" { + var rb = RingBuffer(u8, 2).init(); + + try std.testing.expect(rb.isEmpty()); + try std.testing.expect(!rb.isFull()); + + try rb.push(10); + try std.testing.expect(!rb.isEmpty()); + try std.testing.expect(!rb.isFull()); + + try rb.push(20); + try std.testing.expect(!rb.isEmpty()); + try std.testing.expect(rb.isFull()); +} + +test "ring buf underflow" { + var rb = RingBuffer(u8, 3).init(); + + try std.testing.expectError(error.BufferEmpty, rb.pop()); + try std.testing.expectError(error.BufferEmpty, rb.peek()); +} + +test "ring buf peek operation" { + var rb = RingBuffer(u8, 3).init(); + + try rb.push(42); + try std.testing.expectEqual(@as(u8, 42), try rb.peek()); + try std.testing.expectEqual(@as(u8, 42), try rb.pop()); + + try rb.push(100); + try rb.push(101); + try std.testing.expectEqual(@as(u8, 100), try rb.peek()); + try std.testing.expectEqual(@as(u8, 100), try rb.pop()); + try std.testing.expectEqual(@as(u8, 101), try rb.peek()); +} + +test "ring buf mix push and pop" { + var rb = RingBuffer(i32, 3).init(); + + try rb.push(1); + try rb.push(2); + try std.testing.expectEqual(@as(i32, 1), try rb.pop()); + + try rb.push(3); + try rb.push(4); + try std.testing.expectEqual(@as(i32, 2), try rb.pop()); + try std.testing.expectEqual(@as(i32, 3), try rb.pop()); + + try rb.push(5); + try rb.push(6); + try std.testing.expectEqual(@as(i32, 4), try rb.pop()); + try std.testing.expectEqual(@as(i32, 5), try rb.pop()); +} From b2548418bff0748cf3a810f3177c45821bf95388 Mon Sep 17 00:00:00 2001 From: jLevere Date: Mon, 18 Nov 2024 14:24:09 -0500 Subject: [PATCH 2/2] added more ring buf tests --- shared/main.zig | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/shared/main.zig b/shared/main.zig index 1800bd4..d8e60e3 100644 --- a/shared/main.zig +++ b/shared/main.zig @@ -229,3 +229,28 @@ test "ring buf mix push and pop" { try std.testing.expectEqual(@as(i32, 4), try rb.pop()); try std.testing.expectEqual(@as(i32, 5), try rb.pop()); } + +const TestStruct = struct { + id: u32, + name: []const u8, +}; + +test "ring buf with struct values" { + var rb = RingBuffer(TestStruct, 3).init(); + + const item1 = TestStruct{ .id = 1, .name = "Alice" }; + const item2 = TestStruct{ .id = 2, .name = "Bob" }; + + try rb.push(item1); + try rb.push(item2); + + const result1 = try rb.pop(); + try std.testing.expectEqual(@as(u32, 1), result1.id); + try std.testing.expectEqualStrings("Alice", result1.name); + + const result2 = try rb.pop(); + try std.testing.expectEqual(@as(u32, 2), result2.id); + try std.testing.expectEqualStrings("Bob", result2.name); + + try std.testing.expect(rb.isEmpty()); +}