Skip to documentation
SLOP

tiny.reducer.Storage

Reference tiny.reducer Storage

Defined in bytes.storage.

Workspace, allocated up front and double-buffered, that carries reduction in steady state.

API (17)

Actions

Public operations.

Types and contracts

Public types and contracts.

Fields and members

Public fields and members.

No direct callersNo direct callsbytes.storageStorage
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Source: lib/reducer/src/bytes/storage.zig:95

zig
/// Workspace, allocated up front and double-buffered, that carries reduction in/// steady state. It holds the backing allocation and tracks the phase it is in/// and whether a lease is out.pub const Storage = struct {    /// Lifecycle phase that `alloc_phase` enforces.    phase: alloc_phase.capacity.Phase,    /// Layout derived while initializing.    capacity: capacity_mod.Capacity,    /// Entire contiguous backing byte allocation.    bytes: []u8,    /// Fixed sub-slice reserved for the witness lane, spanning $0 \dots N$.    current: []u8,    /// Fixed sub-slice reserved for the scratch lane, spanning    /// $N \dots N + \max(N - 1, 0)$.    candidate: []u8,    /// Flag recording that a lease is out, turning away a reentrant acquisition    /// and one made while an earlier result is still live.    in_use: bool = false,    /// Re-export of the capacity limits type.    pub const Limits: type = capacity_mod.Limits;    /// Re-export of the derived capacity type.    pub const Capacity: type = capacity_mod.Capacity;    /// Re-export of the exhaustion error set.    pub const Exhaustion: type = model.Exhaustion;    /// Errors `Storage.init()` may return.    pub const InitError = std.mem.Allocator.Error || capacity_mod.DeriveError;    /// Stardust capacity declaration that phase-directed allocation    /// verification reads. It records that the workspace owner makes no further    /// backing allocation once sealed into steady state. It bounds the storage    /// by $2 \times \text{max\_input\_bytes}$. It leaves out the memory and the    /// effects the caller's predicate owns.    pub const claim: alloc_phase.capacity.Declaration = .{        .source = .{            .id = "reducer.byte_storage",            .kind = .phase_static,            .limit_source = .caller,            .storage = .{                .covered = &.{                    .{                        .id = "accepted_input_and_borrowed_result_bytes",                        .lifetime = .steady,                        .detail = "accepted input and borrowed result bytes",                    },                    .{                        .id = "deletion_candidate_scratch_bytes",                        .lifetime = .steady,                        .detail = "deletion candidate scratch bytes",                    },                },                .excluded = &.{                    "caller-owned initial input bytes",                    "caller-owned predicate context, allocation, and effects",                },            },            .capacity = .{                .inputs = &.{                    alloc_phase.capacity.bindInput(Limits, "max_input_bytes", "max_input_bytes"),                },                .type_selectors = &.{},                .nodes = &.{                    .{ .input = 0 },                    .{ .scale = .{ .node = 0, .coefficient = .{ .literal = 2 } } },                },                .assertions = &.{.{                    .scope = .closure_total,                    .measure = .retained,                    .relation = .upper_bound,                    .expression = 1,                }},            },            .overload = .{                .kind = .reject_before_mutation,                .detail = "oversize and concurrent requests fail before workspace bytes change",            },            .risks = .{                .transitive = .{                    .status = .witnessed,                    .detail = "reduction uses byte lanes; predicate effects remain caller-owned",                },                .foreign = .{                    .status = .excluded,                    .detail = "predicate and operating-system effects are caller-owned",                },            },            .obligations = &.{                .{ .key = "reducer_byte_capacity", .role = .capacity_model },                .{ .key = "reducer_byte_acquisition", .role = .custom },                .{ .key = "reducer_byte_oom", .role = .custom },                .{ .key = "reducer_byte_boundaries", .role = .overload },                .{ .key = "reducer_byte_reuse", .role = .overload },                .{ .key = "reducer_byte_sealed", .role = .transitive_risk },                .{ .key = "reducer_byte_callback", .role = .foreign_risk },                .{ .key = "reducer_byte_root", .role = .custom },            },        },        .bindings = .{            .owner = @This(),            .seal = .{                .family = alloc_phase.capacity.selector(@This().activate),                .premise = .{                    .class = .checked_semantic_fact,                    .authority = .checker,                },            },            .teardown = .{                .family = alloc_phase.capacity.selector(@This().deinit),                .premise = .{                    .class = .checked_semantic_fact,                    .authority = .checker,                },            },        },    };    /// Allocates a reduction workspace and divides it into the two lanes, sized    /// for inputs up to `limits.max_input_bytes`. The new workspace is in    /// `.initialization`, and the caller calls `storage.activate()` on it    /// before passing it to `reduce()`. A workspace that is never activated can    /// be freed directly by `storage.deinit()`.    ///    /// ## Errors    /// - `error.CapacityOverflow` when $N + \max(N - 1, 0)$ overflows `usize`.    /// - `error.OutOfMemory` when the allocator declines the request.    pub fn init(allocator: std.mem.Allocator, limits: Limits) InitError!Storage {        const capacity = try Capacity.derive(limits);        const bytes = try allocator.alloc(u8, capacity.storage_bytes);        const owner = Storage{            .phase = .initialization,            .capacity = capacity,            .bytes = bytes,            .current = bytes[0..limits.max_input_bytes],            .candidate = bytes[capacity.candidate_offset..][0..capacity.candidate_bytes],        };        std.debug.assert(owner.current.len == limits.max_input_bytes);        std.debug.assert(owner.candidate.len == capacity.candidate_bytes);        std.debug.assert(owner.current.len + owner.candidate.len == owner.bytes.len);        return owner;    }    /// Moves the workspace from `.initialization` to `.steady`. Once it    /// returns, the workspace owner makes no further heap allocation.    ///    /// ## Preconditions    /// - `self.phase` is `.initialization`.    /// - The backing allocation's length equals `self.capacity.storage_bytes`.    pub fn activate(self: *Storage) void {        std.debug.assert(self.phase == .initialization);        std.debug.assert(self.bytes.len == self.capacity.storage_bytes);        self.phase = .steady;    }    /// Takes exclusive use of the workspace for a run over `input_bytes` bytes.    /// It returns `Regions` holding sub-slices of the backing buffer. It copies    /// nothing into `Regions.current`.    ///    /// ## Preconditions    /// - `self.phase` is `.steady`.    ///    /// ## Errors    /// - `error.ReductionStorageInUse` when `self.in_use` is already true. A    ///   reentrant call, and a call made while an earlier result is still live,    ///   are both turned away without disturbing the hold that is already out.    /// - `error.InputCapacityExceeded` when `input_bytes` exceeds    ///   `max_input_bytes`.    pub fn acquire(self: *Storage, input_bytes: usize) Exhaustion!Regions {        std.debug.assert(self.phase == .steady);        if (self.in_use) return error.ReductionStorageInUse;        if (input_bytes > self.capacity.limits.max_input_bytes) {            return error.InputCapacityExceeded;        }        std.debug.assert(self.current.len == self.capacity.limits.max_input_bytes);        std.debug.assert(self.candidate.len == self.capacity.candidate_bytes);        self.in_use = true;        return .{            .current = self.current[0..input_bytes],            .candidate = self.candidate,        };    }    /// Gives up this run's lease, returning the workspace to steady and idle so    /// it can serve another run. `Result.deinit()` calls it, and it moves the    /// workspace no closer to teardown.    ///    /// ## Preconditions    /// - `self.phase` is `.steady`.    /// - `self.in_use` is true.    pub fn release(self: *Storage) void {        std.debug.assert(self.phase == .steady);        std.debug.assert(self.in_use);        self.in_use = false;        std.debug.assert(!self.in_use);    }    /// Returns a snapshot of this workspace, taken by value at the moment of    /// the call.    pub fn status(self: *const Storage) Status {        return .{            .phase = self.phase,            .in_use = self.in_use,            .storage_bytes = self.capacity.storage_bytes,            .max_input_bytes = self.capacity.limits.max_input_bytes,        };    }    /// Frees the backing allocation and moves the workspace to `.teardown`. It    /// works on an idle steady workspace and on one still in `.initialization`    /// that was never activated. It needs the same allocator `Storage.init()`    /// received.    ///    /// ## Preconditions    /// - `self.phase` is anything other than `.teardown`.    /// - `self.in_use` is false, so every result has had its `deinit()` called.    pub fn deinit(self: *Storage, allocator: std.mem.Allocator) void {        std.debug.assert(self.phase != .teardown);        std.debug.assert(!self.in_use);        std.debug.assert(self.bytes.len == self.capacity.storage_bytes);        self.phase = .teardown;        allocator.free(self.bytes);        self.bytes = &.{};        self.current = &.{};        self.candidate = &.{};    }};

Source: lib/reducer/src/root.zig:351

zig
/// Workspace, allocated up front and double-buffered, that carries reduction in/// steady state.pub const Storage = bytes.Storage;
Called byCallsNo direct callstest sourcelib.reducer.src.bytes.storagetest: byte reduction storage acquires...Storageacquire
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.reducer.src.bytes.storagetest: byte reduction storage acquires...Storageactivate
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.reducer.src.bytes.storagecheckInitFailurestest sourcelib.reducer.src.bytes.storagetest: byte reduction storage acquires...Storagedeinit
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callsprivate sourcelib.reducer.src.bytes.storagecheckInitFailurestest sourcelib.reducer.src.bytes.storagetest: byte reduction storage acquires...Storageinit
Static calls · unresolved targets: 1 · external targets: 1.
Called byCallsNo direct callstest sourcelib.reducer.src.bytes.storagetest: byte reduction storage acquires...Storagerelease
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.reducer.src.bytes.storagetest: byte reduction storage acquires...Storagestatus
Static calls · unresolved targets: 0 · external targets: 0.

Also reachable as

bytes.Storage.

Audit

Definitions12
Public names36
Members6
Version26.7.0
Revisiondaab053ee433