tiny.profiling.experiment.parse
Defined in experiment.
API (2)
Actions
Public operations.
Source
Source: src/profiling/experiment/parse.zig
zig
const std = @import("std");const sys = @import("sys");const profiling = @import("../root.zig");const model = @import("model.zig");const json = profiling.json;const scenario = profiling.scenario;pub fn load( allocator: std.mem.Allocator, path: []const u8,) !model.Plan { const text = try sys.fs.readFileAlloc( allocator, path, model.maximum_plan_bytes, ); const value = try std.json.parseFromSliceLeaky( std.json.Value, allocator, text, .{}, ); return try parse(allocator, value);}pub fn parse( allocator: std.mem.Allocator, value: std.json.Value,) !model.Plan { const object = try json.object(value); const actual_schema = json.string(object.get("schema")) orelse return error.InvalidExperimentSchema; if (!std.mem.eql(u8, actual_schema, model.schema)) { return error.InvalidExperimentSchema; } const plan = model.Plan{ .name = try requiredString(object, "name"), .scenario = try scenario.parse( allocator, object.get("scenario") orelse return error.MissingScenario, ), .baseline = try parseVariant(allocator, object, "baseline"), .candidate = try parseVariant(allocator, object, "candidate"), .metric = model.Metric.parse( try requiredString(object, "metric"), ) orelse return error.InvalidExperimentMetric, .practical_effect_percent = json.asF64( object.get("practical_effect_percent"), ) orelse return error.InvalidPracticalEffect, .seed = json.asU64(object.get("seed")) orelse return error.InvalidExperimentSeed, .design = try parseDesign(object.get("design")), }; try plan.validate(); return plan;}fn parseVariant( allocator: std.mem.Allocator, object: std.json.ObjectMap, field: []const u8,) !model.Variant { const value = object.get(field) orelse return error.MissingVariant; const variant = try json.object(value); const binary = json.string(variant.get("binary")); const ref_name = json.string(variant.get("ref")); if ((binary == null) == (ref_name == null)) return error.InvalidVariant; if (binary) |path| return .{ .binary = path }; return .{ .git_ref = .{ .name = ref_name.?, .build = try parseBuild(allocator, variant.get("build")), } };}fn parseBuild( allocator: std.mem.Allocator, value: ?std.json.Value,) !?model.Build { const actual = value orelse return null; const object = try json.object(actual); return .{ .argv = try parseArguments(allocator, object.get("argv")), .artifact = try requiredString(object, "artifact"), .cwd = json.string(object.get("cwd")), };}fn parseArguments( allocator: std.mem.Allocator, value: ?std.json.Value,) ![]const []const u8 { const rows = try json.array(value orelse return error.InvalidVariantBuild); if (rows.items.len == 0 or rows.items.len > scenario.maximum_arguments) { return error.InvalidVariantBuild; } const result = try allocator.alloc([]const u8, rows.items.len); for (rows.items, 0..) |item, index| { const argument = json.string(item) orelse return error.InvalidVariantBuild; if (argument.len == 0 or argument.len > scenario.maximum_string_bytes) { return error.InvalidVariantBuild; } result[index] = argument; } return result;}fn parseDesign(value: ?std.json.Value) !model.Design { const actual = value orelse return .{}; const object = try json.object(actual); return .{ .calibration_pairs = try optionalUsize( object, "calibration_pairs", model.default_calibration_pairs, ), .minimum_evaluation_pairs = try optionalUsize( object, "minimum_evaluation_pairs", model.default_minimum_evaluation_pairs, ), .maximum_evaluation_pairs = try optionalUsize( object, "maximum_evaluation_pairs", model.default_maximum_evaluation_pairs, ), };}fn optionalUsize( object: std.json.ObjectMap, field: []const u8, default: usize,) !usize { const value = object.get(field) orelse return default; return std.math.cast( usize, json.asU64(value) orelse return error.InvalidExperimentDesign, ) orelse error.InvalidExperimentDesign;}fn requiredString( object: std.json.ObjectMap, field: []const u8,) ![]const u8 { return json.string(object.get(field)) orelse error.InvalidExperimentPlan;}test "profiling experiment parses binary scenario plans" { var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena_state.deinit(); const allocator = arena_state.allocator(); const value = try std.json.parseFromSliceLeaky( std.json.Value, allocator, \\{"schema":"tiny.profiling.experiment/v1","name":"startup", \\ "scenario":{"schema":"tiny.profiling.scenario/v1","name":"cli", \\ "argv":["{binary}","--version"],"oracle":{"exit_code":0}}, \\ "baseline":{"binary":"base"},"candidate":{"binary":"candidate"}, \\ "metric":"wall_ns","practical_effect_percent":5,"seed":42, \\ "design":{"calibration_pairs":6,"maximum_evaluation_pairs":40}} , .{}, ); const plan = try parse(allocator, value); try std.testing.expectEqual(model.Metric.wall_ns, plan.metric); try std.testing.expectEqual(@as(usize, 6), plan.design.calibration_pairs); try std.testing.expectEqual( @as(usize, 40), plan.design.maximum_evaluation_pairs, );}test "profiling experiment requires builds for ref command scenarios" { var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena_state.deinit(); const allocator = arena_state.allocator(); const value = try std.json.parseFromSliceLeaky( std.json.Value, allocator, \\{"schema":"tiny.profiling.experiment/v1","name":"startup", \\ "scenario":{"schema":"tiny.profiling.scenario/v1","name":"cli", \\ "argv":["{binary}"]}, \\ "baseline":{"ref":"main"},"candidate":{"binary":"candidate"}, \\ "metric":"wall_ns","practical_effect_percent":5,"seed":42} , .{}, ); try std.testing.expectError( error.RefCommandRequiresBuild, parse(allocator, value), );}Source: src/profiling/experiment/root.zig:5
zig
pub const parse = @import("parse.zig");Complete call list for experiment.parse.parse
8 direct calls.
tiny.profiling.experiment.model.Metric.parse[function] atsrc/profiling/experiment/model.zig:21src.profiling.experiment.parse.parseDesign[function] — private; no exact target atsrc/profiling/experiment/parse.zig:113in nearest public ownertiny.profiling.experiment.parsesrc.profiling.experiment.parse.parseVariant[function] — private; no exact target atsrc/profiling/experiment/parse.zig:59in nearest public ownertiny.profiling.experiment.parsesrc.profiling.experiment.parse.requiredString[function] — private; no exact target atsrc/profiling/experiment/parse.zig:147in nearest public ownertiny.profiling.experiment.parsetiny.profiling.json.asF64[function] atsrc/profiling/json.zig:58tiny.profiling.json.asU64[function] atsrc/profiling/json.zig:31tiny.profiling.json.object[function] atsrc/profiling/json.zig:3tiny.profiling.scenario.parse[function] atsrc/profiling/scenario.zig:78
Audit
| Definitions | 3 |
|---|---|
| Public names | 3 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |