Skip to documentation
SLOP

tiny.trace.TraceWriter

Reference tiny.trace TraceWriter

Defined in tiny.trace.

API (27)

Actions

Public operations.

Fields and members

Public fields and members.

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

Source

Source: lib/trace/src/store/writer/writer.zig:14

zig
pub const Writer = struct {    storage: ?*Storage = null,    root_path: []u8 = &.{},    target_triple: []u8 = &.{},    build_id: []u8 = &.{},    mode: []u8 = &.{},    endian: []u8 = &.{},    manifest: format.Manifest = .{},    block_builder: block.Builder = undefined,    manifest_io_buffer: []u8 = &.{},    manifest_buffer: []u8 = &.{},    path_buffers: [capacity_mod.path_buffer_count][]u8 = .{ &.{}, &.{} },    sql_allocator: std.heap.FixedBufferAllocator = undefined,    database_workspace: sql.FileDatabase.Workspace = undefined,    database_workspace_open: bool = false,    file: sql.FileDatabase = undefined,    file_open: bool = false,    events: sql.Tree = undefined,    chunk_event_count: u64 = 0,    chunk_byte_count: u64 = 0,    event_hasher: std.hash.Wyhash = format.newHasher(),    initialized: bool = false,    finished: bool = false,    pub fn open(        self: *Writer,        storage: *Storage,        root_path: []const u8,        manifest_base: format.Manifest,        trace_limits: format.Limits,    ) !void {        if (self.initialized) return error.TraceWriterAlreadyOpen;        try trace_limits.validate();        const regions = try storage.acquire(.{            .root_path_bytes = root_path.len,            .target_triple_bytes = manifest_base.target_triple.len,            .build_id_bytes = manifest_base.build_id.len,            .mode_bytes = manifest_base.mode.len,            .endian_bytes = manifest_base.endian.len,            .event_bytes = trace_limits.max_event_bytes,        });        var ownership_transferred = false;        errdefer if (!ownership_transferred) storage.release();        std.mem.copyForwards(u8, regions.root_path, root_path);        std.mem.copyForwards(u8, regions.target_triple, manifest_base.target_triple);        std.mem.copyForwards(u8, regions.build_id, manifest_base.build_id);        std.mem.copyForwards(u8, regions.mode, manifest_base.mode);        std.mem.copyForwards(u8, regions.endian, manifest_base.endian);        self.* = .{            .storage = storage,            .root_path = regions.root_path,            .target_triple = regions.target_triple,            .build_id = regions.build_id,            .mode = regions.mode,            .endian = regions.endian,            .manifest = manifest_base,            .block_builder = block.Builder.init(regions.block),            .manifest_io_buffer = regions.manifest_io,            .manifest_buffer = regions.manifest,            .path_buffers = regions.paths,            .sql_allocator = std.heap.FixedBufferAllocator.init(regions.sql),            .initialized = true,        };        ownership_transferred = true;        errdefer self.deinit();        self.manifest.format_version = event.trace_format_version;        self.manifest.target_triple = self.target_triple;        self.manifest.build_id = self.build_id;        self.manifest.mode = self.mode;        self.manifest.endian = self.endian;        self.manifest.status = "open";        self.manifest.limits = trace_limits;        self.manifest.chunk_count = 0;        self.manifest.event_count = 0;        self.manifest.event_bytes = 0;        self.manifest.event_checksum = 0;        self.manifest.block_count = 0;        self.manifest.block_bytes = 0;        try sys.fs.deleteTree(self.root_path);        try self.ensureLayout();        try self.writeManifest();        self.database_workspace = try sql.FileDatabase.Workspace.allocate(            self.sql_allocator.allocator(),            database.workspaceLimits(storage.capacity.database),        );        self.database_workspace_open = true;        self.file = try database.openWriter(            self.sql_allocator.allocator(),            &self.database_workspace,            self.root_path,            storage.capacity.database,        );        self.file_open = true;        self.events = try database.events(&self.file);    }    pub fn deinit(self: *Writer) void {        if (!self.initialized) return;        if (self.file_open) {            self.file.deinit();            self.file_open = false;        }        if (self.database_workspace_open) {            self.database_workspace.deallocate(self.sql_allocator.allocator());            self.database_workspace_open = false;        }        const storage = self.storage.?;        self.* = .{};        storage.release();    }    pub fn sink(self: *Writer) event.Sink {        return .{ .context = self, .appendFn = appendFromSink };    }    pub fn append(self: *Writer, item: event.Event) !void {        if (!self.initialized or self.finished) return error.TraceWriterNotOpen;        const encoded_size = codec.encodedSize(item) catch |err| switch (err) {            error.CapacityOverflow => return error.EventTooLarge,            error.InvalidEvent, error.OutputTooSmall => unreachable,        };        if (encoded_size == 0 or encoded_size > self.manifest.limits.max_event_bytes) {            return error.EventTooLarge;        }        const next_chunk_bytes = std.math.add(u64, self.chunk_byte_count, encoded_size) catch            return error.TraceTooLarge;        if (self.chunk_event_count != 0 and            next_chunk_bytes > self.manifest.limits.max_chunk_bytes)        {            try self.finishChunk();        }        if (!self.block_builder.empty() and !self.block_builder.canAppend(encoded_size)) {            try self.flushBlock();        }        std.debug.assert(self.block_builder.canAppend(encoded_size));        const next_chunk_event_count = std.math.add(u64, self.chunk_event_count, 1) catch            return error.TraceTooLarge;        const next_chunk_byte_count = std.math.add(u64, self.chunk_byte_count, encoded_size) catch            return error.TraceTooLarge;        const next_event_count = std.math.add(u64, self.manifest.event_count, 1) catch            return error.TraceTooLarge;        const next_event_bytes = std.math.add(u64, self.manifest.event_bytes, encoded_size) catch            return error.TraceTooLarge;        const encoded = self.block_builder.append(item, encoded_size) catch |err| switch (err) {            error.CapacityOverflow, error.OutputTooSmall => return error.EventTooLarge,            error.InvalidEvent => unreachable,        };        var key_buffer: [database.key_bytes]u8 = undefined;        const key = database.sequenceKey(&key_buffer, self.manifest.event_count);        database.updateChecksum(&self.event_hasher, key, encoded);        self.chunk_event_count = next_chunk_event_count;        self.chunk_byte_count = next_chunk_byte_count;        self.manifest.event_count = next_event_count;        self.manifest.event_bytes = next_event_bytes;    }    pub fn finish(self: *Writer) !void {        if (!self.initialized or self.finished) return error.TraceWriterNotOpen;        if (self.chunk_event_count != 0) try self.finishChunk();        self.manifest.status = "closed";        self.manifest.event_checksum = self.event_hasher.final();        try self.writeManifest();        self.finished = true;    }    fn appendFromSink(context: *anyopaque, item: event.Event) !void {        const self: *Writer = @ptrCast(@alignCast(context));        try self.append(item);    }    fn finishChunk(self: *Writer) !void {        std.debug.assert(self.chunk_event_count != 0);        const next_chunk_count = std.math.add(u64, self.manifest.chunk_count, 1) catch            return error.TraceTooLarge;        try self.flushBlock();        try database.checkpoint(&self.file);        self.manifest.chunk_count = next_chunk_count;        self.chunk_event_count = 0;        self.chunk_byte_count = 0;    }    fn flushBlock(self: *Writer) !void {        if (self.block_builder.empty()) return;        const encoded = self.block_builder.finish();        const next_block_count = std.math.add(u64, self.manifest.block_count, 1) catch            return error.TraceTooLarge;        const next_block_bytes = std.math.add(u64, self.manifest.block_bytes, encoded.len) catch            return error.TraceTooLarge;        try database.checkpointIfNeeded(&self.file);        var key_buffer: [database.key_bytes]u8 = undefined;        const key = database.sequenceKey(&key_buffer, self.manifest.block_count);        _ = try self.events.put(key, encoded, .{ .durability = .buffered });        self.manifest.block_count = next_block_count;        self.manifest.block_bytes = next_block_bytes;        self.block_builder.reset();    }    fn ensureLayout(self: *Writer) !void {        try sys.fs.createDirPath(self.root_path);        try sys.fs.createDirPath(self.joinedPath(0, "snapshots"));    }    fn writeManifest(self: *Writer) !void {        const manifest_path = self.joinedPath(0, format.manifest_path);        const pending_path = self.joinedPath(1, "manifest.pending");        try format.writeManifest(            self.manifest,            manifest_path,            pending_path,            self.manifest_buffer,            self.manifest_io_buffer,        );    }    fn joinedPath(self: *Writer, buffer_index: usize, relative: []const u8) []const u8 {        std.debug.assert(buffer_index < self.path_buffers.len);        std.debug.assert(self.root_path.len != 0);        std.debug.assert(relative.len <= format.max_relative_path_bytes);        const buffer = self.path_buffers[buffer_index];        var length = self.root_path.len;        @memcpy(buffer[0..length], self.root_path);        if (!sys.path.isSeparator(buffer[length - 1])) {            buffer[length] = sys.path.separator;            length += 1;        }        @memcpy(buffer[length..][0..relative.len], relative);        length += relative.len;        std.debug.assert(length <= buffer.len);        return buffer[0..length];    }};

