Skip to content

Commit

Permalink
add freelistType as an option
Browse files Browse the repository at this point in the history
  • Loading branch information
WIZARD-CXY committed Jan 17, 2019
1 parent a328824 commit 14455c5
Show file tree
Hide file tree
Showing 6 changed files with 491 additions and 174 deletions.
8 changes: 8 additions & 0 deletions Makefile
Expand Up @@ -6,6 +6,8 @@ default: build

race:
@go test -v -race -test.run="TestSimulate_(100op|1000op)"
@echo "array freelist test"
@ARRAY_FREELIST=y go test -v -race -test.run="TestSimulate_(100op|1000op)"

fmt:
!(gofmt -l -s -d $(shell find . -name \*.go) | grep '[a-z]')
Expand All @@ -27,4 +29,10 @@ test:
# Note: gets "program not an importable package" in out of path builds
go test -v ./cmd/bbolt

@echo "array freelist test"

@ARRAY_FREELIST=y go test -timeout 20m -v -coverprofile cover.out -covermode atomic
# Note: gets "program not an importable package" in out of path builds
@ARRAY_FREELIST=y go test -v ./cmd/bbolt

.PHONY: race fmt errcheck test gosimple unused
8 changes: 6 additions & 2 deletions allocate_test.go
Expand Up @@ -6,8 +6,12 @@ import (

func TestTx_allocatePageStats(t *testing.T) {
f := newFreelist()
ids := []pgid{2, 3}
f.init(ids)
if !f.IsFreelistTypeArray {
ids := []pgid{2, 3}
f.init(ids)
} else {
f.ids = []pgid{2, 3}
}

tx := &Tx{
db: &DB{
Expand Down
20 changes: 20 additions & 0 deletions db.go
Expand Up @@ -70,6 +70,13 @@ type DB struct {
// re-sync during recovery.
NoFreelistSync bool

// IsFreelistTypeArray sets the backend freelist type to array which is simple but endures
// dramatic performance degradation if database is large and framentation in freelist is common.
// The alternative one is using segregated freelist, it is faster in almost all circumstances
// but it doesn't guarantee that it offers the smallest page id available. In normal case it is safe.
// if you depend on this(it offers the smallest page id available), you may set this to true.
IsFreelistTypeArray bool

// When true, skips the truncate call when growing the database.
// Setting this to true is only safe on non-ext3/ext4 systems.
// Skipping truncation avoids preallocation of hard drive space and
Expand Down Expand Up @@ -169,6 +176,7 @@ func Open(path string, mode os.FileMode, options *Options) (*DB, error) {
db.NoGrowSync = options.NoGrowSync
db.MmapFlags = options.MmapFlags
db.NoFreelistSync = options.NoFreelistSync
db.IsFreelistTypeArray = options.IsFreelistTypeArray

// Set default values for later DB operations.
db.MaxBatchSize = DefaultMaxBatchSize
Expand Down Expand Up @@ -283,6 +291,11 @@ func Open(path string, mode os.FileMode, options *Options) (*DB, error) {
// concurrent accesses being made to the freelist.
func (db *DB) loadFreelist() {
db.freelistLoad.Do(func() {
if db.IsFreelistTypeArray {
isFreelistTypeArray = true
} else {
isFreelistTypeArray = false
}
db.freelist = newFreelist()
if !db.hasSyncedFreelist() {
// Reconstruct free list by scanning the DB.
Expand Down Expand Up @@ -1005,6 +1018,13 @@ type Options struct {
// under normal operation, but requires a full database re-sync during recovery.
NoFreelistSync bool

// IsFreelistTypeArray sets the backend freelist type to array which is simple but endures
// dramatic performance degradation if database is large and framentation in freelist is common.
// The alternative one is using segregated freelist, it is faster in almost all circumstances
// but it doesn't guarantee that it offers the smallest page id available. In normal case it is safe.
// if you depend on this(it offers the smallest page id available), you may set this to true.
IsFreelistTypeArray bool

// Open database in read-only mode. Uses flock(..., LOCK_SH |LOCK_NB) to
// grab a shared lock (UNIX).
ReadOnly bool
Expand Down

0 comments on commit 14455c5

Please sign in to comment.