diff options
author | Xiang Li <xiangli.cs@gmail.com> | 2015-11-04 15:12:18 -0800 |
---|---|---|
committer | Xiang Li <xiangli.cs@gmail.com> | 2015-11-06 09:39:17 -0800 |
commit | e67705ed6348675b7bae405ebeb37bb69b53a96d (patch) | |
tree | 896094dfe1466aa5a017424ee19a434dbf9f35cb /db.go | |
parent | Merge pull request #428 from lukechampine/patch-1 (diff) | |
download | dedo-e67705ed6348675b7bae405ebeb37bb69b53a96d.tar.gz dedo-e67705ed6348675b7bae405ebeb37bb69b53a96d.tar.xz |
do not grow dbsize agressively
Only grow the database size when the high watermark increases.
We also grows the database size a little bit aggressively to
save a few ftruncates.
I have tested this on various environments. The performance impact
is ignorable with 16MB over allocation. Without over allocation,
the performance might decrease 100% when each Tx.Commit needs a new
page on a very slow disk (seek time dominates the total write).
Diffstat (limited to 'db.go')
-rw-r--r-- | db.go | 32 |
1 files changed, 32 insertions, 0 deletions
@@ -84,6 +84,7 @@ type DB struct { dataref []byte // mmap'ed readonly, write throws SEGV data *[maxMapSize]byte datasz int + filesz int // current on disk file size meta0 *meta meta1 *meta pageSize int @@ -655,6 +656,37 @@ func (db *DB) allocate(count int) (*page, error) { return p, nil } +// growSize grows the size of the database to the given sz. +func (db *DB) growSize(sz int) error { + if sz <= db.filesz { + return nil + } + + // over allocate 16MB to avoid calling Truncate aggressively + // for efficiency + overAllocation := 16 * 1024 * 1024 + sz = sz + overAllocation + + // do not over allocate + if sz > db.datasz { + sz = db.datasz + } + + // Truncate and fsync to ensure file size metadata is flushed. + // https://github.com/boltdb/bolt/issues/284 + if !db.NoGrowSync && !db.readOnly { + if err := db.file.Truncate(int64(sz)); err != nil { + return fmt.Errorf("file resize error: %s", err) + } + if err := db.file.Sync(); err != nil { + return fmt.Errorf("file sync error: %s", err) + } + } + + db.filesz = sz + return nil +} + func (db *DB) IsReadOnly() bool { return db.readOnly } |