lib/choir/src/composition/plan.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const fixture = @import("fixture/root.zig");
2 const std = @import("std");
3 const choir = @import("../root.zig");
4 const source = @import("source/root.zig");
5
6 const Allocator = std.mem.Allocator;
7 const product = choir.product;
8
9 /// An owned pipeline proposal for one partition and shared ABI version.
10 /// It retains the exact input record and names an artifact export; native work stays transient.
11 pub const FragmentPlan = struct {
12 allocator: Allocator,
13 id: source.FragmentId,
14 input: source.PipelineInput,
15 export_symbol: []const u8,
16 abi_version: u32,
17
18 pub fn init(
19 allocator: Allocator,
20 id: source.FragmentId,
21 input: source.PipelineInput,
22 export_symbol: []const u8,
23 abi_version: u32,
24 ) product.ProductMetadataError!FragmentPlan {
25 const input_product = try product.cloneProductKey(allocator, input.product);
26 errdefer product.deinitProductKey(allocator, input_product);
27 return .{
28 .allocator = allocator,
29 .id = id,
30 .input = .{
31 .partition = input.partition,
32 .pipeline = input.pipeline,
33 .product = input_product,
34 },
35 .export_symbol = try allocator.dupe(u8, export_symbol),
36 .abi_version = abi_version,
37 };
38 }
39
40 pub fn deinit(self: *FragmentPlan) void {
41 self.allocator.free(self.export_symbol);
42 product.deinitProductKey(self.allocator, self.input.product);
43 self.* = undefined;
44 }
45 };
46
47 test "fragment plan owns product names and export symbol" {
48 const Harness = struct {
49 fn run(allocator: Allocator) !void {
50 const records = try fixture.Records.init(allocator);
51 defer records.deinit();
52 var input_name = [_]u8{ 'i', 'n' };
53 var export_symbol = [_]u8{ 'r', 'u', 'n' };
54 var plan = try FragmentPlan.init(
55 allocator,
56 .{ .value = 3 },
57 .{
58 .partition = .{ .value = 2 },
59 .pipeline = .accy,
60 .product = try records.key(&input_name, "4", "5"),
61 },
62 &export_symbol,
63 1,
64 );
65 defer plan.deinit();
66 input_name[0] = 'x';
67 export_symbol[0] = 'x';
68 try std.testing.expectEqualStrings("in", plan.input.product.ref.stage);
69 try std.testing.expectEqualStrings("run", plan.export_symbol);
70 }
71 };
72
73 try std.testing.checkAllAllocationFailures(std.testing.allocator, Harness.run, .{});
74 }