Documentation
¶
Overview ¶
Package pager is aki's single-file pager and buffer pool (spec 2064 doc 03). It turns a flat VFS file into an array of fixed-size pages, caches hot pages in memory, tracks dirty pages, allocates and frees pages through a freelist, and commits a transaction atomically by swapping the double-buffered meta page (doc 02 §9). Durability via the write-ahead log is layered on top in the wal package (doc 04); on its own the pager is already crash-atomic because a commit becomes visible only when the higher-sequence meta page is fsynced.
Index ¶
- Variables
- type CommitInfo
- type Options
- type Page
- type Pager
- func (p *Pager) Allocate() (*Page, error)
- func (p *Pager) CheckFreelist() (int, error)
- func (p *Pager) Close() error
- func (p *Pager) Commit(info CommitInfo) error
- func (p *Pager) Free(pgno uint32) error
- func (p *Pager) FreeCount() int
- func (p *Pager) FreePages() []uint32
- func (p *Pager) Get(pgno uint32) (*Page, error)
- func (p *Pager) Header() format.FileHeader
- func (p *Pager) Meta() format.MetaPage
- func (p *Pager) Name() string
- func (p *Pager) PageCount() uint32
- func (p *Pager) PageSize() uint32
- func (p *Pager) PinnedPages() []uint32
- func (p *Pager) Stats() Stats
- func (p *Pager) Unpin(pg *Page, dirty bool)
- type Stats
Constants ¶
This section is empty.
Variables ¶
var ( ErrClosed = errors.New("aki/pager: pager is closed") ErrPinned = errors.New("aki/pager: page still pinned") ErrInvalidPage = errors.New("aki/pager: invalid page number") ErrNoMeta = errors.New("aki/pager: no valid meta page") ErrReadOnlyMeta = errors.New("aki/pager: page 0/1/2 are reserved") )
Errors returned by the pager.
Functions ¶
This section is empty.
Types ¶
type CommitInfo ¶
type CommitInfo struct {
CatalogRoot uint32
SystemRoot uint32
DBRootPages [8]uint32
WALCommitLSN uint64
SchemaVersion uint32
// SetDBRoots, when true, replaces the DB root array; otherwise the existing
// roots are kept.
SetDBRoots bool
// SetCatalogRoot, when true, replaces the catalog root.
SetCatalogRoot bool
// SetSystemRoot, when true, replaces the system table root.
SetSystemRoot bool
}
CommitInfo carries the per-commit values the caller wants recorded in the new meta snapshot: the updated catalog root, the per-DB B-tree roots, and the WAL commit LSN (zero when the WAL is not in use). Fields left at their zero value inherit the current live meta.
type Options ¶
type Options struct {
// PageSize is used only by Create; Open reads it from the header. Zero means
// format.DefaultPageSize.
PageSize uint32
// DBCount is used only by Create. Zero means format.DefaultDBCount.
DBCount uint32
// CachePages is the buffer-pool capacity in frames. Zero means a default.
CachePages int
// CreateTimeUS stamps the header at create time. Tests pass a fixed value;
// the engine passes the wall clock. Zero is allowed.
CreateTimeUS uint64
}
Options configure a new or opened pager.
type Page ¶
Page is a single in-memory page frame. Data is exactly pageSize bytes and is the authoritative copy while the page is cached; readers and writers operate on Data directly and mark the page dirty through the pager.
type Pager ¶
type Pager struct {
// contains filtered or unexported fields
}
Pager owns a single .aki file and its in-memory page cache.
func Create ¶
Create initialises a fresh .aki file: page 0 header, meta pages 1 and 2, and an empty freelist. It fails if the file already exists with content.
func (*Pager) Allocate ¶
Allocate returns a fresh page for writing, reusing a freelist page when one is available or extending the file otherwise. The returned page is pinned and already marked dirty; its contents are zeroed.
func (*Pager) CheckFreelist ¶
CheckFreelist walks the on-disk freelist chain from the meta head, following the next-link in each free page. It detects a cycle and an out-of-range link, which a plain load cannot since it would loop or read garbage. It returns the number of free pages on a healthy chain. The integrity checker calls it.
func (*Pager) Close ¶
Close flushes nothing implicitly (callers Commit first) and releases the file handle. It errors if any page is still pinned.
func (*Pager) Commit ¶
func (p *Pager) Commit(info CommitInfo) error
Commit makes the current set of dirty pages durable and atomically advances the live meta snapshot (doc 02 §9.1, doc 03 §8). The protocol is:
- flush every dirty data page to its slot and fsync, so the page images are durable before the meta pointer that references them;
- persist the freelist chain if it changed;
- build the next meta with seq = live+1, write it to the non-live meta slot, and fsync, which is the linearization point: the commit is visible exactly when this fsync returns;
- best-effort refresh of the file header's mutable fields.
A crash before step 3's fsync leaves the previous meta live, so the whole transaction rolls back atomically with no journal.
func (*Pager) FreePages ¶
FreePages returns a copy of the in-memory freelist. The page-accounting check uses it to prove no live page is also free, and to find leaked pages that are neither live nor free.
func (*Pager) Get ¶
Get pins and returns the page numbered pgno, faulting it in from disk if it is not resident. The caller must Unpin it when done.
func (*Pager) Header ¶
func (p *Pager) Header() format.FileHeader
Header returns a copy of the file header.
func (*Pager) Name ¶
Name returns the file path this pager was opened with. It is empty for an in-memory backing.
func (*Pager) PinnedPages ¶
PinnedPages returns the page numbers currently held with a non-zero pin count. After a command finishes every page should be unpinned, so a debug build calls this to catch a Get that was never matched by an Unpin (doc 23 section 9.4).
type Stats ¶
type Stats struct {
PageSize uint32
PageCount uint32
FreeCount int
FileBytes int64
ResidentPages int
DirtyPages int
CacheHits uint64
CacheMisses uint64
}
Stats is a point-in-time snapshot of pager and buffer-pool counters. The server reads it for the file-growth INFO fields in doc 20 section 9.8.