mirror of https://github.com/tidwall/buntdb.git
allow only one shrink at a time.
This commit is contained in:
parent
70dec49583
commit
d6a4f5c635
45
buntdb.go
45
buntdb.go
|
@ -50,6 +50,9 @@ var (
|
||||||
|
|
||||||
// ErrInvalidSyncPolicy is returned for an invalid SyncPolicy value.
|
// ErrInvalidSyncPolicy is returned for an invalid SyncPolicy value.
|
||||||
ErrInvalidSyncPolicy = errors.New("invalid sync policy")
|
ErrInvalidSyncPolicy = errors.New("invalid sync policy")
|
||||||
|
|
||||||
|
// ErrShrinkInProcess is returned when a shrink operation is in-process.
|
||||||
|
ErrShrinkInProcess = errors.New("shrink is in-process")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Iterator allows callers of Ascend* or Descend* to iterate in-order
|
// Iterator allows callers of Ascend* or Descend* to iterate in-order
|
||||||
|
@ -61,18 +64,19 @@ type Iterator func(key, val string) bool
|
||||||
// DB represents a collection of key-value pairs that persist on disk.
|
// DB represents a collection of key-value pairs that persist on disk.
|
||||||
// Transactions are used for all forms of data access to the DB.
|
// Transactions are used for all forms of data access to the DB.
|
||||||
type DB struct {
|
type DB struct {
|
||||||
mu sync.RWMutex // the gatekeeper for all fields
|
mu sync.RWMutex // the gatekeeper for all fields
|
||||||
file *os.File // the underlying file
|
file *os.File // the underlying file
|
||||||
bufw *bufio.Writer // only write to this
|
bufw *bufio.Writer // only write to this
|
||||||
keys *btree.BTree // a tree of all item ordered by key
|
keys *btree.BTree // a tree of all item ordered by key
|
||||||
exps *btree.BTree // a tree of items ordered by expiration
|
exps *btree.BTree // a tree of items ordered by expiration
|
||||||
idxs map[string]*index // the index trees.
|
idxs map[string]*index // the index trees.
|
||||||
exmgr bool // indicates that expires manager is running.
|
exmgr bool // indicates that expires manager is running.
|
||||||
flushes int // a count of the number of disk flushes
|
flushes int // a count of the number of disk flushes
|
||||||
closed bool // set when the database has been closed
|
closed bool // set when the database has been closed
|
||||||
aoflen int // the number of lines in the aof file
|
aoflen int // the number of lines in the aof file
|
||||||
config Config // the database configuration
|
config Config // the database configuration
|
||||||
persist bool // do we write to disk
|
persist bool // do we write to disk
|
||||||
|
shrinking bool // when an aof shrink is in-process.
|
||||||
}
|
}
|
||||||
|
|
||||||
// SyncPolicy represents how often data is synced to disk.
|
// SyncPolicy represents how often data is synced to disk.
|
||||||
|
@ -107,10 +111,12 @@ type Config struct {
|
||||||
// disk may be up to 2x the number of items on disk.
|
// disk may be up to 2x the number of items on disk.
|
||||||
// A zero value will disable auto shrinking.
|
// A zero value will disable auto shrinking.
|
||||||
// A negative value or 1 are invalid.
|
// A negative value or 1 are invalid.
|
||||||
// The default is value is 5.
|
// The default is value is 50, but may change in the future.
|
||||||
AutoShrink int
|
AutoShrink int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const defaultAutoShrinkMultiplier = 50
|
||||||
|
|
||||||
// exctx is a simple b-tree context for ordering by expiration.
|
// exctx is a simple b-tree context for ordering by expiration.
|
||||||
type exctx struct {
|
type exctx struct {
|
||||||
db *DB
|
db *DB
|
||||||
|
@ -125,7 +131,7 @@ func Open(path string) (*DB, error) {
|
||||||
db.idxs = make(map[string]*index)
|
db.idxs = make(map[string]*index)
|
||||||
db.config = Config{
|
db.config = Config{
|
||||||
SyncPolicy: EverySecond,
|
SyncPolicy: EverySecond,
|
||||||
AutoShrink: 5,
|
AutoShrink: defaultAutoShrinkMultiplier,
|
||||||
}
|
}
|
||||||
db.persist = path != ":memory:"
|
db.persist = path != ":memory:"
|
||||||
if db.persist {
|
if db.persist {
|
||||||
|
@ -501,6 +507,17 @@ func (db *DB) Shrink() error {
|
||||||
db.mu.Unlock()
|
db.mu.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if db.shrinking {
|
||||||
|
// The database is already in the process of shrinking.
|
||||||
|
db.mu.Unlock()
|
||||||
|
return ErrShrinkInProcess
|
||||||
|
}
|
||||||
|
db.shrinking = true
|
||||||
|
defer func() {
|
||||||
|
db.mu.Lock()
|
||||||
|
db.shrinking = false
|
||||||
|
db.mu.Unlock()
|
||||||
|
}()
|
||||||
fname := db.file.Name()
|
fname := db.file.Name()
|
||||||
tmpname := fname + ".tmp"
|
tmpname := fname + ".tmp"
|
||||||
// the endpos is used to return to the end of the file when we are
|
// the endpos is used to return to the end of the file when we are
|
||||||
|
|
Loading…
Reference in New Issue