diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-20 00:36:50 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:14 -0300 |
| commit | c1990b3e6e196ad41379aa432bf3ccca8a65d9f0 (patch) | |
| tree | d7ad5afe559f7f56464b14c3122242fa3f16399b /test/fs_bench.zig | |
| parent | 717afaf3177a2e0925b18ae3445119efe808b129 (diff) | |
| download | pardes-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.zig | 43 |
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, .{ |
