Skip to documentation
SLOP

tiny.trace.store.format.block

Reference tiny.trace store format block

Defined in store.format.

API (15)

Actions

Public operations.

Types and contracts

Public types and contracts.

Values and defaults

Public values and defaults.

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

Source

Called byCallstest sourcelib.trace.src.store.format.blocktest: binary event block rejects trun...test sourcelib.trace.src.store.format.blocktest: binary event block round trips ...test sourcelib.trace.src.store.reader.streamtest: reader decode failure leaves th...test sourcelib.trace.src.store.reader.streamtest: reader limit failure leaves the...TraceWriterappendstore.format.block.BuildercanAppendstore.format.block.Builderappend
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callsstore.format.block.BuilderappendTraceWriterappendstore.format.block.BuildercanAppend
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsstore.format.block.BuilderfinishTraceWriterappendprivate sourcelib.trace.src.store.writer.writer.WriterflushBlockstore.format.block.Builderempty
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.trace.src.store.format.blocktest: binary event block rejects trun...test sourcelib.trace.src.store.format.blocktest: binary event block round trips ...test sourcelib.trace.src.store.reader.streamtest: reader decode failure leaves th...test sourcelib.trace.src.store.reader.streamtest: reader limit failure leaves the...private sourcelib.trace.src.store.writer.writer.WriterflushBlockstore.format.block.Builderemptystore.format.block.Builderfinish
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.trace.src.store.format.blocktest: binary event block rejects trun...test sourcelib.trace.src.store.format.blocktest: binary event block round trips ...test sourcelib.trace.src.store.reader.streamtest: reader decode failure leaves th...test sourcelib.trace.src.store.reader.streamtest: reader limit failure leaves the...TraceWriteropenstore.format.block.Builderinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.trace.src.store.writer.writer.WriterflushBlockstore.format.block.Builderreset
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.trace.src.store.format.blocktest: binary event block round trips ...store.format.block.Viewpeekstore.format.block.Viewadvance
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.trace.src.store.format.blocktest: binary event block rejects trun...test sourcelib.trace.src.store.format.blocktest: binary event block round trips ...private sourcelib.trace.src.store.reader.stream.ReaderloadBlockprivate sourcelib.trace.src.store.reader.streamtestReaderForBlockstore.format.block.Viewinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsstore.format.block.Viewadvancetest sourcelib.trace.src.store.format.blocktest: binary event block round trips ...store.format.block.Viewpeek
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsTraceReaderCapacityderivetest sourcelib.trace.src.store.reader.capacitytest: trace reader capacity matches i...TraceReaderopenTraceWriterCapacityderivetest sourcelib.trace.src.store.writer.capacitytest: trace writer capacity matches i...store.format.blockcapacity
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/trace/src/store/format/block.zig