Source: lib/trace/src/root.zig:64

zig
pub const TraceWriter = store.Writer;
Called byCallstest sourcelib.trace.src.store.reader.testtest: trace reader remains allocator-...private sourcelib.trace.src.store.writer.writer.WriterappendFromSinkstore.format.block.Builderappendstore.format.block.BuildercanAppendstore.format.block.Builderemptystore.format.codecencodedSizestore.format.databasesequenceKey+3 moreTraceWriterappend
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.trace.src.store.reader.testtest: trace reader remains allocator-...TraceWriteropenTraceWriterdeinit
Static calls · unresolved targets: 0 · external targets: 4.
Called byCallstest sourcelib.trace.src.store.reader.testtest: trace reader remains allocator-...private sourcelib.trace.src.store.writer.writer.WriterfinishChunkprivate sourcelib.trace.src.store.writer.writer.WriterwriteManifestTraceWriterfinish
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallstest sourcelib.trace.src.store.reader.testtest: trace reader remains allocator-...store.format.block.Builderinitstore.format.databaseeventsstore.format.databaseopenWriterstore.format.databaseworkspaceLimitsTraceWriterdeinit+2 moreTraceWriteropen
Static calls · unresolved targets: 0 · external targets: 6.

Also reachable as

store.Writer.

Complete call list for TraceWriter.append

8 direct calls.

Complete call list for TraceWriter.open

7 direct calls.

Audit

Definitions6
Public names12
Members22
Version26.7.0
Revisiondaab053ee433