tiny.profiling.ingest.duplicate
Defined in ingest.
API (9)
Actions
Public operations.
Types and contracts
Public types and contracts.
Values and defaults
Public values and defaults.
Source
Source: src/profiling/ingest/duplicate.zig
zig
const std = @import("std");pub const hash_seed: u64 = 6;pub const KeyEntry = struct { offset: usize, len: usize, hash: u64,};pub const ObjectFrame = struct { first_key: usize, first_byte: usize,};pub const Scratch = struct { json_stack: []u8, key_bytes: []u8, keys: []KeyEntry, objects: []ObjectFrame,};pub const Key = struct { bytes: []const u8, hash: u64,};pub const Observation = union(enum) { none, unique: Key, duplicate,};pub const Tracker = struct { scratch: Scratch, key_count: usize = 0, byte_count: usize = 0, object_count: usize = 0, key_start: usize = 0, key_hash: std.hash.Wyhash = std.hash.Wyhash.init(hash_seed), in_key: bool = false, pub fn init(scratch: Scratch) Tracker { const result = Tracker{ .scratch = scratch }; std.debug.assert(result.key_count == 0); std.debug.assert(result.byte_count == 0); std.debug.assert(result.object_count == 0); return result; } pub fn observe( self: *Tracker, scanner: *const std.json.Scanner, token: std.json.Token, ) error{ScratchExceeded}!Observation { std.debug.assert(self.key_count <= self.scratch.keys.len); std.debug.assert(self.byte_count <= self.scratch.key_bytes.len); std.debug.assert(self.object_count <= self.scratch.objects.len); switch (token) { .object_begin => try self.pushObject(), .object_end => self.popObject(), else => {}, } if (!scanner.string_is_object_key) return .none; switch (token) { .partial_string => |bytes| try self.feed(bytes), .partial_string_escaped_1 => |bytes| try self.feed(&bytes), .partial_string_escaped_2 => |bytes| try self.feed(&bytes), .partial_string_escaped_3 => |bytes| try self.feed(&bytes), .partial_string_escaped_4 => |bytes| try self.feed(&bytes), .string => |bytes| { try self.feed(bytes); return self.finishKey(); }, else => {}, } return .none; } fn pushObject(self: *Tracker) error{ScratchExceeded}!void { std.debug.assert(self.key_count <= self.scratch.keys.len); std.debug.assert(self.byte_count <= self.scratch.key_bytes.len); if (self.object_count >= self.scratch.objects.len) return error.ScratchExceeded; self.scratch.objects[self.object_count] = .{ .first_key = self.key_count, .first_byte = self.byte_count, }; self.object_count += 1; std.debug.assert(self.object_count <= self.scratch.objects.len); } fn popObject(self: *Tracker) void { std.debug.assert(self.object_count > 0); self.object_count -= 1; const frame = self.scratch.objects[self.object_count]; std.debug.assert(frame.first_key <= self.key_count); std.debug.assert(frame.first_byte <= self.byte_count); self.key_count = frame.first_key; self.byte_count = frame.first_byte; } fn feed(self: *Tracker, bytes: []const u8) error{ScratchExceeded}!void { std.debug.assert(self.byte_count <= self.scratch.key_bytes.len); if (!self.in_key) { self.in_key = true; self.key_start = self.byte_count; self.key_hash = std.hash.Wyhash.init(hash_seed); } const end = std.math.add(usize, self.byte_count, bytes.len) catch return error.ScratchExceeded; if (end > self.scratch.key_bytes.len) return error.ScratchExceeded; @memcpy(self.scratch.key_bytes[self.byte_count..end], bytes); self.key_hash.update(bytes); self.byte_count = end; std.debug.assert(self.byte_count <= self.scratch.key_bytes.len); } fn finishKey(self: *Tracker) error{ScratchExceeded}!Observation { std.debug.assert(self.in_key); std.debug.assert(self.object_count > 0); std.debug.assert(self.key_start <= self.byte_count); std.debug.assert(self.key_count <= self.scratch.keys.len); const len = self.byte_count - self.key_start; const hash = self.key_hash.final(); const frame = self.scratch.objects[self.object_count - 1]; std.debug.assert(frame.first_key <= self.key_count); for (self.scratch.keys[frame.first_key..self.key_count]) |key| { if (key.hash != hash or key.len != len) continue; const previous = self.scratch.key_bytes[key.offset..][0..key.len]; const current = self.scratch.key_bytes[self.key_start..][0..len]; if (std.mem.eql(u8, previous, current)) { self.in_key = false; return .duplicate; } } if (self.key_count >= self.scratch.keys.len) return error.ScratchExceeded; self.scratch.keys[self.key_count] = .{ .offset = self.key_start, .len = len, .hash = hash, }; self.key_count += 1; self.in_key = false; return .{ .unique = .{ .bytes = self.scratch.key_bytes[self.key_start..][0..len], .hash = hash, } }; }};Source: src/profiling/ingest/root.zig:5
zig
pub const duplicate = @import("duplicate.zig");Audit
| Definitions | 10 |
|---|---|
| Public names | 10 |
| Members | 21 |
| Version | 26.7.0 |
| Revision | daab053ee433 |