pager

package
v0.5.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 14, 2026 License: AGPL-3.0 Imports: 13 Imported by: 0

Documentation

Overview

Package pager — PageBackend integrates the page-based storage engine with the tinySQL StorageBackend interface.

Package pager implements a page-based, transactional storage engine with Write-Ahead Logging (WAL) for tinySQL.

The storage format consists of a main database file (tinysql.db) with fixed-size pages (default 8 KiB) and a sequential WAL file (tinysql.wal). The first page is a superblock; subsequent pages are typed (B+Tree internal, B+Tree leaf, overflow, freelist). Every page carries a header with type, page-ID, LSN, and CRC32 checksum. Crash recovery replays committed WAL transactions from the last checkpoint_lsn.

Index

Constants

View Source
const (
	// DefaultPageSize is the default page size in bytes (8 KiB).
	DefaultPageSize = 8192

	// MinPageSize is the minimum allowed page size (4 KiB).
	MinPageSize = 4096

	// MaxPageSize is the maximum allowed page size (64 KiB).
	MaxPageSize = 65536

	// PageHeaderSize is the size of the common page header in bytes.
	// Layout:
	//   [0]    PageType   (1 byte)
	//   [1]    Flags      (1 byte)
	//   [2:4]  Reserved   (2 bytes)
	//   [4:8]  PageID     (4 bytes, uint32 LE)
	//   [8:16] LSN        (8 bytes, uint64 LE)
	//   [16:20] CRC32     (4 bytes, uint32 LE)
	//   [20:32] Reserved  (12 bytes)
	PageHeaderSize = 32

	// InvalidPageID represents a null/invalid page pointer.
	InvalidPageID PageID = 0

	// OverflowThreshold is the max inline value size (bytes) before an
	// overflow page chain is used. Set to 1/4 of usable leaf space.
	// Adjusted dynamically based on page size, but this is the default.
	OverflowThreshold = 1024
)
View Source
const (
	// SuperblockMagic identifies a valid tinySQL database file.
	SuperblockMagic = "TNSQLDB\x00"

	// CurrentFormatVersion is the on-disk format version.
	CurrentFormatVersion uint32 = 1
)
View Source
const (
	WALMagic       = "TNSQWAL\x00"
	WALVersion     = uint32(1)
	WALFileHdrSize = 32
	WALRecHdrSize  = 33
)

Variables

This section is empty.

Functions

func ComputePageCRC

func ComputePageCRC(page []byte) uint32

ComputePageCRC computes the CRC32-C of a full page, treating the CRC field (bytes 16..20) as zero during computation.

func DumpTree

func DumpTree(dbPath string, rootPageID PageID, pageSize int) (string, error)

DumpTree produces a human-readable dump of a B+Tree starting at root.

func FreeListCapacity

func FreeListCapacity(pageSize int) int

FreeListCapacity returns how many page IDs fit in one free-list page.

func MarshalHeader

func MarshalHeader(h *PageHeader, buf []byte)

MarshalHeader writes a PageHeader into the first PageHeaderSize bytes of buf.

func MarshalRow

func MarshalRow(row []any, buf []byte) []byte

MarshalRow encodes a row into the compact binary format. It reuses the provided buf if large enough.

func MarshalSuperblock

func MarshalSuperblock(sb *Superblock, pageSize int) []byte

MarshalSuperblock serializes a Superblock into a full page buffer. The buffer must be at least PageSize bytes. The common PageHeader is set (Type=Superblock, ID=0) and the CRC computed.

func NewPage

func NewPage(pageSize int, pt PageType, id PageID) []byte

NewPage allocates a zeroed page buffer at the given size and writes its header.

func OverflowCapacity

func OverflowCapacity(pageSize int) int

OverflowCapacity returns the payload capacity of a single overflow page.

func ParseRowKey

func ParseRowKey(key []byte) int64

ParseRowKey extracts the row ID from a B+Tree key.

func RowKey

func RowKey(rowID int64) []byte

RowKey creates a B+Tree key from a row index.

func SetPageCRC

func SetPageCRC(page []byte)

SetPageCRC computes and writes the CRC into the page header.

