Break the alknet-typedef architecture specs into atomic, dependency-ordered implementation tasks covering crate init, error types, schema layer, data access, both layout modes (aligned static + packed sequential), TUnion dispatch, jsonschema custom keyword validators, TypedefEngine integration, comprehensive tests, and a final review checkpoint. Validated: 12 tasks, 0 cycles, 7 parallel generations.
7.5 KiB
id, name, status, depends_on, scope, risk, impact, level
| id | name | status | depends_on | scope | risk | impact | level | |||
|---|---|---|---|---|---|---|---|---|---|---|
| typedef/offset-map | Implement aligned static OffsetMap for mmap-friendly formats | pending |
|
moderate | medium | component | implementation |
Description
Implement the aligned static OffsetMap in crates/alknet-typedef/src/offset_map.rs.
This is Mode 2 of the two layout modes (ADR-096): fields have fixed positions with
natural alignment padding. Variable-length fields get a 4-byte length prefix at a
known offset; the variable data is not included in the static layout.
Per layout-engine.md §"Mode 2: Aligned static".
Target shape
/// A byte range within a buffer.
#[derive(Debug, Clone, Copy)]
pub struct ByteRange {
pub start: usize,
pub end: usize,
}
/// A flat table of (field_path, byte_range) pairs computed from a schema.
/// Fields have fixed positions with natural alignment padding.
/// Used for mmap-friendly formats (metatensor, safetensors).
#[derive(Debug)]
pub struct OffsetMap {
fields: Vec<(String, ByteRange)>,
total_size: usize,
}
impl OffsetMap {
/// Compute the offset map from a schema JSON value.
/// Walks the schema recursively, computing byte positions for each field
/// based on type sizes, field order, and alignment.
pub fn compute(schema: &serde_json::Value) -> Result<Self, TypedefError>;
/// Look up a field's byte range by dotted path (e.g., "header.version").
pub fn get(&self, field_path: &str) -> Option<&ByteRange>;
/// The total size of the struct in bytes (including alignment padding).
pub fn total_size(&self) -> usize;
/// Iterate over all (field_path, byte_range) pairs.
pub fn iter(&self) -> impl Iterator<Item = &(String, ByteRange)>;
}
Offset computation algorithm
The algorithm walks the schema recursively:
-
Fixed-size types: Determine the type's byte size from the
TypeDef:*kind. Insert alignment padding to satisfy the type's alignment (or the field'salignannotation, or the struct'saligndefault). Record the field's(start, end)range. Advance the current offset by the type's size. -
TStruct: Recurse into the struct'sproperties. Inner fields are computed relative to the struct's start offset. The struct's total size is the sum of its fields' sizes plus alignment padding. The struct itself may have analignannotation that rounds up its total size. -
TUnion: The discriminator occupiesoffset..offset + discriminator_sizebytes. For byte-offset discriminators, the variant struct starts atoffset + discriminator_size. For field-name discriminators, the discriminator is just another field. The union's total size isdiscriminator_size + max(variant_sizes). -
TArrayof fixed-size elements: Element stride = element size plus alignment padding. Elementistarts atarray_offset + i × stride. The array's total size iscount × stride. Count is determined fromminItems/maxItems(when equal, fixed count; otherwise variable — uses length-prefixed encoding). -
Variable-length types (inline length-prefixing): Record the position of the 4-byte length prefix. The variable data is not included in the static layout. The length prefix is aligned to 4 bytes.
-
Variable-length types (fixed-size reservation,
maxLength): ReservemaxLengthbytes at a fixed offset. Data shorter thanmaxLengthis zero-padded. Subsequent fields have known, unchanging offsets. -
Variable-length types (offset indirection): The field is a struct
{offset: u32, length: u32}(8 bytes total). Record its position. The consumer provides the data region separately.
Nested structs and field paths
Nested structs produce dotted field paths: "header.version", "header.magic".
The offset computation propagates the field path prefix during recursion. The
OffsetMap stores fully-qualified paths.
Alignment rules
- Default alignment: 1 for u8/bool, 2 for u16/i16, 4 for u32/i32/f32/enum, 8 for u64/i64/f64, max field alignment for structs.
- Struct-level
"align"sets the default for all fields in that struct. - Field-level
"align"overrides the struct default. - The struct's total size is rounded up to its alignment.
- Alignment padding is inserted before each field to satisfy its alignment.
What this does NOT include
- Packed sequential layout (that's
layout_builder.rsandsequential_reader.rs) - TUnion discriminator dispatch (that's
tunion.rs) - The
TypedefEnginestruct (that'sengine.rs) - Arrays of variable-length-element structs (deferred, OQ-069)
Acceptance Criteria
OffsetMapstruct withfields: Vec<(String, ByteRange)>andtotal_size: usizeOffsetMap::compute(schema)walks the schema and computes byte positions- Fixed-size types get correct byte ranges with natural alignment padding
u8at offset 0,u32at offset 4 (3 bytes padding) — natural alignment- Nested structs produce dotted field paths (
"header.version") TArrayof fixed-size elements: correct stride and element offsetsTArraywithminItems == maxItems: fixed count, known at schema timeTArraywith variable count: length-prefixed encoding (4-byte count prefix)- Variable-length types (inline length-prefixing): 4-byte length prefix at known offset
- Variable-length types (
maxLength): reservedmaxLengthbytes at fixed offset - Variable-length types (offset-indirect): 8-byte
{offset, length}struct at known offset TUnionwith byte-offset discriminator: discriminator atoffset, variant atoffset + disc_sizeTUnionwith field-name discriminator: discriminator is a regular field- Struct-level
"align"annotation: rounds up struct total size - Field-level
"align"annotation: overrides struct default for that field OffsetMap::get("header.version")returns the correctByteRangeOffsetMap::total_size()returns the correct total sizeOffsetMap::iter()iterates all field paths- Returns
TypedefError::Schemafor malformed schemas - Returns
TypedefError::Offsetfor unsupported type combinations - No
unwrap()orexpect()on error paths - All public types and functions have doc comments
cargo check -p alknet-typedefsucceedscargo clippy -p alknet-typedefsucceeds with no warningscargo build --workspacestill succeeds
References
- docs/architecture/crates/typedef/layout-engine.md — Mode 2: Aligned static, offset computation algorithm
- docs/architecture/crates/typedef/schema-layer.md — the 17 TypeDef kinds and their byte sizes
- docs/architecture/decisions/096-two-layout-modes-packed-vs-aligned.md — ADR-096
- docs/architecture/decisions/097-schema-annotations.md — ADR-097 (alignment, encoding)
- /workspace/alknet-typedef-poc/src/offset.rs — POC reference for offset computation
Notes
This is the aligned static layout mode — the simpler of the two modes. Fields have fixed positions; the consumer can read field N without reading fields 0..N-1 first. Used by metatensor and safetensors. The offset computation is a recursive walk of the schema JSON. Nested structs propagate field path prefixes. Alignment padding is inserted between fields based on type sizes and annotations. The POC's
offset.rsis a good reference — the algorithm is correct and can be adapted.
Summary
To be filled on completion