encapsulate the logic of checking the page type

Signed-off-by: Benjamin Wang <wachao@vmware.com>
pull/415/head
Benjamin Wang 2023-03-08 10:46:18 +08:00
parent 17b18580c7
commit a3a9877de6
7 changed files with 32 additions and 16 deletions

View File

@ -410,7 +410,7 @@ func (b *Bucket) Stats() BucketStats {
s.InlineBucketN += 1
}
b.forEachPage(func(p *common.Page, depth int, pgstack []common.Pgid) {
if (p.Flags() & common.LeafPageFlag) != 0 {
if p.IsLeafPage() {
s.KeyN += int(p.Count())
// used totals the used bytes for the page
@ -450,7 +450,7 @@ func (b *Bucket) Stats() BucketStats {
}
}
}
} else if (p.Flags() & common.BranchPageFlag) != 0 {
} else if p.IsBranchPage() {
s.BranchPageN++
lastElement := p.BranchPageElement(p.Count() - 1)
@ -514,7 +514,7 @@ func (b *Bucket) _forEachPageNode(pgId common.Pgid, depth int, fn func(*common.P
// Recursively loop over children.
if p != nil {
if (p.Flags() & common.BranchPageFlag) != 0 {
if p.IsBranchPage() {
for i := 0; i < int(p.Count()); i++ {
elem := p.BranchPageElement(uint16(i))
b._forEachPageNode(elem.Pgid(), depth+1, fn)

View File

@ -272,7 +272,7 @@ func (c *Cursor) prev() (key []byte, value []byte, flags uint32) {
// search recursively performs a binary search against a given page/node until it finds a given key.
func (c *Cursor) search(key []byte, pgId common.Pgid) {
p, n := c.bucket.pageNode(pgId)
if p != nil && (p.Flags()&(common.BranchPageFlag|common.LeafPageFlag)) == 0 {
if p != nil && !p.IsBranchPage() && !p.IsLeafPage() {
panic(fmt.Sprintf("invalid page type: %d: %x", p.Id(), p.Flags()))
}
e := elemRef{page: p, node: n}
@ -410,7 +410,7 @@ func (r *elemRef) isLeaf() bool {
if r.node != nil {
return r.node.isLeaf
}
return (r.page.Flags() & common.LeafPageFlag) != 0
return r.page.IsLeafPage()
}
// count returns the number of inodes or page elements.

View File

@ -166,7 +166,7 @@ func (f *freelist) free(txid common.Txid, p *common.Page) {
allocTxid, ok := f.allocs[p.Id()]
if ok {
delete(f.allocs, p.Id())
} else if (p.Flags() & common.FreelistPageFlag) != 0 {
} else if p.IsFreelistPage() {
// Freelist is always allocated by prior tx.
allocTxid = txid - 1
}
@ -265,7 +265,7 @@ func (f *freelist) freed(pgId common.Pgid) bool {
// read initializes the freelist from a freelist page.
func (f *freelist) read(p *common.Page) {
if (p.Flags() & common.FreelistPageFlag) == 0 {
if !p.IsFreelistPage() {
panic(fmt.Sprintf("invalid freelist page: %d, page type is %s", p.Id(), p.Typ()))
}

View File

@ -45,18 +45,34 @@ func NewPage(id Pgid, flags, count uint16, overflow uint32) *Page {
// Typ returns a human-readable page type string used for debugging.
func (p *Page) Typ() string {
if (p.flags & BranchPageFlag) != 0 {
if p.IsBranchPage() {
return "branch"
} else if (p.flags & LeafPageFlag) != 0 {
} else if p.IsLeafPage() {
return "leaf"
} else if (p.flags & MetaPageFlag) != 0 {
} else if p.IsMetaPage() {
return "meta"
} else if (p.flags & FreelistPageFlag) != 0 {
} else if p.IsFreelistPage() {
return "freelist"
}
return fmt.Sprintf("unknown<%02x>", p.flags)
}
func (p *Page) IsBranchPage() bool {
return p.flags&BranchPageFlag != 0
}
func (p *Page) IsLeafPage() bool {
return p.flags&LeafPageFlag != 0
}
func (p *Page) IsMetaPage() bool {
return p.flags&MetaPageFlag != 0
}
func (p *Page) IsFreelistPage() bool {
return p.flags&FreelistPageFlag != 0
}
// Meta returns a pointer to the metadata section of the page.
func (p *Page) Meta() *Meta {
return (*Meta)(UnsafeAdd(unsafe.Pointer(p), unsafe.Sizeof(*p)))

View File

@ -162,7 +162,7 @@ func (n *node) del(key []byte) {
// read initializes the node from a page.
func (n *node) read(p *common.Page) {
n.pgid = p.Id()
n.isLeaf = (p.Flags() & common.LeafPageFlag) != 0
n.isLeaf = p.IsLeafPage()
n.inodes = make(common.Inodes, int(p.Count()))
for i := 0; i < int(p.Count()); i++ {

2
tx.go
View File

@ -548,7 +548,7 @@ func (tx *Tx) forEachPageInternal(pgidstack []common.Pgid, fn func(*common.Page,
fn(p, len(pgidstack)-1, pgidstack)
// Recursively loop over children.
if (p.Flags() & common.BranchPageFlag) != 0 {
if p.IsBranchPage() {
for i := 0; i < int(p.Count()); i++ {
elem := p.BranchPageElement(uint16(i))
tx.forEachPageInternal(append(pgidstack, elem.Pgid()), fn)

View File

@ -99,7 +99,7 @@ func (tx *Tx) checkBucket(b *Bucket, reachable map[common.Pgid]*common.Page, fre
// We should only encounter un-freed leaf and branch pages.
if freed[p.Id()] {
ch <- fmt.Errorf("page %d: reachable freed", int(p.Id()))
} else if (p.Flags()&common.BranchPageFlag) == 0 && (p.Flags()&common.LeafPageFlag) == 0 {
} else if !p.IsBranchPage() && !p.IsLeafPage() {
ch <- fmt.Errorf("page %d: invalid type: %s (stack: %v)", int(p.Id()), p.Typ(), stack)
}
})
@ -135,7 +135,7 @@ func (tx *Tx) recursivelyCheckPagesInternal(
p := tx.page(pgId)
pagesStack = append(pagesStack, pgId)
switch {
case p.Flags()&common.BranchPageFlag != 0:
case p.IsBranchPage():
// For branch page we navigate ranges of all subpages.
runningMin := minKeyClosed
for i := range p.BranchPageElements() {
@ -150,7 +150,7 @@ func (tx *Tx) recursivelyCheckPagesInternal(
runningMin = maxKeyInSubtree
}
return maxKeyInSubtree
case p.Flags()&common.LeafPageFlag != 0:
case p.IsLeafPage():
runningMin := minKeyClosed
for i := range p.LeafPageElements() {
elem := p.LeafPageElement(uint16(i))