func readFreeList()

in freelist.go [391:437]


func readFreeList(
	access func(PageID) []byte,
	root PageID,
	fn func(bool, region),
) (idList, reason) {
	const op = "txfile/read-freelist"

	if root == 0 {
		return nil, nil
	}

	rootPage := access(root)
	if rootPage == nil {
		return nil, &Error{
			op:    op,
			kind:  InvalidMetaPage,
			cause: raiseOutOfBounds(root),
			msg:   "root page not in bounds",
		}
	}

	var metaPages idList
	for pageID := root; pageID != 0; {
		metaPages.Add(pageID)
		node, payload := castFreePage(access(pageID))
		if node == nil {
			return nil, &Error{
				op:    op,
				kind:  InvalidMetaPage,
				cause: raiseOutOfBounds(pageID),
				msg:   "invalid freelist node page",
			}
		}

		pageID = node.next.Get()
		entries := node.count.Get()
		tracef("free list node: (next: %v, entries: %v)", pageID, entries)

		for ; entries > 0; entries-- {
			isMeta, reg, n := decodeRegion(payload)
			payload = payload[n:]
			fn(isMeta, reg)
		}
	}

	return metaPages, nil
}