func UnmarshalRow

func UnmarshalRow(data []byte) ([]any, error)

UnmarshalRow decodes a row from the compact binary format.

func VerifyDB

func VerifyDB(dbPath string) ([]string, error)

VerifyDB checks the integrity of an entire database file. Returns a list of issues found (empty = healthy).

func VerifyPageCRC

func VerifyPageCRC(page []byte) error

VerifyPageCRC checks the CRC32 checksum of a page.

Types

type BTree

type BTree struct {
	// contains filtered or unexported fields
}

BTree represents a B+Tree stored in the pager.

func CreateBTree

func CreateBTree(p *Pager, txID TxID) (*BTree, error)

CreateBTree allocates a new B+Tree with an empty leaf root page. Must be called within a transaction.

func NewBTree

func NewBTree(p *Pager, root PageID) *BTree

NewBTree creates a handle to an existing B+Tree with the given root. For a new tree, call CreateBTree first.

func (*BTree) Count

func (bt *BTree) Count() (int, error)

Count returns the total number of key-value pairs in the tree.

func (*BTree) Delete

func (bt *BTree) Delete(txID TxID, key []byte) (bool, error)

Delete removes a key from the B+Tree.

func (*BTree) FreeAllPages

func (bt *BTree) FreeAllPages()

FreeAllPages recursively frees every page owned by this B+Tree (internal nodes, leaf nodes, and overflow chains). After this call the tree is invalid and must not be used.

func (*BTree) Get

func (bt *BTree) Get(key []byte) ([]byte, bool, error)

Get looks up a key. Returns (value, true) or (nil, false). Handles overflow pages transparently.

func (*BTree) Insert

func (bt *BTree) Insert(txID TxID, key, value []byte) error

Insert adds or updates a key-value pair within the given transaction.

func (*BTree) Root

func (bt *BTree) Root() PageID

Root returns the root page ID.

func (*BTree) ScanRange

func (bt *BTree) ScanRange(startKey, endKey []byte, fn func(key, value []byte) bool) error

ScanRange calls fn for each key-value pair where startKey <= key <= endKey. If endKey is nil, scans to the end. If fn returns false, the scan stops.

type BTreePage

type BTreePage struct {
	// contains filtered or unexported fields
}

func InitBTreePage

func InitBTreePage(buf []byte, id PageID, leaf bool) *BTreePage

InitBTreePage initialises a page as a B+Tree node.

func WrapBTreePage

func WrapBTreePage(buf []byte) *BTreePage

WrapBTreePage wraps an existing buffer.

func (*BTreePage) Bytes

func (bp *BTreePage) Bytes() []byte

func (*BTreePage) DeleteLeafEntry

func (bp *BTreePage) DeleteLeafEntry(pos int) error

DeleteLeafEntry removes the entry at position pos.

func (*BTreePage) FindChild

func (bp *BTreePage) FindChild(key []byte) PageID

FindChild returns the child PageID for the given search key. For internal-page navigation: find the largest key <= searchKey.

func (*BTreePage) FindLeafEntry

func (bp *BTreePage) FindLeafEntry(key []byte) (int, bool)

FindLeafEntry searches for an exact key match. Returns (index, true) or (-1, false).

func (*BTreePage) GetAllInternalEntries

func (bp *BTreePage) GetAllInternalEntries() []InternalEntry

GetAllInternalEntries returns all separator entries in order.

func (*BTreePage) GetAllLeafEntries

func (bp *BTreePage) GetAllLeafEntries() []LeafEntry

GetAllLeafEntries returns all leaf entries in order.

func (*BTreePage) GetInternalEntry

func (bp *BTreePage) GetInternalEntry(i int) InternalEntry

GetInternalEntry returns the i-th separator key and its left child.

func (*BTreePage) GetLeafEntry

func (bp *BTreePage) GetLeafEntry(i int) LeafEntry

GetLeafEntry returns the i-th key-value pair.

func (*BTreePage) InsertInternalEntry

func (bp *BTreePage) InsertInternalEntry(entry InternalEntry) error

InsertInternalEntry inserts a separator key at the correct sorted position.

func (*BTreePage) InsertLeafEntry

func (bp *BTreePage) InsertLeafEntry(entry LeafEntry) (int, error)

InsertLeafEntry inserts a key-value pair at the correct sorted position. Returns the slot index.

func (*BTreePage) IsLeaf

func (bp *BTreePage) IsLeaf() bool

func (*BTreePage) KeyCount

func (bp *BTreePage) KeyCount() int

func (*BTreePage) NextLeaf

func (bp *BTreePage) NextLeaf() PageID

func (*BTreePage) PageID

func (bp *BTreePage) PageID() PageID

func (*BTreePage) PrevLeaf

func (bp *BTreePage) PrevLeaf() PageID

func (*BTreePage) RightChild

func (bp *BTreePage) RightChild() PageID

func (*BTreePage) SearchInternal

func (bp *BTreePage) SearchInternal(key []byte) PageID

SearchInternal finds the child page for a given key in an internal node. Internal page layout: entries[0].child, entries[0].key, entries[1].child, ... Keys divide the key space: key < entry[0].key → entry[0].child, entry[i-1].key <= key < entry[i].key → entry[i].child, key >= entry[last].key → RightChild.

func (*BTreePage) SetNextLeaf

func (bp *BTreePage) SetNextLeaf(pid PageID)

func (*BTreePage) SetPrevLeaf

func (bp *BTreePage) SetPrevLeaf(pid PageID)

func (*BTreePage) SetRightChild

func (bp *BTreePage) SetRightChild(pid PageID)

func (*BTreePage) UpdateLeafEntry

func (bp *BTreePage) UpdateLeafEntry(pos int, entry LeafEntry) error

UpdateLeafEntry replaces the value at the given sorted position.

type BufferPoolConfig

type BufferPoolConfig struct {
	MaxPages int // maximum number of cached pages (default 1024)
}

BufferPoolConfig configures the page buffer pool.

type Catalog

type Catalog struct {
	// contains filtered or unexported fields
}

Catalog manages the system catalog B+Tree.

func OpenCatalog

func OpenCatalog(p *Pager, txID TxID) (*Catalog, error)

OpenCatalog opens or creates the system catalog.

func (*Catalog) DeleteEntry

func (c *Catalog) DeleteEntry(txID TxID, tenant, table string) error

DeleteEntry removes a catalog entry within the given transaction.

func (*Catalog) GetEntry

func (c *Catalog) GetEntry(tenant, table string) (*CatalogEntry, error)

GetEntry retrieves a catalog entry. Returns nil if not found.

func (*Catalog) ListTables

func (c *Catalog) ListTables(tenant string) ([]string, error)

ListTables returns all table names for a tenant.

func (*Catalog) PutEntry

func (c *Catalog) PutEntry(txID TxID, entry CatalogEntry) error

PutEntry upserts a catalog entry within the given transaction.

func (*Catalog) Root

func (c *Catalog) Root() PageID

Root returns the catalog tree's root page ID.

type CatalogColumn

type CatalogColumn struct {
	Name       string `json:"name"`
	Type       int    `json:"type"`       // ColType as int
	Constraint int    `json:"constraint"` // ConstraintType as int
	FKTable    string `json:"fk_table,omitempty"`
	FKColumn   string `json:"fk_col,omitempty"`
	PtrTable   string `json:"ptr_table,omitempty"`
}

CatalogColumn describes a column in the system catalog.

type CatalogEntry

type CatalogEntry struct {
	Tenant     string          `json:"tenant"`
	Table      string          `json:"table"`
	RootPageID PageID          `json:"root_page_id"`
	Columns    []CatalogColumn `json:"columns"`
	RowCount   int64           `json:"row_count"`
	Version    int             `json:"version"`
}

CatalogEntry is the value stored in the system catalog B+Tree.

type ColumnInfo

type ColumnInfo struct {
	Name         string
	Type         int // ColType as int
	Constraint   int // ConstraintType as int
	FKTable      string
	FKColumn     string
	PointerTable string
}

ColumnInfo is a simplified, pager-internal column descriptor that does not import the storage package (to avoid circular dependencies).

type FeatureFlag

type FeatureFlag uint64

FeatureFlag is a bitmask of optional format features.

const (
	FeatureCompression FeatureFlag = 1 << iota // reserved: page-level compression
	FeatureEncryption                          // reserved: page-level encryption
	FeatureMVCC                                // reserved: multi-version concurrency
	FeaturePartitions                          // reserved: range partitioning
)

FeatureFlag bits (bitmask). Version 1 has no flags set.

const SupportedFeatures FeatureFlag = 0 // v1: none

SupportedFeatures is the set of features understood by this build. Any flag outside of this set causes the file to be rejected.

type FreeListPage

type FreeListPage struct {
	// contains filtered or unexported fields
}

FreeListPage wraps a page buffer as a free-list page.

func InitFreeListPage

func InitFreeListPage(buf []byte, id PageID) *FreeListPage

InitFreeListPage creates a new empty free-list page.

func WrapFreeListPage

func WrapFreeListPage(buf []byte) *FreeListPage

WrapFreeListPage wraps an existing free-list buffer.

func (*FreeListPage) AddEntry

func (fl *FreeListPage) AddEntry(pid PageID) bool

AddEntry appends a free page ID. Returns false if the page is full.

func (*FreeListPage) AllEntries

func (fl *FreeListPage) AllEntries() []PageID

AllEntries returns all stored free page IDs.

func (*FreeListPage) Bytes

func (fl *FreeListPage) Bytes() []byte

Bytes returns the underlying page buffer.

func (*FreeListPage) EntryCount

func (fl *FreeListPage) EntryCount() int

EntryCount returns the number of free page IDs stored.

func (*FreeListPage) GetEntry

func (fl *FreeListPage) GetEntry(i int) PageID

GetEntry returns the i-th free page ID.

func (*FreeListPage) NextFreeList

func (fl *FreeListPage) NextFreeList() PageID

NextFreeList returns the next free-list page in the chain.

func (*FreeListPage) PopEntry

func (fl *FreeListPage) PopEntry() PageID

PopEntry removes and returns the last entry. Returns InvalidPageID if empty.

func (*FreeListPage) SetNextFreeList

func (fl *FreeListPage) SetNextFreeList(pid PageID)

SetNextFreeList sets the next page pointer.

type FreeManager

type FreeManager struct {
	// contains filtered or unexported fields
}

FreeManager tracks free pages using an in-memory set backed by free-list pages on disk. The pager calls its methods during allocation and deallocation.

func NewFreeManager

func NewFreeManager() *FreeManager

NewFreeManager creates a FreeManager. Call LoadFromDisk to populate.

func (*FreeManager) AllFree

func (fm *FreeManager) AllFree() []PageID

AllFree returns all free page IDs (unsorted).

func (*FreeManager) Alloc

func (fm *FreeManager) Alloc() PageID

Alloc returns a free page ID (popped from the set) or InvalidPageID if empty.

func (*FreeManager) Count

func (fm *FreeManager) Count() int

Count returns the number of free pages.

func (*FreeManager) FlushToDisk

func (fm *FreeManager) FlushToDisk(pageSize int, allocPage func() (PageID, []byte)) (PageID, [][]byte)

FlushToDisk writes the in-memory free set into free-list pages. It returns the head PageID of the new chain and the list of page buffers to write. allocPage is a callback that returns a new, zeroed page buffer with a fresh ID.

func (*FreeManager) Free

func (fm *FreeManager) Free(pid PageID)

Free marks a page ID as available for reuse.

func (*FreeManager) LoadFromDisk

func (fm *FreeManager) LoadFromDisk(head PageID, readPage func(PageID) ([]byte, error)) error

LoadFromDisk walks the free-list chain starting at head and populates the in-memory set. readPage is a callback that reads a page by ID.

type GCResult

type GCResult struct {
	TotalPages     int      // total allocated pages in the file
	ReachablePages int      // pages reachable from roots
	FreeBefore     int      // free pages before GC
	FreeAfter      int      // free pages after GC
	Reclaimed      int      // newly freed orphan pages
	Errors         []string // non-fatal issues found during the scan
}

GCResult holds statistics about a garbage collection run.

type InternalEntry

