mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-25 13:16:11 +03:00
circbuf resize operation
This commit is contained in:
@ -41,6 +41,30 @@ pub fn CircBuf(comptime T: type, comptime default: T) type {
|
|||||||
self.* = undefined;
|
self.* = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resize the buffer to the given size (larger or smaller).
|
||||||
|
/// If larger, new values will be set to the default value.
|
||||||
|
pub fn resize(self: *Self, alloc: Allocator, size: usize) !void {
|
||||||
|
// Rotate to zero so it is aligned.
|
||||||
|
try self.rotateToZero(alloc);
|
||||||
|
|
||||||
|
// Reallocate, this adds to the end so we're ready to go.
|
||||||
|
const prev_len = self.len();
|
||||||
|
const prev_cap = self.storage.len;
|
||||||
|
self.storage = try alloc.realloc(self.storage, size);
|
||||||
|
|
||||||
|
// If we grew, we need to set our new defaults. We can add it
|
||||||
|
// at the end since we rotated to start.
|
||||||
|
if (size > prev_cap) {
|
||||||
|
std.mem.set(T, self.storage[prev_cap..], default);
|
||||||
|
|
||||||
|
// Fix up our head/tail
|
||||||
|
if (self.full) {
|
||||||
|
self.head = prev_len;
|
||||||
|
self.full = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Rotate the data so that it is zero-aligned.
|
/// Rotate the data so that it is zero-aligned.
|
||||||
fn rotateToZero(self: *Self, alloc: Allocator) !void {
|
fn rotateToZero(self: *Self, alloc: Allocator) !void {
|
||||||
// TODO: this does this in the worst possible way by allocating.
|
// TODO: this does this in the worst possible way by allocating.
|
||||||
@ -355,3 +379,68 @@ test "rotateToZero full no wrap" {
|
|||||||
try testing.expectEqual(@as(u8, 4), slices[0][3]);
|
try testing.expectEqual(@as(u8, 4), slices[0][3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "resize grow" {
|
||||||
|
const testing = std.testing;
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
|
const Buf = CircBuf(u8, 0);
|
||||||
|
var buf = try Buf.init(alloc, 4);
|
||||||
|
defer buf.deinit(alloc);
|
||||||
|
|
||||||
|
// Fill and write
|
||||||
|
{
|
||||||
|
const slices = buf.getPtrSlice(0, 4);
|
||||||
|
try testing.expect(buf.full);
|
||||||
|
slices[0][0] = 1;
|
||||||
|
slices[0][1] = 2;
|
||||||
|
slices[0][2] = 3;
|
||||||
|
slices[0][3] = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resize
|
||||||
|
try buf.resize(alloc, 6);
|
||||||
|
try testing.expect(!buf.full);
|
||||||
|
try testing.expectEqual(@as(usize, 4), buf.len());
|
||||||
|
try testing.expectEqual(@as(usize, 6), buf.capacity());
|
||||||
|
|
||||||
|
{
|
||||||
|
const slices = buf.getPtrSlice(0, 4);
|
||||||
|
try testing.expectEqual(@as(u8, 1), slices[0][0]);
|
||||||
|
try testing.expectEqual(@as(u8, 2), slices[0][1]);
|
||||||
|
try testing.expectEqual(@as(u8, 3), slices[0][2]);
|
||||||
|
try testing.expectEqual(@as(u8, 4), slices[0][3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "resize shrink" {
|
||||||
|
const testing = std.testing;
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
|
const Buf = CircBuf(u8, 0);
|
||||||
|
var buf = try Buf.init(alloc, 4);
|
||||||
|
defer buf.deinit(alloc);
|
||||||
|
|
||||||
|
// Fill and write
|
||||||
|
{
|
||||||
|
const slices = buf.getPtrSlice(0, 4);
|
||||||
|
try testing.expect(buf.full);
|
||||||
|
slices[0][0] = 1;
|
||||||
|
slices[0][1] = 2;
|
||||||
|
slices[0][2] = 3;
|
||||||
|
slices[0][3] = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resize
|
||||||
|
try buf.resize(alloc, 3);
|
||||||
|
try testing.expect(buf.full);
|
||||||
|
try testing.expectEqual(@as(usize, 3), buf.len());
|
||||||
|
try testing.expectEqual(@as(usize, 3), buf.capacity());
|
||||||
|
|
||||||
|
{
|
||||||
|
const slices = buf.getPtrSlice(0, 3);
|
||||||
|
try testing.expectEqual(@as(u8, 1), slices[0][0]);
|
||||||
|
try testing.expectEqual(@as(u8, 2), slices[0][1]);
|
||||||
|
try testing.expectEqual(@as(u8, 3), slices[0][2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user