zig
const std = @import("std");const event = @import("../../root.zig").event;const codec = @import("codec.zig");pub const target_bytes: usize = 256 * 1024;pub const header_bytes: usize = 16;pub const record_header_bytes: usize = 4;const magic = [_]u8{ 't', 'r', 'c', 'b' };const version: u8 = 1;const version_offset: usize = 4;const reserved_offset: usize = 5;const event_count_offset: usize = 8;const payload_bytes_offset: usize = 12;pub fn capacity(max_event_bytes: usize) error{CapacityOverflow}!usize {    const event_record_bytes = std.math.add(usize, record_header_bytes, max_event_bytes) catch        return error.CapacityOverflow;    const minimum = std.math.add(usize, header_bytes, event_record_bytes) catch        return error.CapacityOverflow;    return @max(target_bytes, minimum);}pub const Builder = struct {    bytes: []u8,    len: usize = header_bytes,    event_count: u32 = 0,    pub fn init(bytes: []u8) Builder {        std.debug.assert(bytes.len >= header_bytes + record_header_bytes);        return .{ .bytes = bytes };    }    pub fn empty(self: *const Builder) bool {        return self.event_count == 0;    }    pub fn canAppend(self: *const Builder, event_bytes: usize) bool {        const record_bytes = std.math.add(usize, record_header_bytes, event_bytes) catch return false;        return record_bytes <= self.bytes.len - self.len;    }    pub fn append(self: *Builder, item: event.Event, event_bytes: usize) codec.Error![]u8 {        std.debug.assert(event_bytes <= std.math.maxInt(u32));        std.debug.assert(self.canAppend(event_bytes));        if (self.event_count == std.math.maxInt(u32)) return error.CapacityOverflow;        const prefix = self.bytes[self.len..][0..record_header_bytes];        std.mem.writeInt(u32, prefix, @intCast(event_bytes), .big);        const start = self.len + record_header_bytes;        const encoded = try codec.encode(self.bytes[start..][0..event_bytes], item);        std.debug.assert(encoded.len == event_bytes);        self.len = start + encoded.len;        self.event_count += 1;        return encoded;    }    pub fn finish(self: *Builder) []const u8 {        std.debug.assert(!self.empty());        @memset(self.bytes[0..header_bytes], 0);        @memcpy(self.bytes[0..magic.len], &magic);        self.bytes[version_offset] = version;        std.mem.writeInt(u32, self.bytes[event_count_offset..][0..4], self.event_count, .big);        std.mem.writeInt(u32, self.bytes[payload_bytes_offset..][0..4], @intCast(self.len - header_bytes), .big);        return self.bytes[0..self.len];    }    pub fn reset(self: *Builder) void {        self.len = header_bytes;        self.event_count = 0;    }};pub const View = struct {    bytes: []u8,    offset: usize = header_bytes,    remaining: u32,    pub fn init(bytes: []u8) error{InvalidBlock}!View {        if (bytes.len < header_bytes) return error.InvalidBlock;        if (!std.mem.eql(u8, bytes[0..magic.len], &magic)) return error.InvalidBlock;        if (bytes[version_offset] != version) return error.InvalidBlock;        for (bytes[reserved_offset..event_count_offset]) |byte| {            if (byte != 0) return error.InvalidBlock;        }        const event_count = std.mem.readInt(u32, bytes[event_count_offset..][0..4], .big);        const payload_bytes: usize = std.mem.readInt(u32, bytes[payload_bytes_offset..][0..4], .big);        if (event_count == 0 or payload_bytes != bytes.len - header_bytes) return error.InvalidBlock;        var offset = header_bytes;        for (0..event_count) |_| {            if (record_header_bytes > bytes.len - offset) return error.InvalidBlock;            const event_bytes: usize = std.mem.readInt(u32, bytes[offset..][0..record_header_bytes], .big);            offset += record_header_bytes;            if (event_bytes == 0 or event_bytes > bytes.len - offset) return error.InvalidBlock;            offset += event_bytes;        }        if (offset != bytes.len) return error.InvalidBlock;        return .{ .bytes = bytes, .remaining = event_count };    }    pub fn peek(self: *const View) ?[]u8 {        if (self.remaining == 0) return null;        const event_bytes: usize = std.mem.readInt(            u32,            self.bytes[self.offset..][0..record_header_bytes],            .big,        );        return self.bytes[self.offset + record_header_bytes ..][0..event_bytes];    }    pub fn advance(self: *View) void {        std.debug.assert(self.remaining != 0);        const encoded = self.peek().?;        self.offset += record_header_bytes + encoded.len;        self.remaining -= 1;    }};test "binary event block round trips bounded records" {    var bytes: [512]u8 = undefined;    var builder = Builder.init(&bytes);    const first = event.Event.user(.{ .seq = 1 }, "first", "payload");    const second = event.Event.user(.{ .seq = 2 }, "second", "");    _ = try builder.append(first, try codec.encodedSize(first));    _ = try builder.append(second, try codec.encodedSize(second));    const encoded = builder.finish();    try std.testing.expectEqualSlices(u8, "trcb", encoded[0..magic.len]);    var view = try View.init(@constCast(encoded));    try std.testing.expect(first.eqlForReplay(try codec.decode(view.peek().?)));    view.advance();    try std.testing.expect(second.eqlForReplay(try codec.decode(view.peek().?)));    view.advance();    try std.testing.expectEqual(@as(?[]u8, null), view.peek());}test "binary event block rejects truncation and trailing bytes" {    var bytes: [256]u8 = undefined;    var builder = Builder.init(&bytes);    const item = event.Event.user(.{}, "event", "payload");    _ = try builder.append(item, try codec.encodedSize(item));    const encoded = builder.finish();    try std.testing.expectError(error.InvalidBlock, View.init(@constCast(encoded[0 .. encoded.len - 1])));    bytes[encoded.len] = 0;    try std.testing.expectError(error.InvalidBlock, View.init(bytes[0 .. encoded.len + 1]));}

Source: lib/trace/src/store/format/root.zig:1

zig
pub const block = @import("block.zig");

Audit

Definitions16
Public names16
Members6
Version26.7.0
Revisiondaab053ee433