mirror of https://github.com/etcd-io/bbolt.git
add AllocSize, minor grow() refactor
This commit moves `overAllocation` to a configurable `DB.AllocSize` field and performs minor cosmetic clean up.pull/34/head
parent
694a82a959
commit
a122e1c02b
24
db.go
24
db.go
|
@ -33,6 +33,7 @@ const IgnoreNoSync = runtime.GOOS == "openbsd"
|
||||||
const (
|
const (
|
||||||
DefaultMaxBatchSize int = 1000
|
DefaultMaxBatchSize int = 1000
|
||||||
DefaultMaxBatchDelay = 10 * time.Millisecond
|
DefaultMaxBatchDelay = 10 * time.Millisecond
|
||||||
|
DefaultAllocSize = 16 * 1024 * 1024
|
||||||
)
|
)
|
||||||
|
|
||||||
// DB represents a collection of buckets persisted to a file on disk.
|
// DB represents a collection of buckets persisted to a file on disk.
|
||||||
|
@ -85,6 +86,11 @@ type DB struct {
|
||||||
// Do not change concurrently with calls to Batch.
|
// Do not change concurrently with calls to Batch.
|
||||||
MaxBatchDelay time.Duration
|
MaxBatchDelay time.Duration
|
||||||
|
|
||||||
|
// AllocSize is the amount of space allocated when the database
|
||||||
|
// needs to create new pages. This is done to amortize the cost
|
||||||
|
// of truncate() and fsync() when growing the data file.
|
||||||
|
AllocSize int
|
||||||
|
|
||||||
path string
|
path string
|
||||||
file *os.File
|
file *os.File
|
||||||
dataref []byte // mmap'ed readonly, write throws SEGV
|
dataref []byte // mmap'ed readonly, write throws SEGV
|
||||||
|
@ -148,6 +154,7 @@ func Open(path string, mode os.FileMode, options *Options) (*DB, error) {
|
||||||
// Set default values for later DB operations.
|
// Set default values for later DB operations.
|
||||||
db.MaxBatchSize = DefaultMaxBatchSize
|
db.MaxBatchSize = DefaultMaxBatchSize
|
||||||
db.MaxBatchDelay = DefaultMaxBatchDelay
|
db.MaxBatchDelay = DefaultMaxBatchDelay
|
||||||
|
db.AllocSize = DefaultAllocSize
|
||||||
|
|
||||||
flag := os.O_RDWR
|
flag := os.O_RDWR
|
||||||
if options.ReadOnly {
|
if options.ReadOnly {
|
||||||
|
@ -799,20 +806,19 @@ func (db *DB) allocate(count int) (*page, error) {
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// growSize grows the size of the database to the given sz.
|
// grow grows the size of the database to the given sz.
|
||||||
func (db *DB) growSize(sz int) error {
|
func (db *DB) grow(sz int) error {
|
||||||
|
// Ignore if the new size is less than available file size.
|
||||||
if sz <= db.filesz {
|
if sz <= db.filesz {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// over allocate 16MB to avoid calling Truncate aggressively
|
// If the data is smaller than the alloc size then only allocate what's needed.
|
||||||
// for efficiency
|
// Once it goes over the allocation size then allocate in chunks.
|
||||||
overAllocation := 16 * 1024 * 1024
|
if db.datasz < db.AllocSize {
|
||||||
sz = sz + overAllocation
|
|
||||||
|
|
||||||
// do not over allocate
|
|
||||||
if sz > db.datasz {
|
|
||||||
sz = db.datasz
|
sz = db.datasz
|
||||||
|
} else {
|
||||||
|
sz += db.AllocSize
|
||||||
}
|
}
|
||||||
|
|
||||||
// Truncate and fsync to ensure file size metadata is flushed.
|
// Truncate and fsync to ensure file size metadata is flushed.
|
||||||
|
|
6
tx.go
6
tx.go
|
@ -184,8 +184,12 @@ func (tx *Tx) Commit() error {
|
||||||
}
|
}
|
||||||
tx.meta.freelist = p.id
|
tx.meta.freelist = p.id
|
||||||
|
|
||||||
|
// If the high water mark has moved up then attempt to grow the database.
|
||||||
if tx.meta.pgid > opgid {
|
if tx.meta.pgid > opgid {
|
||||||
tx.db.growSize(int(tx.meta.pgid+1) * tx.db.pageSize)
|
if err := tx.db.grow(int(tx.meta.pgid+1) * tx.db.pageSize); err != nil {
|
||||||
|
tx.rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write dirty pages to disk.
|
// Write dirty pages to disk.
|
||||||
|
|
Loading…
Reference in New Issue