modified node cache for LRU support
This commit is contained in:
parent
a1631880be
commit
d74924992a
2 changed files with 61 additions and 11 deletions
claimtrie
|
@ -2,6 +2,7 @@ package node
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"container/list"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -25,11 +26,63 @@ type Manager interface {
|
||||||
Hash(name []byte) *chainhash.Hash
|
Hash(name []byte) *chainhash.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type nodeCacheLeaf struct {
|
||||||
|
node *Node
|
||||||
|
key string
|
||||||
|
}
|
||||||
|
|
||||||
|
type nodeCache struct {
|
||||||
|
elements map[string]*list.Element
|
||||||
|
data *list.List
|
||||||
|
maxElements int
|
||||||
|
}
|
||||||
|
|
||||||
|
func newNodeCache(size int) *nodeCache {
|
||||||
|
return &nodeCache{elements:
|
||||||
|
make(map[string]*list.Element, size),
|
||||||
|
data: list.New(),
|
||||||
|
maxElements: size,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nc *nodeCache) Get(key string) *Node {
|
||||||
|
element := nc.elements[key]
|
||||||
|
if element != nil {
|
||||||
|
return element.Value.(nodeCacheLeaf).node
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nc *nodeCache) Put(key string, element *Node) {
|
||||||
|
existing := nc.elements[key]
|
||||||
|
if existing != nil {
|
||||||
|
existing.Value = nodeCacheLeaf{element, key}
|
||||||
|
nc.data.MoveToFront(existing)
|
||||||
|
} else if len(nc.elements) >= nc.maxElements {
|
||||||
|
existing = nc.data.Back()
|
||||||
|
delete(nc.elements, existing.Value.(nodeCacheLeaf).key)
|
||||||
|
existing.Value = nodeCacheLeaf{element, key}
|
||||||
|
nc.data.MoveToFront(existing)
|
||||||
|
nc.elements[key] = existing
|
||||||
|
} else {
|
||||||
|
nc.elements[key] = nc.data.PushFront(nodeCacheLeaf{element, key})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nc *nodeCache) Delete(key string) {
|
||||||
|
existing := nc.elements[key]
|
||||||
|
if existing != nil {
|
||||||
|
delete(nc.elements, key)
|
||||||
|
nc.data.Remove(existing)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
type BaseManager struct {
|
type BaseManager struct {
|
||||||
repo Repo
|
repo Repo
|
||||||
|
|
||||||
height int32
|
height int32
|
||||||
cache map[string]*Node
|
cache *nodeCache
|
||||||
changes []change.Change
|
changes []change.Change
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +90,7 @@ func NewBaseManager(repo Repo) (Manager, error) {
|
||||||
|
|
||||||
nm := &BaseManager{
|
nm := &BaseManager{
|
||||||
repo: repo,
|
repo: repo,
|
||||||
cache: map[string]*Node{},
|
cache: newNodeCache(param.MaxNodeManagerCacheSize),
|
||||||
}
|
}
|
||||||
|
|
||||||
return nm, nil
|
return nm, nil
|
||||||
|
@ -48,8 +101,8 @@ func NewBaseManager(repo Repo) (Manager, error) {
|
||||||
func (nm *BaseManager) Node(name []byte) (*Node, error) {
|
func (nm *BaseManager) Node(name []byte) (*Node, error) {
|
||||||
|
|
||||||
nameStr := string(name)
|
nameStr := string(name)
|
||||||
n, ok := nm.cache[nameStr]
|
n := nm.cache.Get(nameStr)
|
||||||
if ok && n != nil {
|
if n != nil {
|
||||||
return n.AdjustTo(nm.height, -1, name), nil
|
return n.AdjustTo(nm.height, -1, name), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,10 +120,7 @@ func (nm *BaseManager) Node(name []byte) (*Node, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(nm.cache) > param.MaxNodeManagerCacheSize {
|
nm.cache.Put(nameStr, n)
|
||||||
nm.cache = map[string]*Node{} // TODO: let's get a real LRU cache in here
|
|
||||||
}
|
|
||||||
nm.cache[nameStr] = n
|
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +166,7 @@ func (nm *BaseManager) newNodeFromChanges(changes []change.Change, height int32)
|
||||||
|
|
||||||
func (nm *BaseManager) AppendChange(chg change.Change) error {
|
func (nm *BaseManager) AppendChange(chg change.Change) error {
|
||||||
|
|
||||||
delete(nm.cache, string(chg.Name))
|
nm.cache.Delete(string(chg.Name))
|
||||||
nm.changes = append(nm.changes, chg)
|
nm.changes = append(nm.changes, chg)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -196,7 +246,7 @@ func (nm *BaseManager) DecrementHeightTo(affectedNames [][]byte, height int32) e
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range affectedNames {
|
for _, name := range affectedNames {
|
||||||
delete(nm.cache, string(name))
|
nm.cache.Delete(string(name))
|
||||||
if err := nm.repo.DropChanges(name, height); err != nil {
|
if err := nm.repo.DropChanges(name, height); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ var (
|
||||||
func SetNetwork(net wire.BitcoinNet) {
|
func SetNetwork(net wire.BitcoinNet) {
|
||||||
MaxActiveDelay = 4032
|
MaxActiveDelay = 4032
|
||||||
ActiveDelayFactor = 32
|
ActiveDelayFactor = 32
|
||||||
MaxNodeManagerCacheSize = 16000
|
MaxNodeManagerCacheSize = 32000
|
||||||
|
|
||||||
switch net {
|
switch net {
|
||||||
case wire.MainNet:
|
case wire.MainNet:
|
||||||
|
|
Loading…
Add table
Reference in a new issue