type InternalEntry struct {
	ChildID PageID
	Key     []byte
}

InternalEntry represents a key + left-child pointer for internal pages.

type LSN

type LSN uint64

LSN is a monotonically increasing Log Sequence Number.

type LeafEntry

type LeafEntry struct {
	Key            []byte
	Value          []byte // inline value (empty when overflow)
	Overflow       bool
	OverflowPageID PageID
	TotalSize      uint32
}

LeafEntry represents a key-value pair stored in a leaf page.

type OverflowPage

type OverflowPage struct {
	// contains filtered or unexported fields
}

OverflowPage wraps a page buffer as an overflow page.

func InitOverflowPage

func InitOverflowPage(buf []byte, id PageID) *OverflowPage

InitOverflowPage creates a new overflow page.

func WrapOverflowPage

func WrapOverflowPage(buf []byte) *OverflowPage

WrapOverflowPage wraps an existing overflow page buffer.

func (*OverflowPage) Bytes

func (op *OverflowPage) Bytes() []byte

Bytes returns the underlying page buffer.

func (*OverflowPage) Data

func (op *OverflowPage) Data() []byte

Data returns the payload bytes.

func (*OverflowPage) DataLen

func (op *OverflowPage) DataLen() int

DataLen returns the number of payload bytes stored.

func (*OverflowPage) NextOverflow

func (op *OverflowPage) NextOverflow() PageID

NextOverflow returns the next overflow page in the chain.

func (*OverflowPage) SetData

func (op *OverflowPage) SetData(data []byte) error

SetData writes payload into the overflow page. Returns an error if the data exceeds the capacity.

func (*OverflowPage) SetNextOverflow

func (op *OverflowPage) SetNextOverflow(pid PageID)

SetNextOverflow sets the next-page pointer.

type PageBackend

type PageBackend struct {
	// contains filtered or unexported fields
}

PageBackend implements a disk-based key-value store backed by B+Trees, a WAL for crash safety, and a buffer pool for caching.

func NewPageBackend

func NewPageBackend(cfg PageBackendConfig) (*PageBackend, error)

NewPageBackend opens or creates a page-based database.

func (*PageBackend) Close

func (pb *PageBackend) Close() error

Close performs a final checkpoint and closes all files.

func (*PageBackend) DBPath

func (pb *PageBackend) DBPath() string

DBPath returns the database file path.

func (*PageBackend) DeleteTable

func (pb *PageBackend) DeleteTable(tenant, name string) error

DeleteTable removes a table from the catalog and frees its pages.

func (*PageBackend) GC

func (pb *PageBackend) GC() (*GCResult, error)

GC performs a full reachability-based garbage collection on the database. It must be called when no other writers are active (exclusive access). The GC does NOT shrink the file — it only adds orphans to the free-list so they can be reused by future writes.

func (*PageBackend) ListTableNames

func (pb *PageBackend) ListTableNames(tenant string) ([]string, error)

ListTableNames returns all table names for a tenant.

func (*PageBackend) LoadTable

func (pb *PageBackend) LoadTable(tenant, name string) (*TableData, error)

LoadTable retrieves all rows of a table from its B+Tree.

func (*PageBackend) Pager

func (pb *PageBackend) Pager() *Pager

Pager returns the underlying pager (for inspection tools).

func (*PageBackend) SaveTable

func (pb *PageBackend) SaveTable(tenant string, td *TableData) error

SaveTable persists all rows of a table into a B+Tree. This replaces the entire table contents (drop + recreate of the tree).

func (*PageBackend) Stats

func (pb *PageBackend) Stats() PageBackendStats

Stats returns operational statistics.

func (*PageBackend) Sync

func (pb *PageBackend) Sync() error

Sync performs a checkpoint.

func (*PageBackend) TableExists

func (pb *PageBackend) TableExists(tenant, name string) bool

TableExists reports whether a table exists in the catalog.

type PageBackendConfig

type PageBackendConfig struct {
	Path          string // database file path (.db)
	PageSize      int    // 0 = DefaultPageSize (8 KiB)
	MaxCachePages int    // buffer pool size (0 = default 1024)
}

