recycle treap nodes
This commit is contained in:
parent
357d875251
commit
3b25c33e23
4 changed files with 78 additions and 14 deletions
|
@ -502,6 +502,8 @@ func (c *dbCache) flush() error {
|
|||
c.cacheLock.RLock()
|
||||
cachedKeys := c.cachedKeys
|
||||
cachedRemove := c.cachedRemove
|
||||
c.cachedKeys = treap.NewImmutable()
|
||||
c.cachedRemove = treap.NewImmutable()
|
||||
c.cacheLock.RUnlock()
|
||||
|
||||
// Nothing to do if there is no data to flush.
|
||||
|
@ -514,11 +516,8 @@ func (c *dbCache) flush() error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Clear the cache since it has been flushed.
|
||||
c.cacheLock.Lock()
|
||||
c.cachedKeys = treap.NewImmutable()
|
||||
c.cachedRemove = treap.NewImmutable()
|
||||
c.cacheLock.Unlock()
|
||||
cachedKeys.Recycle()
|
||||
cachedRemove.Recycle()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -578,9 +577,16 @@ func (c *dbCache) commitTx(tx *transaction) error {
|
|||
return err
|
||||
}
|
||||
|
||||
pk := tx.pendingKeys
|
||||
pr := tx.pendingRemove
|
||||
|
||||
// Clear the transaction entries since they have been committed.
|
||||
tx.pendingKeys = nil
|
||||
tx.pendingRemove = nil
|
||||
|
||||
pk.Recycle()
|
||||
pr.Recycle()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,13 @@ type treapNode struct {
|
|||
right *treapNode
|
||||
}
|
||||
|
||||
func (n *treapNode) Reset() {
|
||||
n.key = nil
|
||||
n.value = nil
|
||||
n.left = nil
|
||||
n.right = nil
|
||||
}
|
||||
|
||||
// nodeSize returns the number of bytes the specified node occupies including
|
||||
// the struct fields and the contents of the key and value.
|
||||
func nodeSize(node *treapNode) uint64 {
|
||||
|
|
|
@ -7,17 +7,20 @@ package treap
|
|||
import (
|
||||
"bytes"
|
||||
"math/rand"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var nodePool = &sync.Pool{New: func() interface{} { return newTreapNode(nil, nil, 0) }}
|
||||
|
||||
// cloneTreapNode returns a shallow copy of the passed node.
|
||||
func cloneTreapNode(node *treapNode) *treapNode {
|
||||
return &treapNode{
|
||||
key: node.key,
|
||||
value: node.value,
|
||||
priority: node.priority,
|
||||
left: node.left,
|
||||
right: node.right,
|
||||
}
|
||||
clone := nodePool.Get().(*treapNode)
|
||||
clone.key = node.key
|
||||
clone.value = node.value
|
||||
clone.priority = node.priority
|
||||
clone.left = node.left
|
||||
clone.right = node.right
|
||||
return clone
|
||||
}
|
||||
|
||||
// Immutable represents a treap data structure which is used to hold ordered
|
||||
|
@ -165,7 +168,10 @@ func (t *Immutable) Put(key, value []byte) *Immutable {
|
|||
}
|
||||
|
||||
// Link the new node into the binary tree in the correct position.
|
||||
node := newTreapNode(key, value, rand.Int())
|
||||
node := nodePool.Get().(*treapNode)
|
||||
node.key = key
|
||||
node.value = value
|
||||
node.priority = rand.Int()
|
||||
parent := parents.At(0)
|
||||
if compareResult < 0 {
|
||||
parent.left = node
|
||||
|
@ -358,3 +364,24 @@ func (t *Immutable) ForEach(fn func(k, v []byte) bool) {
|
|||
func NewImmutable() *Immutable {
|
||||
return &Immutable{}
|
||||
}
|
||||
|
||||
func (t *Immutable) Recycle() {
|
||||
var parents parentStack
|
||||
for node := t.root; node != nil; node = node.left {
|
||||
parents.Push(node)
|
||||
}
|
||||
|
||||
for parents.Len() > 0 {
|
||||
node := parents.Pop()
|
||||
|
||||
// Extend the nodes to traverse by all children to the left of
|
||||
// the current node's right child.
|
||||
for n := node.right; n != nil; n = n.left {
|
||||
parents.Push(n)
|
||||
}
|
||||
|
||||
node.Reset()
|
||||
nodePool.Put(node)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -145,7 +145,10 @@ func (t *Mutable) Put(key, value []byte) {
|
|||
}
|
||||
|
||||
// Link the new node into the binary tree in the correct position.
|
||||
node := newTreapNode(key, value, rand.Int())
|
||||
node := nodePool.Get().(*treapNode)
|
||||
node.key = key
|
||||
node.value = value
|
||||
node.priority = rand.Int()
|
||||
t.count++
|
||||
t.totalSize += nodeSize(node)
|
||||
parent := parents.At(0)
|
||||
|
@ -276,3 +279,24 @@ func (t *Mutable) Reset() {
|
|||
func NewMutable() *Mutable {
|
||||
return &Mutable{}
|
||||
}
|
||||
|
||||
func (t *Mutable) Recycle() {
|
||||
var parents parentStack
|
||||
for node := t.root; node != nil; node = node.left {
|
||||
parents.Push(node)
|
||||
}
|
||||
|
||||
for parents.Len() > 0 {
|
||||
node := parents.Pop()
|
||||
|
||||
// Extend the nodes to traverse by all children to the left of
|
||||
// the current node's right child.
|
||||
for n := node.right; n != nil; n = n.left {
|
||||
parents.Push(n)
|
||||
}
|
||||
|
||||
node.Reset()
|
||||
nodePool.Put(node)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue