This commit is contained in:
parent
4a5d512128
commit
512eab0db0
5 changed files with 38 additions and 34 deletions
|
|
@ -1,5 +1,5 @@
|
|||
[tools]
|
||||
prek = "0.3.1"
|
||||
"ubi:DonIsaac/zlint" = "0.7.9"
|
||||
zig = "0.15.2"
|
||||
zig = "0.16.0"
|
||||
zls = "0.15.1"
|
||||
|
|
|
|||
41
build.zig
41
build.zig
|
|
@ -250,6 +250,7 @@ const BenchmarkStep = struct {
|
|||
const b = step.owner;
|
||||
const self: *BenchmarkStep = @fieldParentPtr("step", step);
|
||||
|
||||
const io = b.graph.io;
|
||||
const gen_path = b.getInstallPath(.bin, self.gen_exe.name);
|
||||
const exe_path = b.getInstallPath(.bin, self.srf_exe.name);
|
||||
const count_str = b.fmt("{d}", .{self.record_count});
|
||||
|
|
@ -271,29 +272,32 @@ const BenchmarkStep = struct {
|
|||
|
||||
const hash_str = b.fmt("{x}", .{hash});
|
||||
const cache_dir = b.cache_root.join(b.allocator, &.{ "o", hash_str }) catch @panic("OOM");
|
||||
std.fs.cwd().makePath(cache_dir) catch {};
|
||||
b.cache_root.handle.createDirPath(io, cache_dir) catch @panic("Could not create cache path");
|
||||
|
||||
const filename = b.fmt("test-{s}.{s}", .{ fmt.name, fmt.ext });
|
||||
const filepath = b.pathJoin(&.{ cache_dir, filename });
|
||||
test_files[i] = filepath;
|
||||
|
||||
// Check if file exists
|
||||
if (std.fs.cwd().access(filepath, .{})) {
|
||||
if (b.cache_root.handle.access(io, filepath, .{})) {
|
||||
continue; // File exists, skip generation
|
||||
} else |_| {}
|
||||
|
||||
// Generate file
|
||||
var child = std.process.Child.init(&.{ gen_path, fmt.name, count_str }, b.allocator);
|
||||
child.stdout_behavior = .Pipe;
|
||||
try child.spawn();
|
||||
var child = try std.process.spawn(io, .{
|
||||
.argv = &.{ gen_path, fmt.name, count_str },
|
||||
.stdout = .pipe,
|
||||
});
|
||||
|
||||
const output = try child.stdout.?.readToEndAlloc(b.allocator, 100 * 1024 * 1024);
|
||||
var buf: [4096]u8 = undefined;
|
||||
var file_reader = child.stdout.?.reader(io, &buf);
|
||||
var reader = &file_reader.interface;
|
||||
const output = try reader.allocRemaining(b.allocator, .unlimited);
|
||||
defer b.allocator.free(output);
|
||||
const term = try child.wait(io);
|
||||
if (term != .exited or term.exited != 0) return error.GenerationFailed;
|
||||
|
||||
const term = try child.wait();
|
||||
if (term != .Exited or term.Exited != 0) return error.GenerationFailed;
|
||||
|
||||
try std.fs.cwd().writeFile(.{ .sub_path = filepath, .data = output });
|
||||
try b.cache_root.handle.writeFile(io, .{ .sub_path = filepath, .data = output });
|
||||
}
|
||||
|
||||
// Run hyperfine
|
||||
|
|
@ -308,16 +312,19 @@ const BenchmarkStep = struct {
|
|||
try argv.append(b.allocator, b.fmt("{s} jsonl <{s}", .{ exe_path, test_files[2] }));
|
||||
}
|
||||
|
||||
var child = std.process.Child.init(argv.items, b.allocator);
|
||||
|
||||
// We need to lock stderror so hyperfine can output progress in place
|
||||
std.debug.lockStdErr();
|
||||
defer std.debug.unlockStdErr();
|
||||
// SAFETY: buffer for locking
|
||||
var buf: [1024]u8 = undefined; // I have no idea what the right size buffer should be
|
||||
_ = try io.lockStderr(&buf, null);
|
||||
defer io.unlockStderr();
|
||||
|
||||
try child.spawn();
|
||||
const term = try child.wait();
|
||||
var child = try std.process.spawn(io, .{
|
||||
.argv = argv.items,
|
||||
});
|
||||
|
||||
if (term != .Exited or term.Exited != 0)
|
||||
const term = try child.wait(io);
|
||||
|
||||
if (term != .exited or term.exited != 0)
|
||||
return error.BenchmarkFailed;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
.fingerprint = 0x102ed002eff998a9, // Changing this has security and trust implications.
|
||||
// Tracks the earliest Zig version that the package considers to be a
|
||||
// supported use case.
|
||||
.minimum_zig_version = "0.15.2",
|
||||
.minimum_zig_version = "0.16.0",
|
||||
// This field is optional.
|
||||
// Each dependency must either provide a `url` and `hash`, or a `path`.
|
||||
// `zig build --fetch` can be used to fetch all dependencies of a package, recursively.
|
||||
|
|
|
|||
21
src/main.zig
21
src/main.zig
|
|
@ -46,13 +46,10 @@ const CountingAllocator = struct {
|
|||
}
|
||||
};
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer _ = gpa.deinit();
|
||||
const base_allocator = gpa.allocator();
|
||||
pub fn main(init: std.process.Init) !void {
|
||||
const gpa = init.gpa;
|
||||
|
||||
const args = try std.process.argsAlloc(base_allocator);
|
||||
defer std.process.argsFree(base_allocator, args);
|
||||
const args = try init.minimal.args.toSlice(init.arena.allocator());
|
||||
|
||||
if (args.len < 2) {
|
||||
std.debug.print("Usage: {s} <srf|json|jsonl>\n", .{args[0]});
|
||||
|
|
@ -61,19 +58,19 @@ pub fn main() !void {
|
|||
|
||||
const format = args[1];
|
||||
|
||||
const debug_allocs = std.process.hasEnvVarConstant("DEBUG_ALLOCATIONS");
|
||||
const debug_allocs = init.environ_map.contains("DEBUG_ALLOCATIONS");
|
||||
|
||||
var counting = CountingAllocator{ .child_allocator = base_allocator };
|
||||
const allocator = if (debug_allocs) counting.allocator() else base_allocator;
|
||||
var counting = CountingAllocator{ .child_allocator = gpa };
|
||||
const allocator = if (debug_allocs) counting.allocator() else gpa;
|
||||
|
||||
var stdin_buffer: [1024]u8 = undefined;
|
||||
var stdin_reader = std.fs.File.stdin().reader(&stdin_buffer);
|
||||
var stdin_reader = std.Io.File.stdin().reader(init.io, &stdin_buffer);
|
||||
const stdin = &stdin_reader.interface;
|
||||
|
||||
// Load all data into memory first for fair comparison
|
||||
var data: std.ArrayList(u8) = .empty;
|
||||
defer data.deinit(base_allocator);
|
||||
try stdin.appendRemaining(base_allocator, &data, @enumFromInt(100 * 1024 * 1024));
|
||||
defer data.deinit(gpa);
|
||||
try stdin.appendRemaining(gpa, &data, @enumFromInt(100 * 1024 * 1024));
|
||||
|
||||
if (std.mem.eql(u8, format, "srf")) {
|
||||
var reader = std.Io.Reader.fixed(data.items);
|
||||
|
|
|
|||
|
|
@ -1018,9 +1018,9 @@ pub const RecordIterator = struct {
|
|||
/// use or refresh cached data. Note that data will be returned by parse/
|
||||
/// iterator regardless of freshness. This enables callers to use cached
|
||||
/// data temporarily while refreshing it
|
||||
pub fn isFresh(self: RecordIterator) bool {
|
||||
pub fn isFresh(self: RecordIterator, io: std.Io) bool {
|
||||
if (self.expires) |exp|
|
||||
return std.time.timestamp() < exp;
|
||||
return std.Io.Timestamp.now(io, .real).toSeconds() < exp;
|
||||
|
||||
// no expiry: always fresh, never frozen
|
||||
return true;
|
||||
|
|
@ -1038,7 +1038,7 @@ pub const RecordIterator = struct {
|
|||
defer ri.deinit();
|
||||
|
||||
// No expiry set, so always fresh
|
||||
try std.testing.expect(ri.isFresh());
|
||||
try std.testing.expect(ri.isFresh(std.testing.io));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue