hashmap 缓存版本

This commit is contained in:
eson 2019-04-28 02:52:00 +08:00
parent 0bfa7f1317
commit dc00eb99f3
3 changed files with 92 additions and 1 deletions

View File

@ -94,6 +94,30 @@ func (tree *avlTree) Clear() {
// return nil, false
// }
func (tree *avlTree) Traversal(every func(*avlNode) bool) {
if tree.root == nil {
return
}
var traverasl func(cur *avlNode) bool
traverasl = func(cur *avlNode) bool {
if cur == nil {
return true
}
if !traverasl(cur.children[0]) {
return false
}
if !every(cur) {
return false
}
if !traverasl(cur.children[1]) {
return false
}
return true
}
traverasl(tree.root)
}
func (tree *avlTree) Get(key interface{}) (interface{}, bool) {
n, ok := tree.GetNode(key)
if ok {

View File

@ -15,6 +15,7 @@ type HashMap struct {
GetHash HashCode
Compare compare.Compare
pool *nodePool
growsize uint
size uint
}
@ -31,6 +32,7 @@ func New(hcode HashCode, comp compare.Compare) *HashMap {
hm.growfactor = 2
hm.GetHash = hcode
hm.Compare = comp
hm.pool = newNodePool()
// initcap := uint(8)
hm.table = newTable()
hm.countNextGrow()
@ -83,9 +85,13 @@ func (hm *HashMap) Put(key, value interface{}) {
bkt := hm.table.GetWithNilSet(index, func(data []*avlTree, idx uint) {
data[idx] = avlNew(hm.Compare)
})
if bkt.Put(key, value) {
n := hm.pool.Get()
if bkt.PutNode(n) {
hm.size++
hm.grow()
} else {
hm.pool.Recycling(n)
}
}

61
hashmap/pool.go Normal file
View File

@ -0,0 +1,61 @@
package hashmap
import (
"474420502.top/eson/structure/lastack"
)
type nodePool struct {
cache *lastack.Stack
data []avlNode
size int
growSize int
slimmingSize int
}
func newNodePool() *nodePool {
p := &nodePool{}
p.cache = lastack.New()
p.data = make([]avlNode, 16, 16)
p.countNextGrow()
return p
}
func (pool *nodePool) Get() *avlNode {
if !pool.cache.Empty() {
v, _ := pool.cache.Pop()
return v.(*avlNode)
}
pool.Grow()
cur := &pool.data[pool.size]
pool.size++
return cur
}
func (pool *nodePool) Recycling(n *avlNode) {
pool.cache.Push(n)
}
func (pool *nodePool) Grow() {
if pool.size >= len(pool.data) {
growsize := pool.size << 1
temp := make([]avlNode, growsize, growsize)
copy(temp, pool.data)
pool.data = temp
pool.countNextGrow()
}
}
func (pool *nodePool) slimming() {
if pool.size <= pool.slimmingSize {
growsize := len(pool.data) - pool.slimmingSize<<1
temp := make([]avlNode, growsize, growsize)
copy(temp, pool.data)
pool.data = temp
pool.countNextGrow()
}
}
func (pool *nodePool) countNextGrow() {
pool.growSize = len(pool.data)
pool.slimmingSize = pool.growSize << 1
}