Skip to content

Techniques

The hot path is a cursor, a few width checks, and memcpy. Nothing in that path calls a Kiln library written in another language.

Check, then allocate

A list or dict count is rejected before element storage exists. The order is the unread count word, the cap, the product count * min_size(element), and only then an allocation. A tensor count above the cap, or a directory that does not fit, returns before a descriptor array exists. The test counter kiln_debug_alloc_total stays at zero on those paths.

Fixed-width lists do not allocate elements at all. The value holds a pointer into the input and a byte length. Encode writes the count and copies that slice once. kiln_list_load and kiln_tensor_load copy that slice into a caller buffer. On a little-endian host kiln_bulk_copy is one memcpy of count * width. Width is 1, 2, 4, or 8, so a 4-byte list is never written into 8-byte slots. The caller can reuse the destination across decodes.

Tensor payloads

Decode of a directory borrows each payload. The pointer is payload_base + byte_offset inside the caller's buffer. Encode computes canonical offsets in one pass, zeroes the header, the name heap, and the alignment gaps, and memcpys each payload. It does not walk the numeric bytes one at a time.

kiln_decode_reuse keeps the small descriptor arena across calls so a loop does not malloc a document on every tensor.

Schema hash

The frame hash is FNV-1a 64. Each token is mixed a byte at a time, and each token ends with the extra multiply that a 0x00 byte would cause. Struct fields mix the name, a colon, the field type, and a comma. A tensor field mixes the ASCII bytes tensors. The hash does not include tensor dtypes or shapes. Those are payload.

Generated code

Generated decode uses the same cap and the same minimum-size check as the dynamic reader. A short list returns EOF before it allocates. Numeric lists call kiln_bulk_copy into malloc storage instead of storing one scalar at a time. Bool lists stay scalar so only 0 and 1 are written. Strings are copied so the caller can free the input buffer. Tensor fields are not part of the JSON Schema subset, so generated structs do not borrow a directory.