authorgravatar for quae@daurnimator.comdaurnimator <quae@daurnimator.com> 2019-11-11 00:26:40+11:00
committergravatar for quae@daurnimator.comdaurnimator <quae@daurnimator.com> 2019-11-25 09:26:32+11:00
loge810f485ab6395357febc85b65afddae5b061955
treedc56ad17efb5b9c032e5cc0feb86b1a3fd3b368c
parent01b2a56225038537f525f52b0d9c821ffa77b90b
signaturelock-open Commit is signed but in an unrecognized format.

std: add optimization to fifo if size is power of two


1 files changed, 30 insertions(+), 7 deletions(-)

lib/std/fifo.zig+30-7
......@@ -12,6 +12,8 @@ const testing = std.testing;
1212pub fn FixedSizeFifo(comptime T: type) type {
1313 const autoalign = false;
1414
15 const powers_of_two = true;
16
1517 return struct {
1618 allocator: *Allocator,
1719 buf: []T,
......@@ -68,10 +70,10 @@ pub fn FixedSizeFifo(comptime T: type) type {
6870 }
6971
7072 /// 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 {
7274 if (self.buf.len >= size) return;
7375 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;
7577 self.buf = try self.allocator.realloc(self.buf, new_size);
7678 }
7779
......@@ -124,10 +126,19 @@ pub fn FixedSizeFifo(comptime T: type) type {
124126 @memset(unused2.ptr, undefined, unused2.len);
125127 }
126128 }
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) {
130130 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 }
131142 }
132143
133144 /// Read the next item from the fifo
......@@ -225,7 +236,13 @@ pub fn FixedSizeFifo(comptime T: type) type {
225236 fn rewind(self: *Self, size: usize) void {
226237 assert(self.writableLength() >= size);
227238
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;
229246 self.count += size;
230247 }
231248
......@@ -246,7 +263,13 @@ pub fn FixedSizeFifo(comptime T: type) type {
246263 if (offset >= self.count)
247264 return error.EndOfStream;
248265
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];
250273 }
251274 };
252275}