lib/zen/src/site/page/capacity.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2
3 const plan = @import("plan.zig");
4
5 pub const Limits = plan.Limits;
6 pub const DeriveError = error{CapacityOverflow};
7
8 pub const Capacity = struct {
9 limits: Limits,
10 page_bytes: usize,
11 storage_bytes: usize,
12
13 pub fn derive(limits: Limits) DeriveError!Capacity {
14 return .{
15 .limits = limits,
16 .page_bytes = limits.max_page_bytes,
17 .storage_bytes = std.math.add(usize, limits.max_page_bytes, 1) catch
18 return error.CapacityOverflow,
19 };
20 }
21 };
22
23 fn independent(limits: Limits) DeriveError!Capacity {
24 const storage_bytes = @as(u128, limits.max_page_bytes) + 1;
25 if (storage_bytes > std.math.maxInt(usize)) return error.CapacityOverflow;
26 return .{
27 .limits = limits,
28 .page_bytes = limits.max_page_bytes,
29 .storage_bytes = @intCast(storage_bytes),
30 };
31 }
32
33 test "site page capacity matches independent byte arithmetic" {
34 comptime {
35 @stardustClaim(
36 @import("alloc_phase").capacity.witness(@import("./root.zig").Storage, "zen_site_page_capacity"),
37 null,
38 null,
39 null,
40 null,
41 null,
42 null,
43 );
44 }
45
46 const limits = Limits{ .max_page_bytes = 65_535 };
47 try std.testing.expectEqual(try independent(limits), try Capacity.derive(limits));
48 try std.testing.expectEqual(@as(usize, 65_536), (try Capacity.derive(limits)).storage_bytes);
49 }
50
51 test "site page capacity reserves empty lookahead and rejects overflow" {
52 try std.testing.expectEqual(@as(usize, 1), (try Capacity.derive(.{
53 .max_page_bytes = 0,
54 })).storage_bytes);
55 try std.testing.expectError(error.CapacityOverflow, Capacity.derive(.{
56 .max_page_bytes = std.math.maxInt(usize),
57 }));
58 }