Skip to documentation
SLOP

alloc_fixed.Chunks

Reference alloc_fixed Chunks

Internal implementation documentation

Defined in alloc_fixed.

A chunked allocator that builds a result across several allocations and then either commits backing chunks to an outer owner through retain() or invokes upstream frees for rollback through discard().

API (7)

Actions

Public operations.

Types and contracts

Public types and contracts.

Fields and members

Public fields and members.

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

Source

Source: lib/alloc/fixed/src/fixed.zig:286

zig
/// A chunked allocator that builds a result across several allocations and/// then either commits backing chunks to an outer owner through `retain()` or/// invokes upstream frees for rollback through `discard()`. It requests/// chunks from an upstream backing allocator as needed, tracking at most 64/// chunk descriptors simultaneously in an array fixed at compile time./// Initializing an instance performs no initial backing allocation, acquiring/// chunks only as requests demand them.////// ### Growth schedule and capacity bounds/// Fresh chunks follow a growth schedule that starts at `initial_capacity`,/// doubles after each successful fresh chunk, and stops growing at/// `maximum_capacity`. Each fresh chunk has `@max(scheduled_capacity, len)`/// bytes, so requests larger than `maximum_capacity` are allowed but need/// both a free descriptor and a successful backing allocation. Because/// doubling calculations use the scheduled capacity rather than the actual/// requested length, oversized requests do not advance the growth progression/// faster. The `maximum_capacity` parameter caps the growth schedule itself/// rather than limiting individual request sizes or total storage.////// Calling `retain()` clears this descriptor table without freeing backing/// memory, so committed chunks no longer occupy slots in the table and more/// than 64 total chunks can be allocated across successive retain cycles. The/// upstream lifetime owner must reclaim that committed memory. When an/// allocation fails, the failure stems either from the backing allocator/// returning `null` or from exhausting the 64 descriptor slots. Both/// conditions return an allocation failure to the caller.////// ### Transaction discipline/// - Calling `retain()` commits every chunk it holds to the backing lifetime///   owner, such as an enclosing `std.heap.ArenaAllocator`./// - Calling `retain()` clears the descriptor tracking without freeing the///   backing memory./// - A chunk that was retained can no longer be freed through///   `Chunks.discard()`./// - Calling `discard()` frees every tracked chunk in reverse order back to the///   upstream allocator and puts the growth schedule back at///   `initial_capacity`.////// ### Resize behavior/// In `rawResize`, shrinking returns `true` at once without consulting the/// active chunk buffer, leaving the bump frontier where it was. Growing in/// place looks at the active tail chunk alone, `self.current()`. A slice/// allocated in an earlier chunk cannot grow in place.pub const Chunks = struct {    /// Internal chunk storage holding the buffer descriptors and the growth    /// state that the methods work through. The owner maintains it, so a caller    /// accesses storage through `retain` and `discard` and takes no copy of it    /// and makes no direct changes.    inner: ChunkStorage,    const Self = @This();    /// Number of chunk descriptors tracked at one time, fixed at 64 to cap how    /// many chunks one instance holds at a time.    pub const maximum_chunk_count = ChunkStorage.maximum_chunk_count;    /// Starts a `Chunks` instance to open an allocation transaction over an    /// allocator the caller already has. It asserts that `initial_capacity > 0`    /// and that `maximum_capacity >= initial_capacity`. It allocates nothing    /// here: chunks are requested from the backing allocator as they are    /// needed.    pub fn init(        backing: Allocator,        initial_capacity: usize,        maximum_capacity: usize,    ) Self {        return .{ .inner = .init(            backing,            initial_capacity,            maximum_capacity,        ) };    }    /// Returns a borrowed `std.mem.Allocator` handle pointing at `self` to pass    /// to code that allocates. The `self` instance stays alive at one memory    /// address while the handle is in use.    pub fn allocator(self: *Self) Allocator {        return .{ .ptr = self, .vtable = &vtable };    }    /// Reports whether a given handle came from a `Chunks` instance, allowing a    /// caller to allocate straight into an open transaction when handed one. It    /// compares the candidate's vtable pointer against the `Chunks` vtable.    pub fn isAllocator(candidate: Allocator) bool {        return candidate.vtable == &vtable;    }    /// Commits every tracked chunk to the upstream backing owner and clears    /// tracking metadata when work succeeds. It sets the chunk descriptor count    /// to zero without freeing any backing memory. It leaves the current growth    /// schedule, `next_capacity`, as it is. Once retained, the backing memory    /// can no longer be freed through `Chunks.discard()`, and reclaiming it    /// belongs to the upstream backing owner.    pub fn retain(self: *Self) void {        self.inner.retain();    }    /// Rolls back an uncommitted transaction after failure by freeing all    /// tracked chunks to the backing allocator in reverse order. This    /// invalidates any allocations residing in those chunks and resets    /// `next_capacity` to `initial_capacity`. Chunks committed by an earlier    /// call to `retain()` are untouched and remain allocated. Actual physical    /// reuse of the freed memory depends on the free policy of the backing    /// allocator.    pub fn discard(self: *Self) void {        self.inner.discard();    }    fn rawAlloc(        context: *anyopaque,        len: usize,        alignment: Alignment,        return_address: usize,    ) ?[*]u8 {        const self: *Self = @ptrCast(@alignCast(context));        return self.inner.allocate(.retained, len, alignment, return_address);    }    fn rawResize(        context: *anyopaque,        memory: []u8,        alignment: Alignment,        new_len: usize,        return_address: usize,    ) bool {        const self: *Self = @ptrCast(@alignCast(context));        return self.inner.resize(memory, alignment, new_len, return_address);    }    fn rawRemap(        context: *anyopaque,        memory: []u8,        alignment: Alignment,        new_len: usize,        return_address: usize,    ) ?[*]u8 {        const self: *Self = @ptrCast(@alignCast(context));        return self.inner.remap(            .retained,            memory,            alignment,            new_len,            return_address,        );    }    fn rawFree(        context: *anyopaque,        memory: []u8,        alignment: Alignment,        return_address: usize,    ) void {        const self: *Self = @ptrCast(@alignCast(context));        self.inner.free(.retained, memory, alignment, return_address);    }    const vtable: Allocator.VTable = .{        .alloc = rawAlloc,        .resize = rawResize,        .remap = rawRemap,        .free = rawFree,    };};

