Record the amount of free pages instead of hashmapFreeCount calculation

Signed-off-by: xing0821 <54933318+xing0821@users.noreply.github.com>
This commit is contained in:
xinglong 2021-06-22 14:09:22 +08:00 committed by xing0821
parent 233156a53a
commit dfa2d79a8e
3 changed files with 19 additions and 1 deletions

9
db.go
View File

@ -15,6 +15,9 @@ import (
"go.etcd.io/bbolt/internal/common"
)
// When enabled, the database will perform assert function to check the slow-path code
var assertVerify = os.Getenv("BBOLT_VERIFY") == "true"
// The time elapsed between consecutive file locking attempts.
const flockRetryTimeout = 50 * time.Millisecond
@ -1309,3 +1312,9 @@ type Info struct {
Data uintptr
PageSize int
}
func _assertVerify(conditionFunc func() bool, msg string, v ...interface{}) {
if assertVerify && !conditionFunc() {
panic(fmt.Sprintf("assertion failed: "+msg, v...))
}
}

View File

@ -30,6 +30,7 @@ type freelist struct {
freemaps map[uint64]pidSet // key is the size of continuous pages(span), value is a set which contains the starting pgids of same size
forwardMap map[common.Pgid]uint64 // key is start pgid, value is its span size
backwardMap map[common.Pgid]uint64 // key is end pgid, value is its span size
freePagesCount uint64 // count of free pages(hashmap version)
allocate func(txid common.Txid, n int) common.Pgid // the freelist allocate func
free_count func() int // the function which gives you free page number
mergeSpans func(ids common.Pgids) // the mergeSpan func

View File

@ -8,7 +8,11 @@ import (
// hashmapFreeCount returns count of free pages(hashmap version)
func (f *freelist) hashmapFreeCount() int {
// use the forwardMap to get the total count
_assertVerify(func() bool { return int(f.freePagesCount) == f.hashmapFreeCountSlow() }, "freePagesCount is out of sync with free pages map")
return int(f.freePagesCount)
}
func (f *freelist) hashmapFreeCountSlow() int {
count := 0
for _, size := range f.forwardMap {
count += int(size)
@ -142,6 +146,7 @@ func (f *freelist) addSpan(start common.Pgid, size uint64) {
}
f.freemaps[size][start] = struct{}{}
f.freePagesCount += size
}
func (f *freelist) delSpan(start common.Pgid, size uint64) {
@ -151,6 +156,7 @@ func (f *freelist) delSpan(start common.Pgid, size uint64) {
if len(f.freemaps[size]) == 0 {
delete(f.freemaps, size)
}
f.freePagesCount -= size
}
// initial from pgids using when use hashmap version
@ -162,6 +168,8 @@ func (f *freelist) init(pgids []common.Pgid) {
size := uint64(1)
start := pgids[0]
// reset the counter when freelist init
f.freePagesCount = 0
if !sort.SliceIsSorted([]common.Pgid(pgids), func(i, j int) bool { return pgids[i] < pgids[j] }) {
panic("pgids not sorted")