tiny.trace.TraceWriter
Defined in tiny.trace.
API (27)
Actions
Public operations.
Fields and members
Public fields and members.
block_builderbuild_idchunk_byte_countchunk_event_countdatabase_workspacedatabase_workspace_openendianevent_hashereventsfilefile_openfinishedinitializedmanifestmanifest_buffermanifest_io_buffermodepath_buffersroot_pathsql_allocatorstoragetarget_triple
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;Also reachable as
Complete call list for TraceWriter.append
8 direct calls.
tiny.trace.store.format.block.Builder.append[method] atlib/trace/src/store/format/block.zig:43tiny.trace.store.format.block.Builder.canAppend[method] atlib/trace/src/store/format/block.zig:38tiny.trace.store.format.block.Builder.empty[method] atlib/trace/src/store/format/block.zig:34tiny.trace.store.format.codec.encodedSize[function] atlib/trace/src/store/format/codec.zig:37tiny.trace.store.format.database.sequenceKey[function] atlib/trace/src/store/format/database.zig:87tiny.trace.store.format.database.updateChecksum[function] atlib/trace/src/store/format/database.zig:92lib.trace.src.store.writer.writer.Writer.finishChunk[method] — private source atlib/trace/src/store/writer/writer.zig:185in nearest public ownerlib.trace.src.store.writer.writerlib.trace.src.store.writer.writer.Writer.flushBlock[method] — private source atlib/trace/src/store/writer/writer.zig:196in nearest public ownerlib.trace.src.store.writer.writer
Complete call list for TraceWriter.open
7 direct calls.
tiny.trace.store.format.block.Builder.init[function] atlib/trace/src/store/format/block.zig:29tiny.trace.store.format.database.events[function] atlib/trace/src/store/format/database.zig:68tiny.trace.store.format.database.openWriter[function] atlib/trace/src/store/format/database.zig:50tiny.trace.store.format.database.workspaceLimits[function] atlib/trace/src/store/format/database.zig:38tiny.trace.TraceWriter.deinit[method] atlib/trace/src/store/writer/writer.zig:111lib.trace.src.store.writer.writer.Writer.ensureLayout[method] — private source atlib/trace/src/store/writer/writer.zig:212in nearest public ownerlib.trace.src.store.writer.writerlib.trace.src.store.writer.writer.Writer.writeManifest[method] — private source atlib/trace/src/store/writer/writer.zig:217in nearest public ownerlib.trace.src.store.writer.writer
Audit
| Definitions | 6 |
|---|---|
| Public names | 12 |
| Members | 22 |
| Version | 26.7.0 |
| Revision | daab053ee433 |