mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
terminal: change pagelist linked list to an intrusive linked list
This commit is contained in:
@ -11,15 +11,19 @@ pub fn DoublyLinkedList(comptime T: type) type {
|
|||||||
return struct {
|
return struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
first: ?*T = null,
|
/// The type of the node in the list. This makes it easy to get the
|
||||||
last: ?*T = null,
|
/// node type from the list type.
|
||||||
|
pub const Node = T;
|
||||||
|
|
||||||
|
first: ?*Node = null,
|
||||||
|
last: ?*Node = null,
|
||||||
|
|
||||||
/// Insert a new node after an existing one.
|
/// Insert a new node after an existing one.
|
||||||
///
|
///
|
||||||
/// Arguments:
|
/// Arguments:
|
||||||
/// node: Pointer to a node in the list.
|
/// node: Pointer to a node in the list.
|
||||||
/// new_node: Pointer to the new node to insert.
|
/// new_node: Pointer to the new node to insert.
|
||||||
pub fn insertAfter(list: *Self, node: *T, new_node: *T) void {
|
pub fn insertAfter(list: *Self, node: *Node, new_node: *Node) void {
|
||||||
new_node.prev = node;
|
new_node.prev = node;
|
||||||
if (node.next) |next_node| {
|
if (node.next) |next_node| {
|
||||||
// Intermediate node.
|
// Intermediate node.
|
||||||
@ -38,7 +42,7 @@ pub fn DoublyLinkedList(comptime T: type) type {
|
|||||||
/// Arguments:
|
/// Arguments:
|
||||||
/// node: Pointer to a node in the list.
|
/// node: Pointer to a node in the list.
|
||||||
/// new_node: Pointer to the new node to insert.
|
/// new_node: Pointer to the new node to insert.
|
||||||
pub fn insertBefore(list: *Self, node: *T, new_node: *T) void {
|
pub fn insertBefore(list: *Self, node: *Node, new_node: *Node) void {
|
||||||
new_node.next = node;
|
new_node.next = node;
|
||||||
if (node.prev) |prev_node| {
|
if (node.prev) |prev_node| {
|
||||||
// Intermediate node.
|
// Intermediate node.
|
||||||
@ -56,7 +60,7 @@ pub fn DoublyLinkedList(comptime T: type) type {
|
|||||||
///
|
///
|
||||||
/// Arguments:
|
/// Arguments:
|
||||||
/// new_node: Pointer to the new node to insert.
|
/// new_node: Pointer to the new node to insert.
|
||||||
pub fn append(list: *Self, new_node: *T) void {
|
pub fn append(list: *Self, new_node: *Node) void {
|
||||||
if (list.last) |last| {
|
if (list.last) |last| {
|
||||||
// Insert after last.
|
// Insert after last.
|
||||||
list.insertAfter(last, new_node);
|
list.insertAfter(last, new_node);
|
||||||
@ -70,7 +74,7 @@ pub fn DoublyLinkedList(comptime T: type) type {
|
|||||||
///
|
///
|
||||||
/// Arguments:
|
/// Arguments:
|
||||||
/// new_node: Pointer to the new node to insert.
|
/// new_node: Pointer to the new node to insert.
|
||||||
pub fn prepend(list: *Self, new_node: *T) void {
|
pub fn prepend(list: *Self, new_node: *Node) void {
|
||||||
if (list.first) |first| {
|
if (list.first) |first| {
|
||||||
// Insert before first.
|
// Insert before first.
|
||||||
list.insertBefore(first, new_node);
|
list.insertBefore(first, new_node);
|
||||||
@ -87,7 +91,7 @@ pub fn DoublyLinkedList(comptime T: type) type {
|
|||||||
///
|
///
|
||||||
/// Arguments:
|
/// Arguments:
|
||||||
/// node: Pointer to the node to be removed.
|
/// node: Pointer to the node to be removed.
|
||||||
pub fn remove(list: *Self, node: *T) void {
|
pub fn remove(list: *Self, node: *Node) void {
|
||||||
if (node.prev) |prev_node| {
|
if (node.prev) |prev_node| {
|
||||||
// Intermediate node.
|
// Intermediate node.
|
||||||
prev_node.next = node.next;
|
prev_node.next = node.next;
|
||||||
@ -109,7 +113,7 @@ pub fn DoublyLinkedList(comptime T: type) type {
|
|||||||
///
|
///
|
||||||
/// Returns:
|
/// Returns:
|
||||||
/// A pointer to the last node in the list.
|
/// A pointer to the last node in the list.
|
||||||
pub fn pop(list: *Self) ?*T {
|
pub fn pop(list: *Self) ?*Node {
|
||||||
const last = list.last orelse return null;
|
const last = list.last orelse return null;
|
||||||
list.remove(last);
|
list.remove(last);
|
||||||
return last;
|
return last;
|
||||||
@ -119,7 +123,7 @@ pub fn DoublyLinkedList(comptime T: type) type {
|
|||||||
///
|
///
|
||||||
/// Returns:
|
/// Returns:
|
||||||
/// A pointer to the first node in the list.
|
/// A pointer to the first node in the list.
|
||||||
pub fn popFirst(list: *Self) ?*T {
|
pub fn popFirst(list: *Self) ?*Node {
|
||||||
const first = list.first orelse return null;
|
const first = list.first orelse return null;
|
||||||
list.remove(first);
|
list.remove(first);
|
||||||
return first;
|
return first;
|
||||||
|
@ -7,8 +7,9 @@ const std = @import("std");
|
|||||||
const build_config = @import("../build_config.zig");
|
const build_config = @import("../build_config.zig");
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const color = @import("color.zig");
|
|
||||||
const fastmem = @import("../fastmem.zig");
|
const fastmem = @import("../fastmem.zig");
|
||||||
|
const DoublyLinkedList = @import("../datastruct/main.zig").IntrusiveDoublyLinkedList;
|
||||||
|
const color = @import("color.zig");
|
||||||
const kitty = @import("kitty.zig");
|
const kitty = @import("kitty.zig");
|
||||||
const point = @import("point.zig");
|
const point = @import("point.zig");
|
||||||
const pagepkg = @import("page.zig");
|
const pagepkg = @import("page.zig");
|
||||||
@ -33,7 +34,16 @@ const page_preheat = 4;
|
|||||||
/// The list of pages in the screen. These are expected to be in order
|
/// The list of pages in the screen. These are expected to be in order
|
||||||
/// where the first page is the topmost page (scrollback) and the last is
|
/// where the first page is the topmost page (scrollback) and the last is
|
||||||
/// the bottommost page (the current active page).
|
/// the bottommost page (the current active page).
|
||||||
pub const List = std.DoublyLinkedList(Page);
|
pub const List = DoublyLinkedList(Node);
|
||||||
|
|
||||||
|
/// A single node within the PageList linked list.
|
||||||
|
///
|
||||||
|
/// This isn't pub because you can access the type via List.Node.
|
||||||
|
const Node = struct {
|
||||||
|
prev: ?*Node = null,
|
||||||
|
next: ?*Node = null,
|
||||||
|
data: Page,
|
||||||
|
};
|
||||||
|
|
||||||
/// The memory pool we get page nodes from.
|
/// The memory pool we get page nodes from.
|
||||||
const NodePool = std.heap.MemoryPool(List.Node);
|
const NodePool = std.heap.MemoryPool(List.Node);
|
||||||
@ -1699,7 +1709,8 @@ pub fn grow(self: *PageList) !?*List.Node {
|
|||||||
// reuses the popped page. It is possible to have a single page and
|
// reuses the popped page. It is possible to have a single page and
|
||||||
// exceed the max size if that page was adjusted to be larger after
|
// exceed the max size if that page was adjusted to be larger after
|
||||||
// initial allocation.
|
// initial allocation.
|
||||||
if (self.pages.len > 1 and
|
if (self.pages.first != null and
|
||||||
|
self.pages.first != self.pages.last and
|
||||||
self.page_size + PagePool.item_size > self.maxSize())
|
self.page_size + PagePool.item_size > self.maxSize())
|
||||||
prune: {
|
prune: {
|
||||||
// If we need to add more memory to ensure our active area is
|
// If we need to add more memory to ensure our active area is
|
||||||
|
Reference in New Issue
Block a user