PageBackendConfig configures the page-based StorageBackend.

type PageBackendStats

type PageBackendStats struct {
	PageSize      int
	PageCount     uint64
	FreePages     int
	CheckpointLSN LSN
	NextTxID      TxID
	SyncCount     int64
	LoadCount     int64
	DBPath        string
	WALPath       string
}

PageBackendStats holds operational metrics.

type PageBufferPool

type PageBufferPool struct {
	// contains filtered or unexported fields
}

PageBufferPool is an LRU page cache with dirty-page tracking.

type PageFrame

type PageFrame struct {
	// contains filtered or unexported fields
}

PageFrame is an in-memory cached page.

type PageHeader struct {
	Type     PageType // 1 byte
	Flags    uint8    // 1 byte
	Reserved uint16   // 2 bytes
	ID       PageID   // 4 bytes
	LSN      LSN      // 8 bytes
	CRC      uint32   // 4 bytes — CRC32 of the entire page (with CRC field zeroed)
	Pad      [12]byte // reserved for future use
}

PageHeader is the 32-byte header present at the start of every page.

func UnmarshalHeader

func UnmarshalHeader(buf []byte) PageHeader

UnmarshalHeader reads a PageHeader from the first PageHeaderSize bytes of buf.

type PageID

type PageID uint32

PageID is a 32-bit page identifier. Page 0 is always the superblock.

type PageInfo

type PageInfo struct {
	ID       PageID
	Type     PageType
	TypeStr  string
	LSN      LSN
	CRC      uint32
	CRCValid bool
	Flags    uint8
	// B+Tree specifics
	IsLeaf     bool
	KeyCount   int
	RightChild PageID
	NextLeaf   PageID
	PrevLeaf   PageID
	// Slotted page stats
	SlotCount int
	FreeSpace int
	// Overflow
	NextOverflow PageID
	DataLen      int
	// FreeList
	NextFreeList PageID
	EntryCount   int
}

PageInfo holds inspection information about a single page.

func InspectPage

func InspectPage(dbPath string, pageID PageID, pageSize int) (*PageInfo, error)

InspectPage reads a single page and returns detailed information.

type PageType

type PageType uint8

PageType identifies the kind of data stored in a page.

const (
	PageTypeSuperblock    PageType = 0x01
	PageTypeBTreeInternal PageType = 0x02
	PageTypeBTreeLeaf     PageType = 0x03
	PageTypeOverflow      PageType = 0x04
	PageTypeFreeList      PageType = 0x05
)

func (PageType) String

func (pt PageType) String() string

String returns a human-readable label for the page type.

type Pager

type Pager struct {
	// contains filtered or unexported fields
}

Pager manages page-level I/O, WAL, buffer pool, and free-list.

func OpenPager

func OpenPager(cfg PagerConfig) (*Pager, error)

OpenPager opens or creates a page-based database.

func (*Pager) AbortTx

func (p *Pager) AbortTx(txID TxID) error

AbortTx writes an ABORT record. Dirty pages for this TX will be discarded on the next recovery or checkpoint.

func (*Pager) AllocPage

func (p *Pager) AllocPage() (PageID, []byte)

AllocPage allocates a new page (from the free-list or by extending the file). Returns the page ID and a zeroed buffer. The page is pinned in the cache.

func (*Pager) BeginTx

func (p *Pager) BeginTx() (TxID, error)

BeginTx starts a new transaction and writes a BEGIN record to the WAL.

func (*Pager) Checkpoint

func (p *Pager) Checkpoint() error

Checkpoint flushes all dirty pages to the database file, writes an updated superblock, fsyncs the file, then truncates the WAL.

func (*Pager) Close

func (p *Pager) Close() error

Close performs a final checkpoint and closes all files.

func (*Pager) CommitTx

func (p *Pager) CommitTx(txID TxID) error

CommitTx writes a COMMIT record and fsyncs the WAL.

func (*Pager) FreePage

func (p *Pager) FreePage(pid PageID)

FreePage marks a page as free for reuse.

func (*Pager) PageSize

func (p *Pager) PageSize() int

PageSize returns the configured page size.

func (*Pager) Path

