go-ethereum/nomt/core/page.go
weiihann 7aebfb3c71 nomt/core: add Phase 1 core primitives for NOMT binary merkle trie
Implement foundational types and algorithms for the NOMT storage engine:
- node.go: Node/KeyPath/ValueHash types with MSB-based kind discrimination
- hasher.go: Keccak256 hashing with leaf/internal MSB labeling
- page.go: 4096-byte RawPage layout (126 nodes + elided children + pageID)
- pageid.go: PageID encode/decode with shift-then-add encoding
- triepos.go: TriePosition navigation (Down/Up/Sibling/PageID/NodeIndex)
- pagediff.go: 128-bit PageDiff bitfield for tracking changed nodes
- update.go: BuildTrie 3-pointer left-frontier algorithm, LeafOpsSpliced

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 17:05:00 +08:00

71 lines
2.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package core
import "encoding/binary"
// Page layout constants.
const (
// PageDepth is the depth of the rootless sub-binary tree stored in a page.
PageDepth = 6
// NodesPerPage is the total number of nodes in one page: (2^(depth+1)) - 2 = 126.
NodesPerPage = (1 << (PageDepth + 1)) - 2
// NumChildren is the number of child pages each page can have: 2^depth = 64.
NumChildren = 1 << PageDepth
// PageSize is the size of a raw page in bytes, aligned to SSD page size.
PageSize = 4096
// elidedChildrenOffset stores the 8-byte elided children bitfield.
// Layout: [nodes 4032] [padding 24] [elided 8] [pageID 32] = 4096
elidedChildrenOffset = PageSize - 32 - 8 // 4056
// pageIDOffset stores the 32-byte encoded PageID.
pageIDOffset = PageSize - 32 // 4064
)
// RawPage is a 4096-byte page storing a rootless sub-tree of depth 6.
//
// Layout:
//
// [0..4032) 126 nodes × 32 bytes each, in level-order
// [4032..4056) 24 bytes padding
// [4056..4064) ElidedChildren bitfield (8 bytes, little-endian uint64)
// [4064..4096) PageID encoded (32 bytes)
type RawPage [PageSize]byte
// NodeAt reads the 32-byte node at the given index (0-based level-order).
func (p *RawPage) NodeAt(index int) Node {
var n Node
off := index * 32
copy(n[:], p[off:off+32])
return n
}
// SetNodeAt writes a 32-byte node at the given index.
func (p *RawPage) SetNodeAt(index int, n Node) {
off := index * 32
copy(p[off:off+32], n[:])
}
// ElidedChildren reads the 8-byte elided children bitfield.
func (p *RawPage) ElidedChildren() uint64 {
return binary.LittleEndian.Uint64(p[elidedChildrenOffset:])
}
// SetElidedChildren writes the 8-byte elided children bitfield.
func (p *RawPage) SetElidedChildren(ec uint64) {
binary.LittleEndian.PutUint64(p[elidedChildrenOffset:], ec)
}
// PageIDBytes reads the 32-byte encoded PageID from the page.
func (p *RawPage) PageIDBytes() [32]byte {
var id [32]byte
copy(id[:], p[pageIDOffset:pageIDOffset+32])
return id
}
// SetPageIDBytes writes the 32-byte encoded PageID into the page.
func (p *RawPage) SetPageIDBytes(id [32]byte) {
copy(p[pageIDOffset:pageIDOffset+32], id[:])
}