CircBuf: non-allocating rotateToZero

We can call `std.mem.rotate` for this.
This commit is contained in:
Qwerasd
2025-05-25 22:25:23 -06:00
parent 3f6c02b49e
commit 19db2e2755

View File

@@ -152,7 +152,7 @@ pub fn CircBuf(comptime T: type, comptime default: T) type {
/// If larger, new values will be set to the default value.
pub fn resize(self: *Self, alloc: Allocator, size: usize) Allocator.Error!void {
// Rotate to zero so it is aligned.
try self.rotateToZero(alloc);
try self.rotateToZero();
// Reallocate, this adds to the end so we're ready to go.
const prev_len = self.len();
@@ -173,29 +173,16 @@ pub fn CircBuf(comptime T: type, comptime default: T) type {
}
/// Rotate the data so that it is zero-aligned.
fn rotateToZero(self: *Self, alloc: Allocator) Allocator.Error!void {
// TODO: this does this in the worst possible way by allocating.
// rewrite to not allocate, its possible, I'm just lazy right now.
fn rotateToZero(self: *Self) Allocator.Error!void {
// If we're already at zero then do nothing.
if (self.tail == 0) return;
var buf = try alloc.alloc(T, self.storage.len);
defer {
self.head = if (self.full) 0 else self.len();
self.tail = 0;
alloc.free(self.storage);
self.storage = buf;
}
// We use std.mem.rotate to rotate our storage in-place.
std.mem.rotate(T, self.storage, self.tail);
if (!self.full and self.head >= self.tail) {
fastmem.copy(T, buf, self.storage[self.tail..self.head]);
return;
}
const middle = self.storage.len - self.tail;
fastmem.copy(T, buf, self.storage[self.tail..]);
fastmem.copy(T, buf[middle..], self.storage[0..self.head]);
// Then fix up our head and tail.
self.head = self.len() % self.storage.len;
self.tail = 0;
}
/// Returns if the buffer is currently empty. To check if its
@@ -589,7 +576,7 @@ test "CircBuf rotateToZero" {
defer buf.deinit(alloc);
_ = buf.getPtrSlice(0, 11);
try buf.rotateToZero(alloc);
try buf.rotateToZero();
}
test "CircBuf rotateToZero offset" {
@@ -611,7 +598,7 @@ test "CircBuf rotateToZero offset" {
try testing.expect(buf.tail > 0 and buf.head >= buf.tail);
// Rotate to zero
try buf.rotateToZero(alloc);
try buf.rotateToZero();
try testing.expectEqual(@as(usize, 0), buf.tail);
try testing.expectEqual(@as(usize, 1), buf.head);
}
@@ -645,7 +632,7 @@ test "CircBuf rotateToZero wraps" {
}
// Rotate to zero
try buf.rotateToZero(alloc);
try buf.rotateToZero();
try testing.expectEqual(@as(usize, 0), buf.tail);
try testing.expectEqual(@as(usize, 3), buf.head);
{
@@ -681,7 +668,7 @@ test "CircBuf rotateToZero full no wrap" {
}
// Rotate to zero
try buf.rotateToZero(alloc);
try buf.rotateToZero();
try testing.expect(buf.full);
try testing.expectEqual(@as(usize, 0), buf.tail);
try testing.expectEqual(@as(usize, 0), buf.head);