func (p *Pager) Path() string

Path returns the database file path.

func (*Pager) ReadPage

func (p *Pager) ReadPage(id PageID) ([]byte, error)

ReadPage returns a page by ID, using the buffer pool cache. The page is pinned in the cache; call UnpinPage when done.

func (*Pager) Recover

func (p *Pager) Recover() error

Recover replays the WAL and applies committed transactions.

func (*Pager) Superblock

func (p *Pager) Superblock() Superblock

Superblock returns a copy of the current superblock.

func (*Pager) UnpinPage

func (p *Pager) UnpinPage(id PageID)

UnpinPage decrements the pin count.

func (*Pager) UpdateSuperblock

func (p *Pager) UpdateSuperblock(fn func(sb *Superblock))

UpdateSuperblock updates the in-memory superblock fields. It does NOT write to disk. Use Checkpoint for that.

func (*Pager) WALPath

func (p *Pager) WALPath() string

WALPath returns the WAL file path.

func (*Pager) WritePage

func (p *Pager) WritePage(txID TxID, id PageID, buf []byte) error

WritePage writes (updates) a page through the WAL. The page image is logged to the WAL and cached as dirty. The caller should have called BeginTx beforehand.

type PagerConfig

type PagerConfig struct {
	DBPath        string
	WALPath       string
	PageSize      int
	MaxCachePages int // buffer pool capacity (0 = default 1024)
}

PagerConfig configures a Pager.

type SlotEntry

type SlotEntry struct {
	Offset uint16
	Length uint16
}

SlotEntry describes one slot in the directory.

type SlottedPage

type SlottedPage struct {
	// contains filtered or unexported fields
}

SlottedPage wraps a raw page buffer and provides record-level operations.

func InitSlottedPage

func InitSlottedPage(buf []byte, pt PageType, id PageID) *SlottedPage

InitSlottedPage initialises a page buffer as an empty slotted page.

func WrapSlottedPage

func WrapSlottedPage(buf []byte) *SlottedPage

WrapSlottedPage wraps an existing page buffer.

func (*SlottedPage) Bytes

func (sp *SlottedPage) Bytes() []byte

Bytes returns the underlying page buffer.

func (*SlottedPage) Compact

func (sp *SlottedPage) Compact()

Compact reorganises records to remove gaps left by deletions. Preserves slot order. This is needed before splitting pages.

func (*SlottedPage) DeleteRecord

func (sp *SlottedPage) DeleteRecord(i int) error

DeleteRecord marks slot i as deleted (tombstone).

func (*SlottedPage) FreeSpace

func (sp *SlottedPage) FreeSpace() int

FreeSpace returns the number of bytes available for new records+slots.

func (*SlottedPage) FreeSpaceEnd

func (sp *SlottedPage) FreeSpaceEnd() int

FreeSpaceEnd is the byte offset where the next record will be written.

func (*SlottedPage) GetRecord

func (sp *SlottedPage) GetRecord(i int) []byte

GetRecord returns the raw bytes of the record at slot i. Returns nil if the slot is a tombstone.

func (*SlottedPage) GetSlot

func (sp *SlottedPage) GetSlot(i int) SlotEntry

GetSlot returns the slot entry at index i.

func (*SlottedPage) InsertRecord

func (sp *SlottedPage) InsertRecord(data []byte) (int, error)

InsertRecord adds a new record to the page. Returns the slot index, or an error if there is insufficient space.

func (*SlottedPage) IsDeleted

func (sp *SlottedPage) IsDeleted(i int) bool

IsDeleted returns true if slot i is a tombstone.

func (*SlottedPage) LiveRecords

func (sp *SlottedPage) LiveRecords() int

LiveRecords returns the count of non-deleted records.

func (*SlottedPage) SlotCount

func (sp *SlottedPage) SlotCount() int

SlotCount returns the number of slots (including tombstones).

func (*SlottedPage) UpdateRecord

func (sp *SlottedPage) UpdateRecord(i int, data []byte) error

UpdateRecord replaces the record at slot i. If the new data fits in the old slot's space, it is written in-place; otherwise the old slot is tombstoned and a new record is appended.

