summaryrefslogtreecommitdiff
path: root/test/fs_bench.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-20 00:36:50 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:14 -0300
commitc1990b3e6e196ad41379aa432bf3ccca8a65d9f0 (patch)
treed7ad5afe559f7f56464b14c3122242fa3f16399b /test/fs_bench.zig
parent717afaf3177a2e0925b18ae3445119efe808b129 (diff)
downloadpardes-c1990b3e6e196ad41379aa432bf3ccca8a65d9f0.tar.gz
pardes-c1990b3e6e196ad41379aa432bf3ccca8a65d9f0.zip
Flatten the 9P control tree and move it out of fs.zig
The served tree loses the self/ level: /index /ctl /new /log /screen /listeners /pane/<n>/... /os, with /src only in -Dembed-sources=true builds (default off, on for esp32p4). ctl speaks the editor's own language with two lowercase verbs, look TEXT and exec TEXT, plus acme's addr verbs; the new/ factory directory becomes one clone file; cons is gone (exec Msg); name and sel are files; stats report real lengths, modes and mtimes; /log streams pane new/del/rename/save events. The tree code lives in src/ninep/ (tree, pane, ctl, addr, pty, events, screen, sources); fs.zig keeps host access, mounts, resolution and find/grep. Same engine and transports. README (fs-help.txt) and docs rewritten; tests updated and extended. Co-Authored-By: Claude Fable 5.1 <[email protected]>
Diffstat (limited to 'test/fs_bench.zig')
-rw-r--r--test/fs_bench.zig43
1 files changed, 23 insertions, 20 deletions
diff --git a/test/fs_bench.zig b/test/fs_bench.zig
index 7fe49734..f9735ee2 100644
--- a/test/fs_bench.zig
+++ b/test/fs_bench.zig
@@ -1,6 +1,7 @@
const std = @import("std");
const pardes = @import("pardes");
const filesystem = pardes.filesystem;
+const ctlfs = pardes.ctlfs;
pub const std_options: std.Options = .{ .log_level = .err };
@@ -73,8 +74,8 @@ const Session = struct {
s.core.deinit();
}
- fn node(s: *const Session, file: filesystem.PaneFile) u64 {
- return filesystem.Node.of(s.file_serial, file);
+ fn node(s: *const Session, file: ctlfs.PaneFile) u64 {
+ return ctlfs.Node.of(s.file_serial, file);
}
};
@@ -90,9 +91,9 @@ fn checkNumbers(bytes: []const u8, expected: []const usize) ![]const u8 {
return std.mem.trimStart(u8, rest, " ");
}
-fn checkReply(s: *Session, req: filesystem.Req, reply: filesystem.Reply) !void {
+fn checkReply(s: *Session, req: ctlfs.Req, reply: ctlfs.Reply) !void {
const event_read = req.op == .read and req.node == s.node(.event);
- const expected_status: filesystem.Status = if (event_read) .again else .ok;
+ const expected_status: ctlfs.Status = if (event_read) .again else .ok;
if (reply.tag != req.tag or reply.errno != 0 or reply.status != expected_status)
return error.IncorrectReply;
const body = s.core.panes[s.file_id].?.file.?.content;
@@ -112,16 +113,18 @@ fn checkReply(s: *Session, req: filesystem.Req, reply: filesystem.Reply) !void {
if (reply.payload != .staged or reply.payload.staged != bytes.len or bytes.len > req.size)
return error.IncorrectReply;
const pane = s.core.panes[s.file_id].?;
+ if (req.node == @intFromEnum(ctlfs.TopFile.index)) {
+ var expected_buf: [4200]u8 = undefined;
+ const expected = try std.fmt.bufPrint(&expected_buf, "{d} text {d} {s}\n", .{ s.file_serial, @intFromBool(pane.file.?.revision != pane.file.?.saved_revision), pane.file.?.path });
+ if (!std.mem.eql(u8, expected, bytes)) return error.IncorrectReply;
+ return;
+ }
const rest = try checkNumbers(bytes, &.{ s.file_serial, s.tag.len, body.len, 0, @intFromBool(pane.file.?.revision != pane.file.?.saved_revision) });
if (req.node == s.node(.ctl)) {
const tail = try checkNumbers(rest, &.{pane.cols});
if (!std.mem.startsWith(u8, tail, "default ")) return error.IncorrectReply;
if ((try checkNumbers(tail[8..], &.{pardes.config.tab_width})).len != 0)
return error.IncorrectReply;
- } else if (req.node == @intFromEnum(filesystem.SelfFile.index)) {
- const tag = s.tag[0 .. std.mem.indexOfScalar(u8, s.tag, '\n') orelse s.tag.len];
- if (rest.len != tag.len + 1 or rest[rest.len - 1] != '\n' or !std.mem.eql(u8, rest[0..tag.len], tag))
- return error.IncorrectReply;
} else return error.UnmeasuredOperation;
}
},
@@ -129,8 +132,8 @@ fn checkReply(s: *Session, req: filesystem.Req, reply: filesystem.Reply) !void {
const bytes = s.core.fs.out.items;
if (reply.payload != .staged or reply.payload.staged != bytes.len or bytes.len > req.size)
return error.IncorrectReply;
- const names = [_][]const u8{ "index", "cons", "new", "pane", "screen", "listeners" };
- const nodes = [_]u64{ @intFromEnum(filesystem.SelfFile.index), @intFromEnum(filesystem.SelfFile.cons), @intFromEnum(filesystem.SelfFile.new), filesystem.namespace_panes, @intFromEnum(filesystem.SelfFile.screen), @intFromEnum(filesystem.SelfFile.listeners) };
+ const names = [_][]const u8{ "README", "index", "ctl", "new", "log", "screen", "listeners", "pane", "os" };
+ const nodes = [_]u64{ @intFromEnum(ctlfs.TopFile.README), @intFromEnum(ctlfs.TopFile.index), @intFromEnum(ctlfs.TopFile.ctl), @intFromEnum(ctlfs.TopFile.new), @intFromEnum(ctlfs.TopFile.log), @intFromEnum(ctlfs.TopFile.screen), @intFromEnum(ctlfs.TopFile.listeners), @intFromEnum(ctlfs.TopFile.pane), filesystem.os_root };
var off: usize = 0;
var entry: usize = 0;
while (off < bytes.len) : (entry += 1) {
@@ -140,7 +143,7 @@ fn checkReply(s: *Session, req: filesystem.Req, reply: filesystem.Reply) !void {
const size: usize = bytes[off + 9];
off += 10;
if (dir > 1 or size == 0 or size > bytes.len - off) return error.IncorrectReply;
- if (entry < names.len and (node != nodes[entry] or dir != @intFromBool(entry == 2 or entry == 3) or
+ if (entry < names.len and (node != nodes[entry] or dir != @intFromBool(entry >= 7) or
!std.mem.eql(u8, names[entry], bytes[off..][0..size]))) return error.IncorrectReply;
off += size;
}
@@ -151,21 +154,21 @@ fn checkReply(s: *Session, req: filesystem.Req, reply: filesystem.Reply) !void {
}
}
-fn bench(s: *Session, name: []const u8, reps: usize, req: filesystem.Req, note: []const u8) !void {
+fn bench(s: *Session, name: []const u8, reps: usize, req: ctlfs.Req, note: []const u8) !void {
std.debug.assert(reps > 0);
const initial_bytes = s.core.panes[s.file_id].?.file.?.content.len;
const initial_hash = if (req.op == .write) std.hash.Wyhash.hash(0, s.core.panes[s.file_id].?.file.?.content) else 0;
for (0..64) |_| {
- try checkReply(s, req, filesystem.handle(s.core, req));
+ try checkReply(s, req, ctlfs.handle(s.core, req));
_ = s.core.scratch.reset(.retain_capacity);
}
s.counting.allocations = 0;
- const expected_status: filesystem.Status = if (req.op == .read and req.node == s.node(.event)) .again else .ok;
+ const expected_status: ctlfs.Status = if (req.op == .read and req.node == s.node(.event)) .again else .ok;
var valid = true;
- var reply: filesystem.Reply = undefined;
+ var reply: ctlfs.Reply = undefined;
const start = nowNs();
for (0..reps) |_| {
- reply = filesystem.handle(s.core, req);
+ reply = ctlfs.handle(s.core, req);
valid = valid and reply.tag == req.tag and reply.status == expected_status and reply.errno == 0;
std.mem.doNotOptimizeAway(reply);
_ = s.core.scratch.reset(.retain_capacity);
@@ -223,7 +226,7 @@ pub fn main(init: std.process.Init) !void {
try bench(&s, "lookup ctl", reps, .{
.tag = 2,
.op = .lookup,
- .node = filesystem.Node.of(s.file_serial, .dir),
+ .node = ctlfs.Node.of(s.file_serial, .dir),
.data = "ctl",
}, "name -> node");
try bench(&s, "read body 4K", reps, .{
@@ -249,13 +252,13 @@ pub fn main(init: std.process.Init) !void {
try bench(&s, "read index", reps, .{
.tag = 6,
.op = .read,
- .node = @intFromEnum(filesystem.SelfFile.index),
+ .node = @intFromEnum(ctlfs.TopFile.index),
.size = 4096,
}, "one line per pane");
- try bench(&s, "readdir self", reps, .{
+ try bench(&s, "readdir root", reps, .{
.tag = 7,
.op = .readdir,
- .node = @intFromEnum(filesystem.SelfFile.root),
+ .node = ctlfs.root,
.size = 4096,
}, "staged dirents");
try bench(&s, "read event (empty)", reps, .{