// Copyright 2022 Molecula Corp. (DBA FeatureBase). // SPDX-License-Identifier: Apache-2.0 package rbf import ( "fmt" "io" ) func dotCell(b []byte, parent string, writer io.Writer) { pgno := readPageNo(b) if pgno == Magic32() { fmt.Fprintf(writer, "==META\n") return } flags := readFlags(b) cellN := readCellN(b) switch { case flags&PageTypeLeaf != 0: fmt.Fprintf(writer, "cell%d [ shape=none label=<\n", pgno) fmt.Fprintf(writer, "\n", pgno) links := make([]string, 0) for i := 0; i < cellN; i++ { cell := readLeafCell(b, i) switch cell.Type { case ContainerTypeArray: //fmt.Fprintf(os.Stderr, "[%d]: key=%d type=array n=%d elems=%v\n", i, cell.Key, cell.N, toArray16(cell.Data)) fmt.Fprintf(writer, "\n", i, cell.Key, cell.BitN) case ContainerTypeRLE: fmt.Fprintf(writer, "\n", i, cell.Key, cell.BitN) case ContainerTypeBitmapPtr: bpn := toPgno(cell.Data) fmt.Fprintf(writer, "\n", bpn, i, cell.Key, cell.BitN) links = append(links, fmt.Sprintf("bitmap%d[label=\"bitmap (%d)\"]\n cell%d:%d -> bitmap%d\n", bpn, bpn, pgno, i, bpn)) default: fmt.Fprintf(writer, "\n", i, cell.Key, cell.Type, cell.BitN) } } fmt.Fprintf(writer, "
CELL (%d)
[%d]: key=%d type=array n=%d
[%d]: key=%d type=rle n=%d
[%d]: key=%d type=bitmap n=%d
[%d]: key=%d type=unknown<%d> n=%d
>]\n") fmt.Fprintf(writer, "%s -> cell%d\n", parent, pgno) for _, link := range links { fmt.Fprintf(writer, "%s", link) } default: //should not happen fmt.Fprintf(writer, "==!PAGE %d flags=%d\n", pgno, flags) } } // Dumpdot recursively writes the tree representation starting from a given page to STDERR. func Dumpdot(tx *Tx, pgno uint32, parent string, writer io.Writer) { page, _, err := tx.readPage(pgno) if err != nil { panic(err) } if IsMetaPage(page) { //fmt.Fprintf(writer, "META(%d)\n", pgno) //fmt.Fprintf(writer, "└── \n") //treedump(tx, readMetaFreelistPageNo(page), indent+" ") visitor := func(pgno uint32, records []*RootRecord) { rr := fmt.Sprintf("rr%d", pgno) fmt.Fprintf(writer, "%s[label=\"ROOT RECORD(%d): n=%d\"]\n", rr, pgno, len(records)) for _, record := range records { root := fmt.Sprintf("root%d", record.Pgno) fmt.Fprintf(writer, "%s[label=\"ROOT(%d)| %s\"]\n%s->%s\n", root, record.Pgno, record.Name, rr, root) p := fmt.Sprintf("root%d", record.Pgno) Dumpdot(tx, record.Pgno, p, writer) } } Walk(tx, readMetaRootRecordPageNo(page), visitor) return } // Handle switch typ := readFlags(page); typ { case PageTypeBranch: p := fmt.Sprintf("branch%d", pgno) fmt.Fprintf(writer, "%s[label=\"BRANCH(%d)| n=%d\"]\n %s->%s\n", p, pgno, readCellN(page), parent, p) for i, n := 0, readCellN(page); i < n; i++ { cell := readBranchCell(page, i) if cell.Flags&uint32(ContainerTypeBitmap) == 0 { // leaf/branch child page Dumpdot(tx, cell.ChildPgno, p, writer) } else { b := fmt.Sprintf("bm%d", cell.ChildPgno) fmt.Fprintf(writer, "%s[label=\"BITMAP(%d) key=%d \"]\n %s -> %s\n", b, cell.ChildPgno, cell.LeftKey, p, b) } } case PageTypeLeaf: p := fmt.Sprintf("leaf%d", pgno) fmt.Fprintf(writer, "%s[label=\"LEAF(%d)| n=%d\"]\n%s->%s\n", p, pgno, readCellN(page), parent, p) dotCell(page, p, writer) } }