///|
priv struct Meta {
root : Int
freelist : Int
txn_id : Int
page_count : Int
}
///|
fn blank_page() -> FixedArray[Byte] {
FixedArray::make(page_size, b'\x00')
}
///|
fn page_bytes(page : FixedArray[Byte]) -> Bytes {
fixed_to_bytes(page)
}
///|
/// 第 0 页:magic、version、page_size、root、freelist、txn_id、page_count、crc32
fn encode_header(meta : Meta) -> FixedArray[Byte] {
let page = blank_page()
copy_bytes(magic, page, 0)
write_u32(page, 8, format_version)
write_u32(page, 12, page_size.reinterpret_as_uint())
write_u64_int(page, 16, meta.root)
write_u64_int(page, 24, meta.freelist)
write_u64_int(page, 32, meta.txn_id)
write_u64_int(page, 40, meta.page_count)
write_u32(
page,
header_len,
crc32(page.unsafe_reinterpret_as_bytes()[:header_len]),
)
page
}
///|
fn decode_header(page : Bytes) -> Meta raise DbError {
guard page.length() == page_size else { raise DbError::Corrupt }
guard page[0:8] == magic[:] else { raise DbError::Corrupt }
guard read_u32(page, 8) == format_version else { raise DbError::Corrupt }
guard read_u32(page, 12) == page_size.reinterpret_as_uint() else {
raise DbError::Corrupt
}
let stored = read_u32(page, header_len)
guard crc32(page[:header_len]) == stored else { raise DbError::Corrupt }
{
root: read_u64_as_int(page, 16),
freelist: read_u64_as_int(page, 24),
txn_id: read_u64_as_int(page, 32),
page_count: read_u64_as_int(page, 40),
}
}