mirror of
https://github.com/etcd-io/bbolt.git
synced 2025-05-31 11:42:30 +00:00
encapsulate the logic of checking the page type
Signed-off-by: Benjamin Wang <wachao@vmware.com>
This commit is contained in:
parent
17b18580c7
commit
a3a9877de6
@ -410,7 +410,7 @@ func (b *Bucket) Stats() BucketStats {
|
|||||||
s.InlineBucketN += 1
|
s.InlineBucketN += 1
|
||||||
}
|
}
|
||||||
b.forEachPage(func(p *common.Page, depth int, pgstack []common.Pgid) {
|
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())
|
s.KeyN += int(p.Count())
|
||||||
|
|
||||||
// used totals the used bytes for the page
|
// 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++
|
s.BranchPageN++
|
||||||
lastElement := p.BranchPageElement(p.Count() - 1)
|
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.
|
// Recursively loop over children.
|
||||||
if p != nil {
|
if p != nil {
|
||||||
if (p.Flags() & common.BranchPageFlag) != 0 {
|
if p.IsBranchPage() {
|
||||||
for i := 0; i < int(p.Count()); i++ {
|
for i := 0; i < int(p.Count()); i++ {
|
||||||
elem := p.BranchPageElement(uint16(i))
|
elem := p.BranchPageElement(uint16(i))
|
||||||
b._forEachPageNode(elem.Pgid(), depth+1, fn)
|
b._forEachPageNode(elem.Pgid(), depth+1, fn)
|
||||||
|
@ -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.
|
// 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) {
|
func (c *Cursor) search(key []byte, pgId common.Pgid) {
|
||||||
p, n := c.bucket.pageNode(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()))
|
panic(fmt.Sprintf("invalid page type: %d: %x", p.Id(), p.Flags()))
|
||||||
}
|
}
|
||||||
e := elemRef{page: p, node: n}
|
e := elemRef{page: p, node: n}
|
||||||
@ -410,7 +410,7 @@ func (r *elemRef) isLeaf() bool {
|
|||||||
if r.node != nil {
|
if r.node != nil {
|
||||||
return r.node.isLeaf
|
return r.node.isLeaf
|
||||||
}
|
}
|
||||||
return (r.page.Flags() & common.LeafPageFlag) != 0
|
return r.page.IsLeafPage()
|
||||||
}
|
}
|
||||||
|
|
||||||
// count returns the number of inodes or page elements.
|
// count returns the number of inodes or page elements.
|
||||||
|
@ -166,7 +166,7 @@ func (f *freelist) free(txid common.Txid, p *common.Page) {
|
|||||||
allocTxid, ok := f.allocs[p.Id()]
|
allocTxid, ok := f.allocs[p.Id()]
|
||||||
if ok {
|
if ok {
|
||||||
delete(f.allocs, p.Id())
|
delete(f.allocs, p.Id())
|
||||||
} else if (p.Flags() & common.FreelistPageFlag) != 0 {
|
} else if p.IsFreelistPage() {
|
||||||
// Freelist is always allocated by prior tx.
|
// Freelist is always allocated by prior tx.
|
||||||
allocTxid = txid - 1
|
allocTxid = txid - 1
|
||||||
}
|
}
|
||||||
@ -265,7 +265,7 @@ func (f *freelist) freed(pgId common.Pgid) bool {
|
|||||||
|
|
||||||
// read initializes the freelist from a freelist page.
|
// read initializes the freelist from a freelist page.
|
||||||
func (f *freelist) read(p *common.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()))
|
panic(fmt.Sprintf("invalid freelist page: %d, page type is %s", p.Id(), p.Typ()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
// Typ returns a human-readable page type string used for debugging.
|
||||||
func (p *Page) Typ() string {
|
func (p *Page) Typ() string {
|
||||||
if (p.flags & BranchPageFlag) != 0 {
|
if p.IsBranchPage() {
|
||||||
return "branch"
|
return "branch"
|
||||||
} else if (p.flags & LeafPageFlag) != 0 {
|
} else if p.IsLeafPage() {
|
||||||
return "leaf"
|
return "leaf"
|
||||||
} else if (p.flags & MetaPageFlag) != 0 {
|
} else if p.IsMetaPage() {
|
||||||
return "meta"
|
return "meta"
|
||||||
} else if (p.flags & FreelistPageFlag) != 0 {
|
} else if p.IsFreelistPage() {
|
||||||
return "freelist"
|
return "freelist"
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("unknown<%02x>", p.flags)
|
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.
|
// Meta returns a pointer to the metadata section of the page.
|
||||||
func (p *Page) Meta() *Meta {
|
func (p *Page) Meta() *Meta {
|
||||||
return (*Meta)(UnsafeAdd(unsafe.Pointer(p), unsafe.Sizeof(*p)))
|
return (*Meta)(UnsafeAdd(unsafe.Pointer(p), unsafe.Sizeof(*p)))
|
||||||
|
2
node.go
2
node.go
@ -162,7 +162,7 @@ func (n *node) del(key []byte) {
|
|||||||
// read initializes the node from a page.
|
// read initializes the node from a page.
|
||||||
func (n *node) read(p *common.Page) {
|
func (n *node) read(p *common.Page) {
|
||||||
n.pgid = p.Id()
|
n.pgid = p.Id()
|
||||||
n.isLeaf = (p.Flags() & common.LeafPageFlag) != 0
|
n.isLeaf = p.IsLeafPage()
|
||||||
n.inodes = make(common.Inodes, int(p.Count()))
|
n.inodes = make(common.Inodes, int(p.Count()))
|
||||||
|
|
||||||
for i := 0; i < int(p.Count()); i++ {
|
for i := 0; i < int(p.Count()); i++ {
|
||||||
|
2
tx.go
2
tx.go
@ -548,7 +548,7 @@ func (tx *Tx) forEachPageInternal(pgidstack []common.Pgid, fn func(*common.Page,
|
|||||||
fn(p, len(pgidstack)-1, pgidstack)
|
fn(p, len(pgidstack)-1, pgidstack)
|
||||||
|
|
||||||
// Recursively loop over children.
|
// Recursively loop over children.
|
||||||
if (p.Flags() & common.BranchPageFlag) != 0 {
|
if p.IsBranchPage() {
|
||||||
for i := 0; i < int(p.Count()); i++ {
|
for i := 0; i < int(p.Count()); i++ {
|
||||||
elem := p.BranchPageElement(uint16(i))
|
elem := p.BranchPageElement(uint16(i))
|
||||||
tx.forEachPageInternal(append(pgidstack, elem.Pgid()), fn)
|
tx.forEachPageInternal(append(pgidstack, elem.Pgid()), fn)
|
||||||
|
@ -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.
|
// We should only encounter un-freed leaf and branch pages.
|
||||||
if freed[p.Id()] {
|
if freed[p.Id()] {
|
||||||
ch <- fmt.Errorf("page %d: reachable freed", int(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)
|
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)
|
p := tx.page(pgId)
|
||||||
pagesStack = append(pagesStack, pgId)
|
pagesStack = append(pagesStack, pgId)
|
||||||
switch {
|
switch {
|
||||||
case p.Flags()&common.BranchPageFlag != 0:
|
case p.IsBranchPage():
|
||||||
// For branch page we navigate ranges of all subpages.
|
// For branch page we navigate ranges of all subpages.
|
||||||
runningMin := minKeyClosed
|
runningMin := minKeyClosed
|
||||||
for i := range p.BranchPageElements() {
|
for i := range p.BranchPageElements() {
|
||||||
@ -150,7 +150,7 @@ func (tx *Tx) recursivelyCheckPagesInternal(
|
|||||||
runningMin = maxKeyInSubtree
|
runningMin = maxKeyInSubtree
|
||||||
}
|
}
|
||||||
return maxKeyInSubtree
|
return maxKeyInSubtree
|
||||||
case p.Flags()&common.LeafPageFlag != 0:
|
case p.IsLeafPage():
|
||||||
runningMin := minKeyClosed
|
runningMin := minKeyClosed
|
||||||
for i := range p.LeafPageElements() {
|
for i := range p.LeafPageElements() {
|
||||||
elem := p.LeafPageElement(uint16(i))
|
elem := p.LeafPageElement(uint16(i))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user