mirror of
https://github.com/wader/fq.git
synced 2024-11-23 09:56:07 +03:00
postgres: pg_btree begin impl
This commit is contained in:
parent
f122f72373
commit
dd84d3218c
@ -103,6 +103,7 @@ const (
|
||||
OPUS_PACKET = "opus_packet"
|
||||
PCAP = "pcap"
|
||||
PCAPNG = "pcapng"
|
||||
PG_BTREE = "pg_btree"
|
||||
PG_WAL = "pg_wal"
|
||||
PG_WALPAGE = "pg_wal_page"
|
||||
PG_MULTIXACTOFF = "pg_multixact_offsets"
|
||||
|
146
format/postgres/flavours/postgres14/pg_btree.go
Normal file
146
format/postgres/flavours/postgres14/pg_btree.go
Normal file
@ -0,0 +1,146 @@
|
||||
package postgres14
|
||||
|
||||
import (
|
||||
"github.com/wader/fq/format/postgres/common"
|
||||
"github.com/wader/fq/pkg/decode"
|
||||
)
|
||||
|
||||
const (
|
||||
BTREE_MAGIC = 0x053162
|
||||
)
|
||||
|
||||
// struct BTMetaPageData {
|
||||
/* 0 | 4 */ // uint32 btm_magic
|
||||
/* 4 | 4 */ // uint32 btm_version
|
||||
/* 8 | 4 */ // BlockNumber btm_root
|
||||
/* 12 | 4 */ // uint32 btm_level
|
||||
/* 16 | 4 */ // BlockNumber btm_fastroot
|
||||
/* 20 | 4 */ // uint32 btm_fastlevel
|
||||
/* 24 | 4 */ // uint32 btm_last_cleanup_num_delpages
|
||||
/* XXX 4-byte hole */
|
||||
/* 32 | 8 */ // float8 btm_last_cleanup_num_heap_tuples
|
||||
/* 40 | 1 */ // _Bool btm_allequalimage
|
||||
/* XXX 7-byte padding */
|
||||
//
|
||||
/* total size (bytes): 48 */
|
||||
|
||||
func DecodePgBTree(d *decode.D) any {
|
||||
d.SeekAbs(0)
|
||||
|
||||
btree := &BTreeD{
|
||||
PageSize: common.HeapPageSize,
|
||||
}
|
||||
decodeBTreePages(btree, d)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type BTreeD struct {
|
||||
PageSize uint64
|
||||
page *BTreePage
|
||||
}
|
||||
|
||||
type BTreePage struct {
|
||||
heap HeapPage
|
||||
bytesPosBegin uint64 // bytes pos of page's beginning
|
||||
bytesPosEnd uint64 // bytes pos of page's ending
|
||||
bytesPosSpecial uint64 // bytes pos of page's special
|
||||
}
|
||||
|
||||
type HeapPage struct {
|
||||
PdLower uint16
|
||||
PdUpper uint16
|
||||
PdSpecial uint16
|
||||
PdPagesizeVersion uint16
|
||||
}
|
||||
|
||||
func decodeBTreePages(btree *BTreeD, d *decode.D) {
|
||||
for i := 0; ; i++ {
|
||||
if end, _ := d.TryEnd(); end {
|
||||
return
|
||||
}
|
||||
|
||||
page := &BTreePage{}
|
||||
if btree.page != nil {
|
||||
// use prev page
|
||||
page.bytesPosBegin = btree.page.bytesPosEnd
|
||||
}
|
||||
page.bytesPosEnd = common.TypeAlign(btree.PageSize, page.bytesPosBegin+1)
|
||||
btree.page = page
|
||||
|
||||
if i == 0 {
|
||||
// first page contains meta information
|
||||
d.FieldStruct("heap_page", func(d *decode.D) {
|
||||
decodeBTreeMetaPage(btree, d)
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
if i > 0 {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func decodeBTreeMetaPage(btree *BTreeD, d *decode.D) {
|
||||
d.FieldStruct("page_header", func(d *decode.D) {
|
||||
decodePageHeader(btree, d)
|
||||
})
|
||||
d.FieldStruct("meta_page_data", func(d *decode.D) {
|
||||
decodeBTMetaPageData(btree, d)
|
||||
})
|
||||
}
|
||||
|
||||
func decodePageHeader(btree *BTreeD, d *decode.D) {
|
||||
heap := btree.page.heap
|
||||
|
||||
d.FieldStruct("pd_lsn", func(d *decode.D) {
|
||||
/* 0 | 4 */ // uint32 xlogid;
|
||||
/* 4 | 4 */ // uint32 xrecoff;
|
||||
d.FieldU32("xlogid", common.HexMapper)
|
||||
d.FieldU32("xrecoff", common.HexMapper)
|
||||
})
|
||||
d.FieldU16("pd_checksum")
|
||||
d.FieldU16("pd_flags")
|
||||
heap.PdLower = uint16(d.FieldU16("pd_lower"))
|
||||
heap.PdUpper = uint16(d.FieldU16("pd_upper"))
|
||||
heap.PdSpecial = uint16(d.FieldU16("pd_special"))
|
||||
heap.PdPagesizeVersion = uint16(d.FieldU16("pd_pagesize_version"))
|
||||
d.FieldU32("pd_prune_xid")
|
||||
|
||||
// ItemIdData pd_linp[];
|
||||
//page.ItemsEnd = int64(page.PagePosBegin*8) + int64(page.PdLower*8)
|
||||
//d.FieldArray("pd_linp", func(d *decode.D) {
|
||||
// DecodeItemIds(heap, d)
|
||||
//})
|
||||
}
|
||||
|
||||
func decodeBTMetaPageData(btree *BTreeD, d *decode.D) {
|
||||
/* 0 | 4 */ // uint32 btm_magic
|
||||
/* 4 | 4 */ // uint32 btm_version
|
||||
/* 8 | 4 */ // BlockNumber btm_root
|
||||
/* 12 | 4 */ // uint32 btm_level
|
||||
/* 16 | 4 */ // BlockNumber btm_fastroot
|
||||
/* 20 | 4 */ // uint32 btm_fastlevel
|
||||
/* 24 | 4 */ // uint32 btm_last_cleanup_num_delpages
|
||||
/* XXX 4-byte hole */
|
||||
/* 32 | 8 */ // float8 btm_last_cleanup_num_heap_tuples
|
||||
/* 40 | 1 */ // _Bool btm_allequalimage
|
||||
/* XXX 7-byte padding */
|
||||
|
||||
btmMagic := d.FieldU32("btm_magic")
|
||||
d.FieldU32("btm_version")
|
||||
d.FieldU32("btm_root")
|
||||
d.FieldU32("btm_level")
|
||||
d.FieldU32("btm_fastroot")
|
||||
d.FieldU32("btm_fastlevel")
|
||||
d.FieldU32("btm_last_cleanup_num_delpages")
|
||||
d.FieldU32("hole0")
|
||||
d.FieldF64("btm_last_cleanup_num_heap_tuples")
|
||||
d.FieldU8("btm_allequalimage")
|
||||
d.FieldU56("padding0")
|
||||
|
||||
if btmMagic != BTREE_MAGIC {
|
||||
d.Fatalf("invalid btmMagic = %X, must be %X\n", btmMagic, BTREE_MAGIC)
|
||||
}
|
||||
}
|
37
format/postgres/pg_btree.go
Normal file
37
format/postgres/pg_btree.go
Normal file
@ -0,0 +1,37 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"github.com/wader/fq/format"
|
||||
"github.com/wader/fq/format/postgres/flavours/postgres14"
|
||||
"github.com/wader/fq/pkg/decode"
|
||||
"github.com/wader/fq/pkg/interp"
|
||||
)
|
||||
|
||||
func init() {
|
||||
interp.RegisterFormat(decode.Format{
|
||||
Name: format.PG_BTREE,
|
||||
Description: "PostgreSQL btree index file",
|
||||
DecodeFn: decodePgBTree,
|
||||
DecodeInArg: format.PostgresIn{
|
||||
Flavour: "default",
|
||||
},
|
||||
RootArray: true,
|
||||
RootName: "pages",
|
||||
})
|
||||
}
|
||||
|
||||
func decodePgBTree(d *decode.D, in any) any {
|
||||
d.Endian = decode.LittleEndian
|
||||
|
||||
pgIn, ok := in.(format.PostgresIn)
|
||||
if !ok {
|
||||
d.Fatalf("DecodeInArg must be PostgresIn!\n")
|
||||
}
|
||||
|
||||
switch pgIn.Flavour {
|
||||
case PG_FLAVOUR_POSTGRES14, PG_FLAVOUR_POSTGRES:
|
||||
return postgres14.DecodePgBTree(d)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user