MAGIC
MAGIC = 'STRATA-PAK-1'
Magic bytes and format version closing every pack.
The per-frame directory a pack carries at its own end.
A pack is a flat concatenation of encoded frames with no framing between them, so the only thing
that can find a frame inside one is a map of offsets. Keeping that map exclusively in the local
database would make every packed frame unreadable the moment the database went away - which is
precisely the situation strata:reindex exists to recover from, and precisely the situation a
module uninstall creates. So the map is written into the object as well, after the frames.
The directory sits at the END rather than the front because a frame is read by absolute offset from byte zero; a header would have to be a fixed width or every offset would depend on the size of the thing describing them. A trailer of a known shape is found by reading the last PackIndex::TAIL_BYTES bytes, which is one ranged GET on any endpoint that supports ranges.
Each entry carries what a frame record needs and nothing more. At 16 KiB frames in a 1 MiB pack that is about 64 entries and roughly 0.8% of the object.
encode(list> $entries) : string
Serializes a directory into the bytes that close a pack.
| list |
$entries | One entry per frame, each carrying hash, offset, length, raw, codec, cipher and optionally dictionary, parent and depth. |
When an entry names no valid content address.
The trailer, ready to append to the concatenated frames.
decode(string $key, string $object) : list<array<string,mixed>>
Reads the directory out of a whole pack object.
| string | $key | The object key, for error messages. |
| string | $object | The pack bytes, including the trailer. |
When the object is too short, carries no directory, or the directory does not parse.
One entry per frame, in the order they appear in the pack, with the same keys PackIndex::encode() accepts.
trailerLength(string $key, string $tail) : int
Reads the directory length out of a pack's fixed-size tail.
Split out so a reader with range support can fetch PackIndex::TAIL_BYTES, learn how long the directory is, and fetch only that - two small reads instead of a whole 1 MiB object.
| string | $key | The object key, for error messages. |
| string | $tail | The last PackIndex::TAIL_BYTES bytes of the object. |
When the tail is the wrong size, or does not carry the magic this release writes.
Length of the directory in bytes.
parse(string $key, string $body) : list<array<string,mixed>>
Expands a serialized directory back into entries.
| string | $key | The object key, for error messages. |
| string | $body | The serialized directory. |
When the directory does not parse, or names a version this release cannot read.
The entries.