Skip to content

Commit 3770f97

Browse files
committed
terminal: Zig 0.15, lib-vt and test-lib-vt work
1 parent 913d2df commit 3770f97

File tree

15 files changed

+417
-370
lines changed

15 files changed

+417
-370
lines changed

src/datastruct/lru.zig

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,13 @@ pub fn HashMap(
3333
) type {
3434
return struct {
3535
const Self = @This();
36-
const Map = std.HashMapUnmanaged(K, *Queue.Node, Context, max_load_percentage);
37-
const Queue = std.DoublyLinkedList(KV);
36+
const Queue = std.DoublyLinkedList;
37+
const Map = std.HashMapUnmanaged(
38+
K,
39+
*Entry,
40+
Context,
41+
max_load_percentage,
42+
);
3843

3944
/// Map to maintain our entries.
4045
map: Map,
@@ -46,6 +51,15 @@ pub fn HashMap(
4651
/// misses will begin evicting entries.
4752
capacity: Map.Size,
4853

54+
const Entry = struct {
55+
data: KV,
56+
node: Queue.Node,
57+
58+
fn fromNode(node: *Queue.Node) *Entry {
59+
return @fieldParentPtr("node", node);
60+
}
61+
};
62+
4963
pub const KV = struct {
5064
key: K,
5165
value: V,
@@ -82,7 +96,7 @@ pub fn HashMap(
8296
var it = self.queue.first;
8397
while (it) |node| {
8498
it = node.next;
85-
alloc.destroy(node);
99+
alloc.destroy(Entry.fromNode(node));
86100
}
87101

88102
self.map.deinit(alloc);
@@ -108,8 +122,8 @@ pub fn HashMap(
108122
const map_gop = try self.map.getOrPutContext(alloc, key, ctx);
109123
if (map_gop.found_existing) {
110124
// Move to end to mark as most recently used
111-
self.queue.remove(map_gop.value_ptr.*);
112-
self.queue.append(map_gop.value_ptr.*);
125+
self.queue.remove(&map_gop.value_ptr.*.node);
126+
self.queue.append(&map_gop.value_ptr.*.node);
113127

114128
return GetOrPutResult{
115129
.found_existing = true,
@@ -122,37 +136,34 @@ pub fn HashMap(
122136
// We're evicting if our map insertion increased our capacity.
123137
const evict = self.map.count() > self.capacity;
124138

125-
// Get our node. If we're not evicting then we allocate a new
126-
// node. If we are evicting then we avoid allocation by just
127-
// reusing the node we would've evicted.
128-
var node = if (!evict) try alloc.create(Queue.Node) else node: {
139+
// Get our entry. If we're not evicting then we allocate a new
140+
// entry. If we are evicting then we avoid allocation by just
141+
// reusing the entry we would've evicted.
142+
const entry: *Entry = if (!evict) try alloc.create(Entry) else entry: {
129143
// Our first node is the least recently used.
130-
const least_used = self.queue.first.?;
131-
132-
// Move our least recently used to the end to make
133-
// it the most recently used.
134-
self.queue.remove(least_used);
144+
const least_used_node = self.queue.popFirst().?;
145+
const least_used_entry: *Entry = .fromNode(least_used_node);
135146

136147
// Remove the least used from the map
137-
_ = self.map.remove(least_used.data.key);
148+
_ = self.map.remove(least_used_entry.data.key);
138149

139-
break :node least_used;
150+
break :entry least_used_entry;
140151
};
141-
errdefer if (!evict) alloc.destroy(node);
152+
errdefer if (!evict) alloc.destroy(entry);
142153

143-
// Store our node in the map.
144-
map_gop.value_ptr.* = node;
154+
// Store our entry in the map.
155+
map_gop.value_ptr.* = entry;
145156

146-
// Mark the node as most recently used
147-
self.queue.append(node);
157+
// Mark the entry as most recently used
158+
self.queue.append(&entry.node);
148159

149160
// Set our key
150-
node.data.key = key;
161+
entry.data.key = key;
151162

152-
return GetOrPutResult{
163+
return .{
153164
.found_existing = map_gop.found_existing,
154-
.value_ptr = &node.data.value,
155-
.evicted = if (!evict) null else node.data,
165+
.value_ptr = &entry.data.value,
166+
.evicted = if (!evict) null else entry.data,
156167
};
157168
}
158169

@@ -193,11 +204,12 @@ pub fn HashMap(
193204

194205
var i: Map.Size = 0;
195206
while (i < delta) : (i += 1) {
196-
const node = self.queue.first.?;
197-
evicted[i] = node.data.value;
207+
const node = self.queue.popFirst().?;
208+
const entry: *Entry = .fromNode(node);
209+
evicted[i] = entry.data.value;
198210
self.queue.remove(node);
199-
_ = self.map.remove(node.data.key);
200-
alloc.destroy(node);
211+
_ = self.map.remove(entry.data.key);
212+
alloc.destroy(entry);
201213
}
202214

203215
self.capacity = capacity;

src/datastruct/main.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub const CacheTable = cache_table.CacheTable;
1414
pub const CircBuf = circ_buf.CircBuf;
1515
pub const IntrusiveDoublyLinkedList = intrusive_linked_list.DoublyLinkedList;
1616
pub const SegmentedPool = segmented_pool.SegmentedPool;
17-
pub const SplitTree = split_tree.SplitTree;
17+
//pub const SplitTree = split_tree.SplitTree;
1818

1919
test {
2020
@import("std").testing.refAllDecls(@This());

src/terminal/PageList.zig

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const std_size = Page.layout(std_capacity).total_size;
5656
/// allocator because we need memory that is zero-initialized and page-aligned.
5757
const PagePool = std.heap.MemoryPoolAligned(
5858
[std_size]u8,
59-
std.heap.page_size_min,
59+
.fromByteUnits(std.heap.page_size_min),
6060
);
6161

6262
/// List of pins, known as "tracked" pins. These are pins that are kept
@@ -388,11 +388,18 @@ pub fn reset(self: *PageList) void {
388388
const page_arena = &self.pool.pages.arena;
389389
var it = page_arena.state.buffer_list.first;
390390
while (it) |node| : (it = node.next) {
391-
// The fully allocated buffer
392-
const alloc_buf = @as([*]u8, @ptrCast(node))[0..node.data];
391+
// WARN: Since HeapAllocator's BufNode is not public API,
392+
// we have to hardcode its layout here. We do a comptime assert
393+
// on Zig version to verify we check it on every bump.
394+
const BufNode = struct {
395+
data: usize,
396+
node: std.SinglyLinkedList.Node,
397+
};
398+
const buf_node: *BufNode = @fieldParentPtr("node", node);
393399

400+
// The fully allocated buffer
401+
const alloc_buf = @as([*]u8, @ptrCast(buf_node))[0..buf_node.data];
394402
// The buffer minus our header
395-
const BufNode = @TypeOf(page_arena.state.buffer_list).Node;
396403
const data_buf = alloc_buf[@sizeOf(BufNode)..];
397404
@memset(data_buf, 0);
398405
}
@@ -2075,7 +2082,7 @@ inline fn createPageExt(
20752082
else
20762083
try page_alloc.alignedAlloc(
20772084
u8,
2078-
std.heap.page_size_min,
2085+
.fromByteUnits(std.heap.page_size_min),
20792086
layout.total_size,
20802087
);
20812088
errdefer if (pooled)
@@ -2676,7 +2683,7 @@ pub const EncodeUtf8Options = struct {
26762683
/// predates this and is a thin wrapper around it so the tests all live there.
26772684
pub fn encodeUtf8(
26782685
self: *const PageList,
2679-
writer: anytype,
2686+
writer: *std.Io.Writer,
26802687
opts: EncodeUtf8Options,
26812688
) anyerror!void {
26822689
// We don't currently use self at all. There is an argument that this

src/terminal/Parser.zig

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,9 @@ pub const Action = union(enum) {
9797
// Implement formatter for logging
9898
pub fn format(
9999
self: CSI,
100-
comptime layout: []const u8,
101-
opts: std.fmt.FormatOptions,
102-
writer: anytype,
100+
writer: *std.Io.Writer,
103101
) !void {
104-
_ = layout;
105-
_ = opts;
106-
try std.fmt.format(writer, "ESC [ {s} {any} {c}", .{
102+
try writer.print("ESC [ {s} {any} {c}", .{
107103
self.intermediates,
108104
self.params,
109105
self.final,
@@ -118,13 +114,9 @@ pub const Action = union(enum) {
118114
// Implement formatter for logging
119115
pub fn format(
120116
self: ESC,
121-
comptime layout: []const u8,
122-
opts: std.fmt.FormatOptions,
123-
writer: anytype,
117+
writer: *std.Io.Writer,
124118
) !void {
125-
_ = layout;
126-
_ = opts;
127-
try std.fmt.format(writer, "ESC {s} {c}", .{
119+
try writer.print("ESC {s} {c}", .{
128120
self.intermediates,
129121
self.final,
130122
});
@@ -142,11 +134,8 @@ pub const Action = union(enum) {
142134
// print out custom formats for some of our primitives.
143135
pub fn format(
144136
self: Action,
145-
comptime layout: []const u8,
146-
opts: std.fmt.FormatOptions,
147-
writer: anytype,
137+
writer: *std.Io.Writer,
148138
) !void {
149-
_ = layout;
150139
const T = Action;
151140
const info = @typeInfo(T).@"union";
152141

@@ -162,21 +151,20 @@ pub const Action = union(enum) {
162151
const value = @field(self, u_field.name);
163152
switch (@TypeOf(value)) {
164153
// Unicode
165-
u21 => try std.fmt.format(writer, "'{u}' (U+{X})", .{ value, value }),
154+
u21 => try writer.print("'{u}' (U+{X})", .{ value, value }),
166155

167156
// Byte
168-
u8 => try std.fmt.format(writer, "0x{x}", .{value}),
157+
u8 => try writer.print("0x{x}", .{value}),
169158

170159
// Note: we don't do ASCII (u8) because there are a lot
171160
// of invisible characters we don't want to handle right
172161
// now.
173162

174163
// All others do the default behavior
175-
else => try std.fmt.formatType(
176-
@field(self, u_field.name),
164+
else => try writer.printValue(
177165
"any",
178-
opts,
179-
writer,
166+
.{},
167+
@field(self, u_field.name),
180168
3,
181169
),
182170
}
@@ -391,7 +379,7 @@ inline fn doAction(self: *Parser, action: TransitionAction, c: u8) ?Action {
391379
// We only allow colon or mixed separators for the 'm' command.
392380
if (c != 'm' and self.params_sep.count() > 0) {
393381
log.warn(
394-
"CSI colon or mixed separators only allowed for 'm' command, got: {}",
382+
"CSI colon or mixed separators only allowed for 'm' command, got: {f}",
395383
.{result},
396384
);
397385
break :csi_dispatch null;

0 commit comments

Comments
 (0)