| ... | ... | @@ -12,6 +12,8 @@ const testing = std.testing; |
| 12 | 12 | pub fn FixedSizeFifo(comptime T: type) type { |
| 13 | 13 | const autoalign = false; |
| 14 | 14 | |
| 15 | const powers_of_two = true; |
| 16 | |
| 15 | 17 | return struct { |
| 16 | 18 | allocator: *Allocator, |
| 17 | 19 | buf: []T, |
| ... | ... | @@ -68,10 +70,10 @@ pub fn FixedSizeFifo(comptime T: type) type { |
| 68 | 70 | } |
| 69 | 71 | |
| 70 | 72 | /// Ensure that the buffer can fit at least `size` items |
| 71 | | pub fn ensureCapacity(self: *Self, size: usize) error{OutOfMemory}!void { |
| 73 | pub fn ensureCapacity(self: *Self, size: usize) !void { |
| 72 | 74 | if (self.buf.len >= size) return; |
| 73 | 75 | self.realign(); |
| 74 | | const new_size = math.ceilPowerOfTwo(usize, size) catch return error.OutOfMemory; |
| 76 | const new_size = if (powers_of_two) math.ceilPowerOfTwo(usize, size) catch return error.OutOfMemory else size; |
| 75 | 77 | self.buf = try self.allocator.realloc(self.buf, new_size); |
| 76 | 78 | } |
| 77 | 79 | |
| ... | ... | @@ -124,10 +126,19 @@ pub fn FixedSizeFifo(comptime T: type) type { |
| 124 | 126 | @memset(unused2.ptr, undefined, unused2.len); |
| 125 | 127 | } |
| 126 | 128 | } |
| 127 | | self.head = (self.head + count) % self.buf.len; |
| 128 | | self.count -= count; |
| 129 | | if (autoalign and self.count == 0) |
| 129 | if (autoalign and self.count == count) { |
| 130 | 130 | self.head = 0; |
| 131 | self.count = 0; |
| 132 | } else { |
| 133 | var head = self.head + count; |
| 134 | if (powers_of_two) { |
| 135 | head &= self.buf.len - 1; |
| 136 | } else { |
| 137 | head %= self.buf.len; |
| 138 | } |
| 139 | self.head = head; |
| 140 | self.count -= count; |
| 141 | } |
| 131 | 142 | } |
| 132 | 143 | |
| 133 | 144 | /// Read the next item from the fifo |
| ... | ... | @@ -225,7 +236,13 @@ pub fn FixedSizeFifo(comptime T: type) type { |
| 225 | 236 | fn rewind(self: *Self, size: usize) void { |
| 226 | 237 | assert(self.writableLength() >= size); |
| 227 | 238 | |
| 228 | | self.head = (self.head + (self.buf.len - size)) % self.buf.len; |
| 239 | var head = self.head + (self.buf.len - size); |
| 240 | if (powers_of_two) { |
| 241 | head &= self.buf.len - 1; |
| 242 | } else { |
| 243 | head %= self.buf.len; |
| 244 | } |
| 245 | self.head = head; |
| 229 | 246 | self.count += size; |
| 230 | 247 | } |
| 231 | 248 | |
| ... | ... | @@ -246,7 +263,13 @@ pub fn FixedSizeFifo(comptime T: type) type { |
| 246 | 263 | if (offset >= self.count) |
| 247 | 264 | return error.EndOfStream; |
| 248 | 265 | |
| 249 | | return self.buf[(self.head + offset) % self.buf.len]; |
| 266 | var index = self.head + offset; |
| 267 | if (powers_of_two) { |
| 268 | index &= self.buf.len - 1; |
| 269 | } else { |
| 270 | index %= self.buf.len; |
| 271 | } |
| 272 | return self.buf[index]; |
| 250 | 273 | } |
| 251 | 274 | }; |
| 252 | 275 | } |