Source: lib/alloc/fixed/src/root.zig:407

zig
/// `Chunks` builds a result across several allocations, committing backing/// chunks to an outer owner through `retain()` or invoking upstream frees for/// rollback through `discard()`.////// Fresh chunks requested from the backing allocator follow a growth schedule/// that starts at `initial_capacity`, doubles after each successful fresh/// chunk, and stops growing at `maximum_capacity`, with each fresh chunk/// sized to `@max(scheduled_capacity, len)`. Requests larger than the/// scheduled size are permitted without altering the doubling calculation,/// but can fail from exhausted descriptor slots or backing allocation/// failure.////// The owner tracks at most 64 chunk descriptors simultaneously. Calling/// `retain()` clears the descriptor table without freeing backing memory,/// leaving committed storage for the upstream lifetime owner to reclaim.pub const Chunks = fixed.Chunks;
Called byCallsNo direct callstest sourcelib.alloc.fixed.src.testtest: chunked fixed buffer bounds rol...test sourcelib.alloc.fixed.src.testtest: chunked fixed buffer caps sched...test sourcelib.alloc.fixed.src.testtest: chunked fixed buffer discards u...test sourcelib.alloc.fixed.src.testtest: chunked fixed buffer retains co...test sourcelib.alloc.fixed.src.testtest: recycling chunks stay distinct ...test sourcelib.alloc.fixed.src.testtest: recycling chunks unwind a faile...Chunksallocator
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.alloc.fixed.src.testtest: chunked fixed buffer bounds rol...test sourcelib.alloc.fixed.src.testtest: chunked fixed buffer discards u...test sourcelib.alloc.fixed.src.testtest: recycling chunks stay distinct ...test sourcelib.alloc.fixed.src.testtest: recycling chunks unwind a faile...private sourcelib.alloc.fixed.src.fixed.ChunkStoragediscardChunksdiscard
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.alloc.fixed.src.testtest: chunked fixed buffer bounds rol...test sourcelib.alloc.fixed.src.testtest: chunked fixed buffer caps sched...test sourcelib.alloc.fixed.src.testtest: chunked fixed buffer discards u...test sourcelib.alloc.fixed.src.testtest: chunked fixed buffer retains co...test sourcelib.alloc.fixed.src.testtest: recycling chunks stay distinct ...test sourcelib.alloc.fixed.src.testtest: recycling chunks unwind a faile...Chunksinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.alloc.fixed.src.testtest: recycling chunks stay distinct ...ChunksisAllocator
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.alloc.fixed.src.testtest: chunked fixed buffer retains co...test sourcelib.alloc.fixed.src.testtest: recycling chunks unwind a faile...private sourcelib.alloc.fixed.src.fixed.ChunkStorageretainChunksretain
Static calls · unresolved targets: 0 · external targets: 0.

Audit

Definitions7
Public names7
Members1
Version26.7.0
Revisiondaab053ee433