Skip to documentation
SLOP

tiny.sql.WalWriter

Reference tiny.sql WalWriter

Defined in wal.

API (39)

Actions

Public operations.

Types and contracts

Public types and contracts.

Fields and members

Public fields and members.

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

Source

Source: lib/sql/src/wal.zig:637

zig
pub const Writer = struct {    pub const storage_alignment: usize = @alignOf(u8);    pub const Storage = []align(storage_alignment) u8;    pub const Limits = struct {        header: Header,        frames: usize,    };    pub const Capacity = struct {        frames: usize,        storage_bytes: usize,        pub const DeriveError = error{CapacityOverflow};        pub fn derive(limits: Limits) DeriveError!Capacity {            const frame_bytes = std.math.mul(usize, limits.frames, frame_size) catch {                return error.CapacityOverflow;            };            const storage_bytes = std.math.add(usize, header_size, frame_bytes) catch {                return error.CapacityOverflow;            };            return .{ .frames = limits.frames, .storage_bytes = storage_bytes };        }    };    pub const Exhaustion = error{WalFull};    pub const InitError = Capacity.DeriveError || error{StorageTooShort};    pub const LoadError = ReadError || Exhaustion;    pub const ControlledLoadError = LoadError || error{Interrupted};    pub const work_limits: alloc_phase.capacity.WorkLimits = .{        .transition_steps_max = 1,        .cleanup_steps_per_call_max = 0,        .cleanup_calls_at_capacity_max = 0,    };    pub const claim: alloc_phase.capacity.Declaration = .{        .source = .{            .id = "sql.wal_writer",            .kind = .phase_static,            .limit_source = .caller,            .storage = .{                .covered = &.{                    .{                        .id = "exact_header_and_committed_frame_byte_region",                        .lifetime = .steady,                        .detail = "mutable borrow of the caller-provisioned exact header and frame byte region",                    },                    .{                        .id = "invisible_staged_frame_tail_transferred_into_the_co_0ed8d0c7aca0",                        .lifetime = .transferred,                        .detail = "invisible staged frame tail transferred into the committed prefix",                    },                },                .excluded = &.{                    "caller-owned storage outside the exact borrowed prefix",                    "caller-owned page images and recovery source bytes",                    "pager frame indexes, page indexes, checkpoint plans, files, and I/O runtime state",                    "trace instrumentation and allocator implementation state",                },            },            .capacity = .{                .inputs = &.{                    alloc_phase.capacity.bindInput(Limits, "frames", "frames"),                },                .type_selectors = &.{                    alloc_phase.capacity.bindType([frame_size]u8, "walframebytes"),                    alloc_phase.capacity.bindType([header_size]u8, "walheaderbytes"),                },                .nodes = &.{                    .{ .input = 0 },                    .{ .scale = .{ .node = 0, .coefficient = .{ .size_of_concrete_type = 0 } } },                    .{ .constant = 1 },                    .{ .scale = .{ .node = 2, .coefficient = .{ .size_of_concrete_type = 1 } } },                    .{ .add = .{ .left = 1, .right = 3 } },                },                .assertions = &.{.{                    .scope = .closure_total,                    .measure = .retained,                    .relation = .exact,                    .expression = 4,                }},            },            .overload = .{                .kind = .reject_before_mutation,                .detail = "append staging and recovery load return WalFull before bytes length salt or checksum mutate",            },            .risks = .{                .transitive = .{                    .status = .open,                    .detail = "pager indexes and trace instrumentation are outside the writer-owned byte region",                },                .foreign = .{                    .status = .open,                    .detail = "file reads and writes that consume WAL bytes are owned by the file database",                },            },            .work = .{ .equation = "transition_steps <= transition_steps_max" },            .obligations = &.{                .{ .key = "sql_wal_capacity", .role = .capacity_model },                .{ .key = "sql_wal_storage_rejection", .role = .initialization_failure },                .{ .key = "sql_wal_sealed", .role = .overload },                .{ .key = "sql_wal_work_bound", .role = .work_bound },                .{ .key = "sql_wal_semantics", .role = .custom },                .{ .key = "sql_wal_staged_transfer", .role = .custom },                .{ .key = "sql_wal_corruption", .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,                },            },        },    };    phase: alloc_phase.capacity.Phase,    capacity: Capacity,    storage: Storage,    len: usize,    salt: Salt,    checksum: Checksum,    pub const Position = struct {        len: usize,        checksum_first: u32,        checksum_second: u32,    };    pub fn init(storage: Storage, limits: Limits) InitError!Writer {        const capacity = try Capacity.derive(limits);        if (storage.len < capacity.storage_bytes) return error.StorageTooShort;        const borrowed = storage[0..capacity.storage_bytes];        const checksum = encodeHeader(borrowed[0..header_size], limits.header);        return .{            .phase = .initialization,            .capacity = capacity,            .storage = borrowed,            .len = header_size,            .salt = limits.header.salt,            .checksum = checksum,        };    }    pub fn activate(self: *Writer) void {        std.debug.assert(self.phase == .initialization);        std.debug.assert(self.storage.len == self.capacity.storage_bytes);        std.debug.assert(self.len == header_size);        self.phase = .steady;    }    pub fn deinit(self: *Writer) Storage {        std.debug.assert(self.phase != .teardown);        std.debug.assert(self.storage.len == self.capacity.storage_bytes);        self.phase = .teardown;        const storage = self.storage;        self.* = undefined;        return storage;    }    pub fn bytes(self: *const Writer) []const u8 {        std.debug.assert(self.phase == .steady);        std.debug.assert(self.len <= self.storage.len);        return self.storage[0..self.len];    }    pub fn frameCount(self: *const Writer) usize {        std.debug.assert(self.phase == .steady);        return (self.len - header_size) / frame_size;    }    pub fn frameCapacity(self: *const Writer) usize {        std.debug.assert(self.phase == .steady);        return self.capacity.frames;    }    pub fn byteCapacity(self: *const Writer) usize {        std.debug.assert(self.phase == .steady);        return self.capacity.storage_bytes;    }    pub fn remainingFrames(self: *const Writer) usize {        std.debug.assert(self.phase == .steady);        return self.capacity.frames - self.frameCount();    }    pub fn position(self: *const Writer) Position {        std.debug.assert(self.phase == .steady);        return .{            .len = self.len,            .checksum_first = self.checksum.first,            .checksum_second = self.checksum.second,        };    }    pub fn restore(self: *Writer, position_value: Position) void {        std.debug.assert(self.phase == .steady);        std.debug.assert(position_value.len >= header_size);        std.debug.assert((position_value.len - header_size) % frame_size == 0);        std.debug.assert(position_value.len <= self.len);        self.len = position_value.len;        self.checksum = .{            .first = position_value.checksum_first,            .second = position_value.checksum_second,        };    }    pub fn load(self: *Writer, source: []const u8, committed_len: usize) LoadError!void {        return self.loadControlled(source, committed_len, .{}) catch |err| switch (err) {            error.Interrupted => unreachable,            else => return @errorCast(err),        };    }    pub fn loadControlled(        self: *Writer,        source: []const u8,        committed_len: usize,        control: Control,    ) ControlledLoadError!void {        std.debug.assert(self.phase == .steady);        if (committed_len > source.len) return error.InvalidWal;        if (committed_len > self.capacity.storage_bytes) return error.WalFull;        var reader = try Reader.initControlled(source[0..committed_len], control);        const frames_max = (committed_len - header_size) / frame_size;        var frame_index: usize = 0;        while (frame_index < frames_max) : (frame_index += 1) {            if (try reader.nextControlled(control) == null) break;        }        if (reader.offset != committed_len) return error.InvalidWal;        var copied: usize = 0;        var chunks: usize = 0;        const chunks_max = std.math.divCeil(            usize,            committed_len,            controlled_copy_chunk_bytes,        ) catch unreachable;        while (copied < committed_len) : (chunks += 1) {            std.debug.assert(chunks < chunks_max);            try control.check();            const end = copied + @min(                controlled_copy_chunk_bytes,                committed_len - copied,            );            std.mem.copyForwards(u8, self.storage[copied..end], source[copied..end]);            copied = end;        }        try control.check();        self.len = committed_len;        self.salt = reader.salt;        self.checksum = reader.checksum;    }    pub fn append(self: *Writer, page_id: u32, db_page_count: u32, image: *const [page.size]u8) Exhaustion!void {        const phase = trace.scope("wal.append");        defer phase.end();        std.debug.assert(self.phase == .steady);        if (self.remainingFrames() == 0) return error.WalFull;        var frame_header = @as([frame_header_size]u8, @splat(0));        writeU32(frame_header[0..4], page_id);        writeU32(frame_header[4..8], db_page_count);        writeU32(frame_header[8..12], self.salt.first);        writeU32(frame_header[12..16], self.salt.second);        var checksum = self.checksum;        checksum.update(frame_header[0..8]);        checksum.update(image[0..]);        writeU32(frame_header[16..20], checksum.first);        writeU32(frame_header[20..24], checksum.second);        @memcpy(self.storage[self.len..][0..frame_header_size], frame_header[0..]);        @memcpy(self.storage[self.len + frame_header_size ..][0..page.size], image[0..]);        self.len += frame_size;        self.checksum = checksum;        trace.progress("wal.append.complete");    }    pub fn stagePage(self: *Writer, position_value: Position, index: usize, page_id: u32, image: *const [page.size]u8) Exhaustion!void {        std.debug.assert(self.phase == .steady);        std.debug.assert(position_value.len == self.len);        const offset = try self.stagedFrameOffset(position_value, index);        writeU32(self.storage[offset..][0..4], page_id);        const staged = self.storage[offset + frame_header_size ..][0..page.size];        if (staged != image) @memcpy(staged, image);    }    pub fn stagedPage(self: *const Writer, position_value: Position, index: usize) []const u8 {        std.debug.assert(self.phase == .steady);        std.debug.assert(position_value.len == self.len);        const offset = self.stagedFrameOffset(position_value, index) catch unreachable;        return self.storage[offset + frame_header_size ..][0..page.size];    }    /// Returns a staged image for editing in place. Staging the returned    /// image again copies nothing, and the checksum covers the edits    /// when the frame commits.    pub fn stagedPageMut(self: *Writer, position_value: Position, index: usize) *[page.size]u8 {        std.debug.assert(self.phase == .steady);        std.debug.assert(position_value.len == self.len);        const offset = self.stagedFrameOffset(position_value, index) catch unreachable;        return self.storage[offset + frame_header_size ..][0..page.size];    }    pub fn stagedPageId(self: *const Writer, position_value: Position, index: usize) u32 {        std.debug.assert(self.phase == .steady);        const offset = self.stagedFrameOffset(position_value, index) catch unreachable;        return readU32(self.storage[offset..][0..4]);    }    pub fn swapStagedFrames(self: *Writer, position_value: Position, left_index: usize, right_index: usize) void {        std.debug.assert(self.phase == .steady);        std.debug.assert(position_value.len == self.len);        if (left_index == right_index) return;        const left_offset = self.stagedFrameOffset(position_value, left_index) catch unreachable;        const right_offset = self.stagedFrameOffset(position_value, right_index) catch unreachable;        const left: *[frame_size]u8 = self.storage[left_offset..][0..frame_size];        const right: *[frame_size]u8 = self.storage[right_offset..][0..frame_size];        const temporary = left.*;        left.* = right.*;        right.* = temporary;    }    pub fn commitStagedFrame(self: *Writer, position_value: Position, index: usize, db_page_count: u32) void {        std.debug.assert(self.phase == .steady);        const offset = self.stagedFrameOffset(position_value, index) catch unreachable;        std.debug.assert(self.len == offset);        const frame_header = self.storage[offset..][0..frame_header_size];        const image = self.storage[offset + frame_header_size ..][0..page.size];        std.debug.assert(readU32(frame_header[0..4]) != 0);        writeU32(frame_header[4..8], db_page_count);        writeU32(frame_header[8..12], self.salt.first);        writeU32(frame_header[12..16], self.salt.second);        var checksum = self.checksum;        checksum.update(frame_header[0..8]);        checksum.update(image);        writeU32(frame_header[16..20], checksum.first);        writeU32(frame_header[20..24], checksum.second);        self.len += frame_size;        self.checksum = checksum;    }    pub fn rewriteTail(self: *Writer, checkpoint_mark: usize, header: Header) void {        std.debug.assert(self.phase == .steady);        std.debug.assert(checkpoint_mark <= self.frameCount());        const source = self.bytes();        var reader = Reader.init(source) catch @panic("invalid wal writer storage");        self.writeHeader(header);        while (reader.next() catch @panic("invalid wal writer storage")) |frame| {            if (frame.index <= checkpoint_mark) continue;            const image = frame.image[0..page.size].*;            self.append(frame.page_id, frame.db_page_count, &image) catch unreachable;        }        if (reader.offset != source.len) @panic("invalid wal writer storage");    }    fn writeHeader(self: *Writer, header: Header) void {        const checksum = encodeHeader(self.storage[0..header_size], header);        self.len = header_size;        self.salt = header.salt;        self.checksum = checksum;    }    fn stagedFrameOffset(self: *const Writer, position_value: Position, index: usize) Exhaustion!usize {        std.debug.assert(position_value.len >= header_size);        std.debug.assert((position_value.len - header_size) % frame_size == 0);        const staged_bytes = std.math.mul(usize, index, frame_size) catch return error.WalFull;        const offset = std.math.add(usize, position_value.len, staged_bytes) catch return error.WalFull;        if (offset > self.storage.len or frame_size > self.storage.len - offset) return error.WalFull;        return offset;    }};

Source: lib/sql/src/root.zig:303

zig
pub const WalWriter = wal.Writer;
Called byCallsNo direct callsprivate sourcelib.sql.src.pager.PagerWorkspace.Capacityderivetest sourcelib.sql.src.waltest: wal writer capacity matches an ...test sourcelib.sql.src.waltest: wal writer is sealed before max...test sourcelib.sql.src.waltest: wal writer rejects short storag...private sourcelib.sql.src.waltestingWriterWalWriter.Capacityderive
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsPagerinittest sourcelib.sql.src.waltest: wal writer is sealed before max...test sourcelib.sql.src.waltest: wal writer rejects short storag...private sourcelib.sql.src.waltestingWriterWalWriteractivate
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsPagerappendWalWalWriterrewriteTailtest sourcelib.sql.src.waltest: wal writer is sealed before max...traceprogressWalWriterremainingFramesprivate sourcelib.sql.src.walwriteU32WalWriterappend
Static calls · unresolved targets: 1 · external targets: 2.
Called byCallsNo direct callsPagerwalCapacityBytesWalWriterbyteCapacity
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsPagerwalBytesWalWriterrewriteTailtest sourcelib.sql.src.waltest: wal writer is sealed before max...WalWriterbytes
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsPagercommitStagedWaltest sourcelib.sql.src.waltest: wal writer is sealed before max...private sourcelib.sql.src.wal.WriterstagedFrameOffsetprivate sourcelib.sql.src.walreadU32private sourcelib.sql.src.walwriteU32WalWritercommitStagedFrame
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsNo direct callsPagerdeinittest sourcelib.sql.src.waltest: wal writer is sealed before max...test sourcelib.sql.src.waltest: wal writer rejects short storag...WalWriterdeinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsPagerreplaceWalControlledWalWriterframeCapacity
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsPagerframeCountprivate sourcelib.sql.src.pager.PagerindexAppendedWalFrameprivate sourcelib.sql.src.pager.PagerrebuildWalFramesFromJournalControlledWalWriterremainingFramesWalWriterrewriteTailtest sourcelib.sql.src.waltest: wal writer is sealed before max...WalWriterframeCount
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsPagerinittest sourcelib.sql.src.waltest: wal writer capacity matches an ...test sourcelib.sql.src.waltest: wal writer is sealed before max...test sourcelib.sql.src.waltest: wal writer rejects short storag...private sourcelib.sql.src.waltestingWriterprivate sourcelib.sql.src.walencodeHeaderWalWriterinit
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallstest sourcelib.sql.src.waltest: wal writer is sealed before max...WalWriterloadControlledWalWriterload
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsPagerreplaceWalControlledWalWriterloadWalReaderinitControlledWalWriterloadControlled
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallsNo direct callsPagercanRestorePagerpositiontest sourcelib.sql.src.waltest: wal writer is sealed before max...WalWriterposition
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsPagerappendWalPagerreservePagerwalStagingCapacityWalWriterappendWalWriterframeCountWalWriterremainingFrames
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsPagerrestoreWalWriterrestore
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate sourcelib.sql.src.pager.PagerfinishCheckpointFramestest sourcelib.sql.src.waltest: wal writer is sealed before max...WalReaderinitWalReadernextWalWriterappendWalWriterbytesWalWriterframeCountprivate sourcelib.sql.src.wal.WriterwriteHeaderWalWriterrewriteTail
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsPagerstageWalPagetest sourcelib.sql.src.waltest: wal writer is sealed before max...private sourcelib.sql.src.wal.WriterstagedFrameOffsetprivate sourcelib.sql.src.walwriteU32WalWriterstagePage
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsPagerstagedWalPageprivate sourcelib.sql.src.wal.WriterstagedFrameOffsetWalWriterstagedPage
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsPagerstagedWalPageIdprivate sourcelib.sql.src.wal.WriterstagedFrameOffsetprivate sourcelib.sql.src.walreadU32WalWriterstagedPageId
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsPagerstagedWalPageMutprivate sourcelib.sql.src.wal.WriterstagedFrameOffsetWalWriterstagedPageMut
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsPagerswapStagedWalFramesprivate sourcelib.sql.src.wal.WriterstagedFrameOffsetWalWriterswapStagedFrames
Static calls · unresolved targets: 0 · external targets: 0.

Audit

Definitions34
Public names68
Members15
Version26.7.0
Revisiondaab053ee433