type Superblock

type Superblock struct {
	FormatVersion uint32
	PageSize      uint32
	PageCount     uint64
	FeatureFlags  FeatureFlag
	CatalogRoot   PageID
	FreeListRoot  PageID
	CheckpointLSN LSN
	NextTxID      TxID
	NextPageID    PageID
}

Superblock holds the parsed contents of page 0.

func NewSuperblock

func NewSuperblock(pageSize uint32) *Superblock

NewSuperblock creates a default Superblock for a new database.

func UnmarshalSuperblock

func UnmarshalSuperblock(buf []byte) (*Superblock, error)

UnmarshalSuperblock decodes page 0 from buf. It validates magic bytes, format version, feature flags, and CRC. Returns an error on any mismatch.

type SuperblockInfo

type SuperblockInfo struct {
	FormatVersion uint32
	PageSize      uint32
	PageCount     uint64
	FeatureFlags  uint64
	CatalogRoot   PageID
	FreeListRoot  PageID
	CheckpointLSN LSN
	NextTxID      TxID
	NextPageID    PageID
	CRCValid      bool
}

SuperblockInfo holds display-friendly superblock data.

func InspectSuperblock

func InspectSuperblock(dbPath string) (*SuperblockInfo, error)

InspectSuperblock reads and returns the superblock metadata.

type TableData

type TableData struct {
	Name    string
	Columns []ColumnInfo
	Rows    [][]any
	IsTemp  bool
	Version int
}

TableData is the pager-level representation of a table. Higher layers convert between TableData and storage.Table.

type TxID

type TxID uint64

TxID is a transaction identifier.

type WALFile

type WALFile struct {
	// contains filtered or unexported fields
}

WALFile manages the append-only WAL file.

func OpenWALFile

func OpenWALFile(path string, pageSize int) (*WALFile, error)

OpenWALFile opens or creates a WAL file. If the file exists, it validates the header. If it does not exist, it writes a new header.

func (*WALFile) AppendRecord

func (wf *WALFile) AppendRecord(rec *WALRecord) (LSN, error)

AppendRecord writes a WAL record and assigns it a monotonic LSN. Returns the assigned LSN.

func (*WALFile) Close

func (wf *WALFile) Close() error

Close closes the WAL file.

func (*WALFile) NextLSN

func (wf *WALFile) NextLSN() LSN

NextLSN returns the next LSN that will be assigned.

func (*WALFile) SetNextLSN

func (wf *WALFile) SetNextLSN(lsn LSN)

SetNextLSN allows recovery to set the LSN counter.

func (*WALFile) Sync

func (wf *WALFile) Sync() error

Sync fsyncs the WAL file to guarantee durability.

func (*WALFile) Truncate

func (wf *WALFile) Truncate() error

Truncate resets the WAL file to just the header (after a checkpoint).

type WALInfo

type WALInfo struct {
	PageSize   int
	Records    int
	MinLSN     LSN
	MaxLSN     LSN
	TxCount    int
	Committed  int
	Aborted    int
	PageImages int
}

WALInfo holds information about a WAL file.

func InspectWAL

func InspectWAL(walPath string) (*WALInfo, error)

InspectWAL reads and summarises a WAL file.

type WALRecord

type WALRecord struct {
	Type   WALRecordType
	LSN    LSN
	TxID   TxID
	PageID PageID
	Data   []byte // full page image for PAGE_IMAGE, nil otherwise
}

WALRecord is an in-memory representation of a WAL record.

func ReadAllRecords

func ReadAllRecords(path string) ([]*WALRecord, error)

ReadAllRecords reads all WAL records from the file (after the header). Partial/corrupt records at the tail are silently ignored (crash truncation).

type WALRecordType

type WALRecordType uint8

WALRecordType identifies the kind of WAL record.

const (
	WALRecordBegin      WALRecordType = 0x01
	WALRecordPageImage  WALRecordType = 0x02
	WALRecordCommit     WALRecordType = 0x03
	WALRecordAbort      WALRecordType = 0x04
	WALRecordCheckpoint WALRecordType = 0x05
)

func (WALRecordType) String

func (rt WALRecordType) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL