A leaf node holds the actual keys and values, packed into one page. Today you serialize a leaf - its header, its next-leaf link, and its sorted key/value entries - into exact bytes, so a node can be written to a page and later to disk.
Serialize a leaf node (keys, values, and a next-leaf link) into a 4096-byte page with an exact byte layout.
A leaf is where the index actually stores data: sorted keys, each paired with
a value (here a uint64, standing in for a row pointer). Its page starts with the
shared header, then a four-byte next-leaf link (the page id of the leaf to its
right - the thing range scans will follow), then the entries: each key immediately
followed by its value, in sorted key order.
Because keys and values are both fixed-width, entry i always lives at a
predictable offset - leafHeader + i * entrySize - which is what makes an
in-page binary search possible later. Nothing here is variable-length or
pointer-based; the whole leaf is a self-contained block of bytes that means the
same thing in RAM and on disk. That is the property the entire crash-safety story
will eventually depend on.
type LeafNode struct { Keys, Vals []uint64; Next PageID }// layout: [type:1][count:2][next:4] then entries of [key:8][val:8]const leafHeader = 7 // 1 + 2 + 4const entrySize = 16 // 8-byte key + 8-byte valuefunc serializeLeaf(n *LeafNode) []byte {// setHeader(nodeLeaf, len(Keys)); putU32(b,3,Next); then each entry}