tiny.sql.MetaPage
Defined in page.
API (17)
Actions
Public operations.
adoptChainallocatechainHeadfreeAtfreeCapacityfreeCountgenerationhighestPageidinitisChainedloadrefillFromChainreleasereserveThroughspillEntries
Fields and members
Public fields and members.
Source
Source: lib/sql/src/page.zig:740
zig
pub const Meta = struct { bytes: *[size]u8, pub fn init(bytes: *[size]u8, page_id: u64, highest_page: u32) Meta { var meta = Meta{ .bytes = bytes }; @memset(meta.bytes, 0); @memcpy(meta.bytes[magic_offset..][0..magic.len], magic[0..]); meta.bytes[version_offset] = format_version; meta.bytes[kind_offset] = meta_kind; meta.writeU16(flags_offset, 0); meta.writeU64(id_offset, page_id); meta.writeU64(generation_offset, 0); meta.writeU32(meta_highest_offset, highest_page); meta.writeU16(meta_free_count_offset, 0); meta.writeU16(meta_reserved_offset, 0); return meta; } pub fn load(bytes: *[size]u8) Error!Meta { const meta = Meta{ .bytes = bytes }; try meta.validate(); return meta; } pub fn id(self: *const Meta) u64 { return self.readU64(id_offset); } pub fn generation(self: *const Meta) u64 { return self.readU64(generation_offset); } pub fn highestPage(self: *const Meta) u32 { return self.readU32(meta_highest_offset); } pub fn freeCount(self: *const Meta) usize { return self.readU16(meta_free_count_offset); } pub fn isChained(self: *const Meta) bool { return self.readU16(flags_offset) & meta_chained_flag != 0; } pub fn chainHead(self: *const Meta) u32 { if (!self.isChained()) return 0; return self.readU32(meta_chain_offset); } pub fn freeCapacity(self: *const Meta) usize { return (size - self.entriesOffset()) / meta_entry_size; } fn entriesOffset(self: *const Meta) usize { return if (self.isChained()) meta_chained_entries_offset else header_size; } pub fn allocate(self: *Meta) Error!u32 { const next_generation = try self.nextGeneration(); const count = self.freeCount(); if (count > 0) { const page_id = self.freeAt(count - 1); self.writeU16(meta_free_count_offset, @intCast(count - 1)); self.writeU64(generation_offset, next_generation); return page_id; } const highest = self.highestPage(); if (highest == std.math.maxInt(u32)) return error.InvalidPageId; const page_id = highest + 1; self.writeU32(meta_highest_offset, page_id); self.writeU64(generation_offset, next_generation); return page_id; } pub fn reserveThrough(self: *Meta, page_id: u32) Error!bool { if (page_id == 0) return error.InvalidPageId; if (page_id <= self.highestPage()) return false; const next_generation = try self.nextGeneration(); self.writeU32(meta_highest_offset, page_id); self.writeU64(generation_offset, next_generation); return true; } pub fn release(self: *Meta, page_id: u32) Error!void { if (page_id == 0 or @as(u64, page_id) == self.id() or page_id > self.highestPage()) return error.InvalidPageId; if (self.contains(page_id)) return error.InvalidPage; if (page_id == self.highestPage()) return self.releaseHighest(); const count = self.freeCount(); if (count >= self.freeCapacity()) return error.FreeListFull; const next_generation = try self.nextGeneration(); self.writeFree(count, page_id); self.writeU16(meta_free_count_offset, @intCast(count + 1)); self.writeU64(generation_offset, next_generation); } pub fn spillEntries(self: *Meta, buffer: []u32) Error!usize { const count = self.freeCount(); if (count == 0 or count > buffer.len) return error.InvalidPage; const next_generation = try self.nextGeneration(); var index: usize = 0; while (index < count) : (index += 1) buffer[index] = self.freeAt(index); self.writeU16(meta_free_count_offset, 0); self.writeU64(generation_offset, next_generation); return count; } pub fn adoptChain(self: *Meta, head: u32) Error!void { if (head == 0 or @as(u64, head) == self.id() or head > self.highestPage()) return error.InvalidPageId; if (self.freeCount() != 0) return error.InvalidPage; const next_generation = try self.nextGeneration(); self.writeU16(flags_offset, meta_chained_flag); self.writeU32(meta_chain_offset, head); self.writeU64(generation_offset, next_generation); } pub fn refillFromChain(self: *Meta, next_head: u32, entries: []const u32) Error!void { if (!self.isChained()) return error.InvalidPage; if (self.freeCount() != 0) return error.InvalidPage; if (next_head != 0 and (@as(u64, next_head) == self.id() or next_head > self.highestPage())) return error.InvalidPageId; for (entries) |entry| { if (entry == 0 or @as(u64, entry) == self.id() or entry > self.highestPage()) return error.InvalidPage; } const target_entries_offset: usize = if (next_head == 0) header_size else meta_chained_entries_offset; if (entries.len > (size - target_entries_offset) / meta_entry_size) return error.InvalidPage; const next_generation = try self.nextGeneration(); if (next_head == 0) { self.writeU16(flags_offset, 0); self.writeU32(meta_chain_offset, 0); } else { self.writeU32(meta_chain_offset, next_head); } for (entries, 0..) |entry, index| self.writeFree(index, entry); self.writeU16(meta_free_count_offset, @intCast(entries.len)); self.writeU64(generation_offset, next_generation); } pub fn freeAt(self: *const Meta, index: usize) u32 { return self.readU32(self.entriesOffset() + index * meta_entry_size); } fn validate(self: *const Meta) Error!void { if (!std.mem.eql(u8, self.bytes[magic_offset..][0..magic.len], magic[0..])) return error.InvalidPage; if (self.bytes[version_offset] != format_version) return error.InvalidPage; if (self.bytes[kind_offset] != meta_kind) return error.InvalidPage; const flags = self.readU16(flags_offset); if (flags & ~meta_chained_flag != 0) return error.InvalidPage; if (self.readU16(meta_reserved_offset) != 0) return error.InvalidPage; if (flags & meta_chained_flag != 0) { const head = self.readU32(meta_chain_offset); if (head == 0 or @as(u64, head) == self.id() or head > self.highestPage()) return error.InvalidPage; } const count = self.freeCount(); if (count > self.freeCapacity()) return error.InvalidPage; if (self.highestPage() == 0) return error.InvalidPage; var index: usize = 0; while (index < count) : (index += 1) { const page_id = self.freeAt(index); if (page_id == 0 or @as(u64, page_id) == self.id() or page_id > self.highestPage()) return error.InvalidPage; var compare: usize = index + 1; while (compare < count) : (compare += 1) { if (page_id == self.freeAt(compare)) return error.InvalidPage; } } } fn contains(self: *const Meta, page_id: u32) bool { var index: usize = 0; while (index < self.freeCount()) : (index += 1) { if (self.freeAt(index) == page_id) return true; } return false; } fn releaseHighest(self: *Meta) Error!void { const next_generation = try self.nextGeneration(); var highest = self.highestPage() - 1; var count = self.freeCount(); while (count > 0) { const index = self.freeIndex(highest, count) orelse break; count -= 1; if (index != count) self.writeFree(index, self.freeAt(count)); highest -= 1; } self.writeU32(meta_highest_offset, highest); self.writeU16(meta_free_count_offset, @intCast(count)); self.writeU64(generation_offset, next_generation); } fn freeIndex(self: *const Meta, page_id: u32, count: usize) ?usize { var index: usize = 0; while (index < count) : (index += 1) { if (self.freeAt(index) == page_id) return index; } return null; } fn nextGeneration(self: *const Meta) Error!u64 { const current = self.generation(); if (current == std.math.maxInt(u64)) return error.GenerationOverflow; return current + 1; } fn writeFree(self: *Meta, index: usize, page_id: u32) void { self.writeU32(self.entriesOffset() + index * meta_entry_size, page_id); } fn readU16(self: *const Meta, offset: usize) u16 { return std.mem.readInt(u16, self.bytes[offset..][0..2], .big); } fn readU32(self: *const Meta, offset: usize) u32 { return std.mem.readInt(u32, self.bytes[offset..][0..4], .big); } fn readU64(self: *const Meta, offset: usize) u64 { return std.mem.readInt(u64, self.bytes[offset..][0..8], .big); } fn writeU16(self: *Meta, offset: usize, value: u16) void { std.mem.writeInt(u16, self.bytes[offset..][0..2], value, .big); } fn writeU32(self: *Meta, offset: usize, value: u32) void { std.mem.writeInt(u32, self.bytes[offset..][0..4], value, .big); } fn writeU64(self: *Meta, offset: usize, value: u64) void { std.mem.writeInt(u64, self.bytes[offset..][0..8], value, .big); }};Source: lib/sql/src/root.zig:58
zig
pub const MetaPage = page.Meta;Complete call list for MetaPage.adoptChain
7 direct calls.
tiny.sql.MetaPage.freeCount[method] atlib/sql/src/page.zig:776tiny.sql.MetaPage.highestPage[method] atlib/sql/src/page.zig:772tiny.sql.MetaPage.id[method] atlib/sql/src/page.zig:764lib.sql.src.page.Meta.nextGeneration[method] — private source atlib/sql/src/page.zig:936in nearest public ownertiny.sql.pagelib.sql.src.page.Meta.writeU16[method] — private source atlib/sql/src/page.zig:958in nearest public ownertiny.sql.pagelib.sql.src.page.Meta.writeU32[method] — private source atlib/sql/src/page.zig:962in nearest public ownertiny.sql.pagelib.sql.src.page.Meta.writeU64[method] — private source atlib/sql/src/page.zig:966in nearest public ownertiny.sql.page
Complete call list for MetaPage.allocate
7 direct calls.
tiny.sql.MetaPage.freeAt[method] atlib/sql/src/page.zig:876tiny.sql.MetaPage.freeCount[method] atlib/sql/src/page.zig:776tiny.sql.MetaPage.highestPage[method] atlib/sql/src/page.zig:772lib.sql.src.page.Meta.nextGeneration[method] — private source atlib/sql/src/page.zig:936in nearest public ownertiny.sql.pagelib.sql.src.page.Meta.writeU16[method] — private source atlib/sql/src/page.zig:958in nearest public ownertiny.sql.pagelib.sql.src.page.Meta.writeU32[method] — private source atlib/sql/src/page.zig:962in nearest public ownertiny.sql.pagelib.sql.src.page.Meta.writeU64[method] — private source atlib/sql/src/page.zig:966in nearest public ownertiny.sql.page
Complete caller list for MetaPage.freeCount
12 direct callers.
tiny.sql.MetaPage.adoptChain[method] atlib/sql/src/page.zig:846tiny.sql.MetaPage.allocate[method] atlib/sql/src/page.zig:797lib.sql.src.page.Meta.contains[method] — private source atlib/sql/src/page.zig:905in nearest public ownertiny.sql.pagetiny.sql.MetaPage.refillFromChain[method] atlib/sql/src/page.zig:855tiny.sql.MetaPage.release[method] atlib/sql/src/page.zig:823lib.sql.src.page.Meta.releaseHighest[method] — private source atlib/sql/src/page.zig:913in nearest public ownertiny.sql.pagetiny.sql.MetaPage.spillEntries[method] atlib/sql/src/page.zig:835lib.sql.src.page.Meta.validate[method] — private source atlib/sql/src/page.zig:880in nearest public ownertiny.sql.pagelib.sql.src.page.test_meta_page_allocates_appends_and_reuses_released_pages[function] — test source atlib/sql/src/page.zig:1648in nearest public ownertiny.sql.pagelib.sql.src.page.test_meta_page_rejects_malformed_chain_transitions[function] — test source atlib/sql/src/page.zig:1741in nearest public ownertiny.sql.pagelib.sql.src.page.test_meta_page_spills_and_refills_a_chained_free_list[function] — test source atlib/sql/src/page.zig:1707in nearest public ownertiny.sql.pagelib.sql.src.page.test_meta_page_truncates_descending_high-page_releases[function] — test source atlib/sql/src/page.zig:1673in nearest public ownertiny.sql.page
Complete caller list for MetaPage.highestPage
10 direct callers.
tiny.sql.MetaPage.adoptChain[method] atlib/sql/src/page.zig:846tiny.sql.MetaPage.allocate[method] atlib/sql/src/page.zig:797tiny.sql.MetaPage.refillFromChain[method] atlib/sql/src/page.zig:855tiny.sql.MetaPage.release[method] atlib/sql/src/page.zig:823lib.sql.src.page.Meta.releaseHighest[method] — private source atlib/sql/src/page.zig:913in nearest public ownertiny.sql.pagetiny.sql.MetaPage.reserveThrough[method] atlib/sql/src/page.zig:814lib.sql.src.page.Meta.validate[method] — private source atlib/sql/src/page.zig:880in nearest public ownertiny.sql.pagelib.sql.src.page.test_meta_page_allocates_appends_and_reuses_released_pages[function] — test source atlib/sql/src/page.zig:1648in nearest public ownertiny.sql.pagelib.sql.src.page.test_meta_page_truncates_descending_high-page_releases[function] — test source atlib/sql/src/page.zig:1673in nearest public ownertiny.sql.pagelib.sql.src.page.test_meta_reserves_explicit_root_pages_before_allocation[function] — test source atlib/sql/src/page.zig:1685in nearest public ownertiny.sql.page
Complete caller list for MetaPage.init
10 direct callers.
lib.sql.src.page.test_meta_page_allocates_appends_and_reuses_released_pages[function] — test source atlib/sql/src/page.zig:1648in nearest public ownertiny.sql.pagelib.sql.src.page.test_meta_page_rejects_invalid_free-list_entries[function] — test source atlib/sql/src/page.zig:1694in nearest public ownertiny.sql.pagelib.sql.src.page.test_meta_page_rejects_malformed_chain_transitions[function] — test source atlib/sql/src/page.zig:1741in nearest public ownertiny.sql.pagelib.sql.src.page.test_meta_page_spills_and_refills_a_chained_free_list[function] — test source atlib/sql/src/page.zig:1707in nearest public ownertiny.sql.pagelib.sql.src.page.test_meta_page_truncates_descending_high-page_releases[function] — test source atlib/sql/src/page.zig:1673in nearest public ownertiny.sql.pagelib.sql.src.page.test_meta_reserves_explicit_root_pages_before_allocation[function] — test source atlib/sql/src/page.zig:1685in nearest public ownertiny.sql.pagelib.sql.src.tree.Allocation.init[function] — private source atlib/sql/src/tree.zig:332in nearest public ownertiny.sql.treelib.sql.src.tree.test_tree_rejects_a_reserved_root_with_a_byte_past_a_zero_header[function] — test source atlib/sql/src/tree.zig:2403in nearest public ownertiny.sql.treelib.sql.src.tree.test_tree_scan_projection_controls_overflow_materialization[function] — test source atlib/sql/src/tree.zig:3354in nearest public ownertiny.sql.treelib.sql.src.tree.test_tree_treats_sparse_reserved_root_as_empty[function] — test source atlib/sql/src/tree.zig:2372in nearest public ownertiny.sql.tree
Complete caller list for MetaPage.load
12 direct callers.
lib.sql.src.page.test_meta_page_allocates_appends_and_reuses_released_pages[function] — test source atlib/sql/src/page.zig:1648in nearest public ownertiny.sql.pagelib.sql.src.page.test_meta_page_rejects_invalid_free-list_entries[function] — test source atlib/sql/src/page.zig:1694in nearest public ownertiny.sql.pagelib.sql.src.page.test_meta_page_rejects_malformed_chain_transitions[function] — test source atlib/sql/src/page.zig:1741in nearest public ownertiny.sql.pagelib.sql.src.page.test_meta_page_spills_and_refills_a_chained_free_list[function] — test source atlib/sql/src/page.zig:1707in nearest public ownertiny.sql.pagelib.sql.src.tree.Allocation.init[function] — private source atlib/sql/src/tree.zig:332in nearest public ownertiny.sql.treelib.sql.src.tree.Write.allocatePage[method] — private source atlib/sql/src/tree.zig:510in nearest public ownertiny.sql.treelib.sql.src.tree.Write.releasePage[method] — private source atlib/sql/src/tree.zig:518in nearest public ownertiny.sql.treelib.sql.src.tree.seedFullInlineFreeList[function] — private source atlib/sql/src/tree.zig:3140in nearest public ownertiny.sql.treelib.sql.src.tree.test_allocated_roots_clear_recycled_page_images[function] — test source atlib/sql/src/tree.zig:3029in nearest public ownertiny.sql.treelib.sql.src.tree.test_tree_reuses_freed_pages_after_delete_compaction[function] — test source atlib/sql/src/tree.zig:2963in nearest public ownertiny.sql.treelib.sql.src.tree.test_tree_spills_a_full_inline_free_list_into_a_chain_and_refills_it[function] — test source atlib/sql/src/tree.zig:3162in nearest public ownertiny.sql.treelib.sql.src.tree.test_tree_stores_large_values_in_overflow_pages_and_reuses_replaced_chains[function] — test source atlib/sql/src/tree.zig:3273in nearest public ownertiny.sql.tree
Complete call list for MetaPage.refillFromChain
9 direct calls.
tiny.sql.MetaPage.freeCount[method] atlib/sql/src/page.zig:776tiny.sql.MetaPage.highestPage[method] atlib/sql/src/page.zig:772tiny.sql.MetaPage.id[method] atlib/sql/src/page.zig:764tiny.sql.MetaPage.isChained[method] atlib/sql/src/page.zig:780lib.sql.src.page.Meta.nextGeneration[method] — private source atlib/sql/src/page.zig:936in nearest public ownertiny.sql.pagelib.sql.src.page.Meta.writeFree[method] — private source atlib/sql/src/page.zig:942in nearest public ownertiny.sql.pagelib.sql.src.page.Meta.writeU16[method] — private source atlib/sql/src/page.zig:958in nearest public ownertiny.sql.pagelib.sql.src.page.Meta.writeU32[method] — private source atlib/sql/src/page.zig:962in nearest public ownertiny.sql.pagelib.sql.src.page.Meta.writeU64[method] — private source atlib/sql/src/page.zig:966in nearest public ownertiny.sql.page
Complete call list for MetaPage.release
10 direct calls.
lib.sql.src.page.Meta.contains[method] — private source atlib/sql/src/page.zig:905in nearest public ownertiny.sql.pagetiny.sql.MetaPage.freeCapacity[method] atlib/sql/src/page.zig:789tiny.sql.MetaPage.freeCount[method] atlib/sql/src/page.zig:776tiny.sql.MetaPage.highestPage[method] atlib/sql/src/page.zig:772tiny.sql.MetaPage.id[method] atlib/sql/src/page.zig:764lib.sql.src.page.Meta.nextGeneration[method] — private source atlib/sql/src/page.zig:936in nearest public ownertiny.sql.pagelib.sql.src.page.Meta.releaseHighest[method] — private source atlib/sql/src/page.zig:913in nearest public ownertiny.sql.pagelib.sql.src.page.Meta.writeFree[method] — private source atlib/sql/src/page.zig:942in nearest public ownertiny.sql.pagelib.sql.src.page.Meta.writeU16[method] — private source atlib/sql/src/page.zig:958in nearest public ownertiny.sql.pagelib.sql.src.page.Meta.writeU64[method] — private source atlib/sql/src/page.zig:966in nearest public ownertiny.sql.page
Audit
| Definitions | 17 |
|---|---|
| Public names | 34 |
| Members | 1 |
| Version | 26.7.0 |
| Revision | daab053ee433 |