Skip to main content

Module freelist

Module freelist 

Source
Expand description

Persisted free-page list (SQLR-6).

After DROP TABLE / DROP INDEX / ALTER TABLE DROP COLUMN, the next save_database no longer references the dropped object’s pages. Without a freelist those pages would either be re-numbered (every later table shifts down → high write amplification) or stranded as orphans on disk.

The freelist solves both: pages no longer referenced from sqlrite_master go on a persisted stack rooted at header.freelist_head, so subsequent saves can pull from there before extending the file. The unrelated tables that didn’t change keep their page numbers and their pages re-stage byte- identical → the diff pager skips writing them.

§On-disk layout

Each freelist trunk page carries the standard 7-byte page header with page_type = PAGE_TYPE_FREELIST_TRUNK (5) and next_page pointing at the next trunk in the chain (0 = end). The 4089-byte payload area holds:

  0..2      count: u16 LE       — number of free leaf-page IDs that follow
  2..2+4*N  page_ids[N]: u32 LE — free leaf-page numbers, ascending

A trunk holds up to (PAYLOAD_PER_PAGE - 2) / 4 = 1021 free page IDs. Larger freelists chain across multiple trunks. The trunk pages themselves are part of the live page set (they hold metadata) and are not on the freelist they encode.

Constants§

FREELIST_IDS_PER_TRUNK
Maximum number of free page IDs a single trunk page can hold. PAYLOAD_PER_PAGE is 4089; we reserve 2 bytes for the count and 4 bytes per ID, giving (4089 - 2) / 4 = 1021.
PAGE_TYPE_FREELIST_TRUNK
Page-type tag for a freelist trunk page. Distinct from existing page tags (2 = TableLeaf, 3 = Overflow, 4 = InteriorNode); 1 was retired.

Functions§

encode_trunk
Encodes a single freelist trunk page into the given buffer.
freelist_to_deque
Helper: collect a freelist into a VecDeque<u32> sorted ascending — the ordering the PageAllocator uses to draw next free pages from.
read_freelist
Walks the freelist chain rooted at head and returns every free leaf-page ID. The trunk pages themselves are not included — they’re live metadata. Returns the trunk page numbers separately so the caller can release them (the next save re-encodes the freelist from scratch and frees the old trunks for reuse).
stage_freelist
Stages the freelist chain into the pager. free_pages is the full set of pages that need persisted-on-the-freelist treatment — both the trunk pages (metadata) and the leaf entries (the actually-free leaves).