terminal/new: use new pagelist grow mechanism that prunes

This commit is contained in:
Mitchell Hashimoto
2024-02-27 10:29:12 -08:00
parent 79146e3abd
commit 345b246e06
2 changed files with 19 additions and 44 deletions

View File

@ -258,7 +258,9 @@ pub fn scroll(self: *PageList, behavior: Scroll) void {
/// This may allocate, but also may not if our current page has more
/// capacity we can use. This will prune scrollback if necessary to
/// adhere to max_size.
pub fn grow2(self: *PageList) !?*List.Node {
///
/// This returns the newly allocated page node if there is one.
pub fn grow(self: *PageList) !?*List.Node {
const last = self.pages.last.?;
if (last.data.capacity.rows > last.data.size.rows) {
// Fast path: we have capacity in the last page.
@ -305,16 +307,6 @@ pub fn grow2(self: *PageList) !?*List.Node {
return next_page;
}
/// Grow the page list by exactly one page and return the new page. The
/// newly allocated page will be size 0 (but capacity is set).
pub fn grow(self: *PageList) !*List.Node {
const next_page = try self.createPage();
// we don't errdefer this because we've added it to the linked
// list and its fine to have dangling unused pages.
self.pages.append(next_page);
return next_page;
}
/// Create a new page node. This does not add it to the list and this
/// does not do any memory size accounting with max_size/page_size.
fn createPage(self: *PageList) !*List.Node {
@ -461,7 +453,7 @@ fn growRows(self: *PageList, n: usize) !void {
}
while (n_rem > 0) {
page = try self.grow();
page = (try self.grow()).?;
const add = @min(n_rem, page.data.capacity.rows);
page.data.size.rows = add;
n_rem -= add;
@ -847,7 +839,7 @@ test "PageList grow fit in capacity" {
try testing.expect(last.size.rows < last.capacity.rows);
// Grow
try testing.expect(try s.grow2() == null);
try testing.expect(try s.grow() == null);
{
const pt = s.getCell(.{ .active = .{} }).?.screenPoint();
try testing.expectEqual(point.Point{ .screen = .{
@ -868,11 +860,11 @@ test "PageList grow allocate" {
const last_node = s.pages.last.?;
const last = &s.pages.last.?.data;
for (0..last.capacity.rows - last.size.rows) |_| {
try testing.expect(try s.grow2() == null);
try testing.expect(try s.grow() == null);
}
// Grow, should allocate
const new = (try s.grow2()).?;
const new = (try s.grow()).?;
try testing.expect(s.pages.last.? == new);
try testing.expect(last_node.next.? == new);
{
@ -897,14 +889,14 @@ test "PageList grow prune scrollback" {
const page1_node = s.pages.last.?;
const page1 = page1_node.data;
for (0..page1.capacity.rows - page1.size.rows) |_| {
try testing.expect(try s.grow2() == null);
try testing.expect(try s.grow() == null);
}
// Grow and allocate one more page. Then fill that page up.
const page2_node = (try s.grow2()).?;
const page2_node = (try s.grow()).?;
const page2 = page2_node.data;
for (0..page2.capacity.rows - page2.size.rows) |_| {
try testing.expect(try s.grow2() == null);
try testing.expect(try s.grow() == null);
}
// Get our page size
@ -912,7 +904,7 @@ test "PageList grow prune scrollback" {
// Next should create a new page, but it should reuse our first
// page since we're at max size.
const new = (try s.grow2()).?;
const new = (try s.grow()).?;
try testing.expect(s.pages.last.? == new);
try testing.expectEqual(s.page_size, old_page_size);

View File

@ -226,31 +226,14 @@ pub fn cursorAbsolute(self: *Screen, x: size.CellCountInt, y: size.CellCountInt)
pub fn cursorDownScroll(self: *Screen) !void {
assert(self.cursor.y == self.pages.rows - 1);
const cursor_page = self.cursor.page_offset.page;
if (cursor_page.data.capacity.rows > cursor_page.data.size.rows) {
// If we have cap space in our current cursor page then we can take
// a fast path: update the size, recalculate the row/cell cursor pointers.
cursor_page.data.size.rows += 1;
const page_offset = self.cursor.page_offset.forward(1).?;
const page_rac = page_offset.rowAndCell(self.cursor.x);
self.cursor.page_offset = page_offset;
self.cursor.page_row = page_rac.row;
self.cursor.page_cell = page_rac.cell;
} else {
// No space, we need to allocate a new page and move the cursor to it.
const new_page = try self.pages.grow();
assert(new_page.data.size.rows == 0);
new_page.data.size.rows = 1;
const page_offset: PageList.RowOffset = .{
.page = new_page,
.row_offset = 0,
};
const page_rac = page_offset.rowAndCell(self.cursor.x);
self.cursor.page_offset = page_offset;
self.cursor.page_row = page_rac.row;
self.cursor.page_cell = page_rac.cell;
}
// Grow our pages by one row. The PageList will handle if we need to
// allocate, prune scrollback, whatever.
_ = try self.pages.grow();
const page_offset = self.cursor.page_offset.forward(1).?;
const page_rac = page_offset.rowAndCell(self.cursor.x);
self.cursor.page_offset = page_offset;
self.cursor.page_row = page_rac.row;
self.cursor.page_cell = page_rac.cell;
// The newly created line needs to be styled according to the bg color
// if it is set.