Skip to content

Commit b39d36f

Browse files
authored
Merge pull request #1183 from k8s-infra-cherrypick-robot/cherry-pick-1180-to-release-1.4
[release-1.4] Improve FastCheck performance
2 parents a3ea6e5 + b181c26 commit b39d36f

4 files changed

Lines changed: 46 additions & 11 deletions

File tree

bucket.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,9 @@ func (b *Bucket) node(pgId common.Pgid, parent *node) *node {
884884
// if p isn't nil, then it's an inline bucket.
885885
// The pgId must be 0 in this case.
886886
common.Verify(func() {
887-
common.Assert(pgId == 0, "The page ID (%d) isn't 0 for an inline bucket", pgId)
887+
if pgId != 0 {
888+
panic(fmt.Sprintf("assertion failed: The page ID (%d) isn't 0 for an inline bucket", pgId))
889+
}
888890
})
889891
}
890892

internal/common/bench_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package common_test
2+
3+
import (
4+
"math/rand/v2"
5+
"testing"
6+
7+
"go.etcd.io/bbolt/internal/common"
8+
)
9+
10+
func BenchmarkFastCheck(b *testing.B) {
11+
var (
12+
id = common.Pgid(rand.Uint64()) // Important, constant ID optimizes some code out.
13+
flags = uint16(common.BranchPageFlag) << rand.IntN(3) // From 0x01 to 0x04.
14+
p = common.NewPage(id, flags, 0, 0)
15+
)
16+
for b.Loop() {
17+
p.FastCheck(id)
18+
}
19+
}

internal/common/page.go

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,27 @@ func (p *Page) IsFreelistPage() bool {
7474
return p.flags == FreelistPageFlag
7575
}
7676

77+
// IsValidPage checks Page flags correctness, only a single proper flag can be used.
78+
func (p *Page) IsValidPage() bool {
79+
return p.IsBranchPage() ||
80+
p.IsLeafPage() ||
81+
p.IsMetaPage() ||
82+
p.IsFreelistPage()
83+
}
84+
7785
// Meta returns a pointer to the metadata section of the page.
7886
func (p *Page) Meta() *Meta {
7987
return (*Meta)(UnsafeAdd(unsafe.Pointer(p), unsafe.Sizeof(*p)))
8088
}
8189

8290
func (p *Page) FastCheck(id Pgid) {
83-
Assert(p.id == id, "Page expected to be: %v, but self identifies as %v", id, p.id)
91+
if p.id != id {
92+
panic(fmt.Sprintf("assertion failed: Page expected to be: %v, but self identifies as %v", id, p.id))
93+
}
8494
// Only one flag of page-type can be set.
85-
Assert(p.IsBranchPage() ||
86-
p.IsLeafPage() ||
87-
p.IsMetaPage() ||
88-
p.IsFreelistPage(),
89-
"page %v: has unexpected type/flags: %x", p.id, p.flags)
95+
if !p.IsValidPage() {
96+
panic(fmt.Sprintf("assertion failed: page %v: has unexpected type/flags: %x", p.id, p.flags))
97+
}
9098
}
9199

92100
// LeafPageElement retrieves the leaf node by index
@@ -122,7 +130,9 @@ func (p *Page) BranchPageElements() []branchPageElement {
122130
}
123131

124132
func (p *Page) FreelistPageCount() (int, int) {
125-
Assert(p.IsFreelistPage(), fmt.Sprintf("can't get freelist page count from a non-freelist page: %2x", p.flags))
133+
if !p.IsFreelistPage() {
134+
panic(fmt.Sprintf("assertion failed: can't get freelist page count from a non-freelist page: %2x", p.flags))
135+
}
126136

127137
// If the page.count is at the max uint16 value (64k) then it's considered
128138
// an overflow and the size of the freelist is stored as the first element.
@@ -140,7 +150,9 @@ func (p *Page) FreelistPageCount() (int, int) {
140150
}
141151

142152
func (p *Page) FreelistPageIds() []Pgid {
143-
Assert(p.IsFreelistPage(), fmt.Sprintf("can't get freelist page IDs from a non-freelist page: %2x", p.flags))
153+
if !p.IsFreelistPage() {
154+
panic(fmt.Sprintf("assertion failed: can't get freelist page IDs from a non-freelist page: %2x", p.flags))
155+
}
144156

145157
idx, count := p.FreelistPageCount()
146158

internal/freelist/hashmap.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,10 @@ func (f *hashMap) Allocate(txid common.Txid, n int) common.Pgid {
108108
func (f *hashMap) FreeCount() int {
109109
common.Verify(func() {
110110
expectedFreePageCount := f.hashmapFreeCountSlow()
111-
common.Assert(int(f.freePagesCount) == expectedFreePageCount,
112-
"freePagesCount (%d) is out of sync with free pages map (%d)", f.freePagesCount, expectedFreePageCount)
111+
if int(f.freePagesCount) != expectedFreePageCount {
112+
panic(fmt.Sprintf("assertion failed: freePagesCount (%d) is out of sync with free pages map (%d)",
113+
f.freePagesCount, expectedFreePageCount))
114+
}
113115
})
114116
return int(f.freePagesCount)
115117
}

0 commit comments

Comments
 (0)