-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathring_buffer.zig
69 lines (55 loc) · 1.67 KB
/
ring_buffer.zig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
const std = @import("std");
const Opts = struct {
capacity: usize = 1024,
};
pub fn RingBuffer(comptime T: type, opts: Opts) type {
return struct {
buffer: [opts.capacity]T,
r: usize,
w: usize,
const Self = @This();
pub fn init() !Self {
if (!isPowerOfTwo(opts.capacity)) return error.InvalidCapacity;
return Self{
.buffer = undefined,
.r = 0,
.w = 0,
};
}
fn isPowerOfTwo(value: usize) bool {
return value != 0 and (value & (value - 1)) == 0;
}
fn mask(self: Self, index: usize) usize {
return index & (self.buffer.len - 1);
}
pub fn isEmpty(self: Self) bool {
return self.w == self.r;
}
pub fn isFull(self: Self) bool {
return self.size() == self.buffer.len;
}
pub fn size(self: Self) usize {
return self.w - self.r;
}
pub fn write(self: *Self, item: T) !void {
if (self.isFull()) return error.BufferFull;
self.buffer[self.mask(self.w)] = item;
self.w += 1;
}
pub fn read(self: *Self) !T {
if (self.isEmpty()) return error.BufferEmpty;
const value = self.buffer[self.mask(self.r)];
self.r += 1;
return value;
}
pub fn clear(self: *Self) void {
self.r = 0;
self.w = 0;
}
pub fn plot(self: Self) void {
for (0..self.size()) |i| {
std.log.debug("{any}, ", .{self.buffer[self.mask(i)]});
}
}
};
}