aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Johnson <benbjohnson@yahoo.com>2014-07-23 09:04:36 -0600
committerBen Johnson <benbjohnson@yahoo.com>2014-07-23 09:04:36 -0600
commitfd3c1d44b01d5a3b21bd19413972428ea2f14508 (patch)
tree5b3553be671dd6a91c31deea0dfc4cdee03b25c9
parentMerge pull request #226 from benbjohnson/optimize-large-append (diff)
downloaddedo-fd3c1d44b01d5a3b21bd19413972428ea2f14508.tar.gz
dedo-fd3c1d44b01d5a3b21bd19413972428ea2f14508.tar.xz
Fix double spill.
This fixes an issue where split nodes can be double spilled. This is typically not noticable but it can have large effects when bulk inserting as double spilled nodes will get added to the freelist which will grow quickly.
-rw-r--r--node.go6
1 files changed, 5 insertions, 1 deletions
diff --git a/node.go b/node.go
index 242e423..cda5201 100644
--- a/node.go
+++ b/node.go
@@ -9,9 +9,9 @@ import (
// node represents an in-memory, deserialized page.
type node struct {
bucket *Bucket
- dirty bool
isLeaf bool
unbalanced bool
+ spilled bool
key []byte
pgid pgid
parent *node
@@ -313,6 +313,9 @@ func (n *node) splitIndex(threshold int) (index, sz int) {
// Returns an error if dirty pages cannot be allocated.
func (n *node) spill() error {
var tx = n.bucket.tx
+ if n.spilled {
+ return nil
+ }
// Spill child nodes first. Child nodes can materialize sibling nodes in
// the case of split-merge so we cannot use a range loop. We have to check
@@ -346,6 +349,7 @@ func (n *node) spill() error {
_assert(p.id < tx.meta.pgid, "pgid (%d) above high water mark (%d)", p.id, tx.meta.pgid)
node.pgid = p.id
node.write(p)
+ node.spilled = true
// Insert into parent inodes.
if node.parent != nil {