准备回滚到数组版本

This commit is contained in:
eson 2019-05-07 13:59:29 +08:00
parent 48f48fe782
commit db935ea11f
5 changed files with 56 additions and 39 deletions

View File

@ -40,16 +40,17 @@ func (bkt *hmBucket) Add(hash uint, k, v interface{}, Compare compare.Compare) {
} }
} }
bkt.size++
if bkt.size < uint(len(bkt.data)) { if bkt.size < uint(len(bkt.data)) {
n := bkt.data[bkt.size] n := bkt.data[bkt.size]
n.hash = hash n.hash = hash
n.key = k n.key = k
n.value = v n.value = v
bkt.size++
return return
} }
bkt.data = append(bkt.data, &bucketNode{key: k, value: v, hash: hash}) bkt.data = append(bkt.data, &bucketNode{key: k, value: v, hash: hash})
bkt.size++
} }
func (bkt *hmBucket) AddNode(node *bucketNode, Compare compare.Compare) { func (bkt *hmBucket) AddNode(node *bucketNode, Compare compare.Compare) {
@ -65,10 +66,11 @@ func (bkt *hmBucket) AddNode(node *bucketNode, Compare compare.Compare) {
} }
} }
bkt.size++
if bkt.size < uint(len(bkt.data)) { if bkt.size < uint(len(bkt.data)) {
bkt.data[bkt.size] = node bkt.data[bkt.size] = node
bkt.size++
return return
} }
bkt.data = append(bkt.data, node) bkt.data = append(bkt.data, node)
bkt.size++
} }

View File

@ -1,4 +1,4 @@
package hashmap package gomap
import "fmt" import "fmt"

View File

@ -12,8 +12,9 @@ type HashMap struct {
table *Table table *Table
GetHash HashCode GetHash HashCode
Compare compare.Compare Compare compare.Compare
growsize uint growsize uint
size uint size uint
} }
@ -40,33 +41,34 @@ func (hm *HashMap) countNextGrow() {
hm.growsize = hm.table.Cap() << 1 hm.growsize = hm.table.Cap() << 1
} }
var growcount = 0
func (hm *HashMap) grow() { func (hm *HashMap) grow() {
if hm.size >= hm.growsize { if hm.size >= hm.growsize {
newsize := hm.size << 1 newsize := hm.size << 1
// newtable := make([]*avlTree, newsize, newsize) // newtable := make([]*avlTree, newsize, newsize)
hm.table.Grow(int(newsize - hm.size)) hm.table.Grow(int(newsize - hm.size))
nodelist := make([]*bucketNode, hm.size, hm.size) nodelist := make([]*avlNode, hm.size, hm.size)
i := 0
var count = 0 hm.table.Traversal(func(cur *avlTree) {
for i := 0; i < len(hm.table.data); i++ { if cur != nil {
curbkt := hm.table.data[i] cur.Traversal(func(node *avlNode) bool {
tnodelist := curbkt.data nodelist[i] = node
for _, n := range tnodelist { i++
nodelist[count] = n return true
count++ })
cur.Clear()
} }
curbkt.size = 0 })
}
var hash, index uint
for _, node := range nodelist { for _, node := range nodelist {
index := node.hash % hm.table.cap hash = hm.GetHash(node.key)
index = hash % hm.table.cap
//bkt := newtable[index] //bkt := newtable[index]
hm.table.data[index].AddNode(node, hm.Compare) bkt := hm.table.GetWithNilSet(index, func(data []*avlTree, idx uint) {
// bkt.data data[idx] = avlNew(hm.Compare)
// bkt.PutNode(node) })
node.clearAttr()
bkt.PutNode(node)
} }
hm.countNextGrow() hm.countNextGrow()
@ -74,13 +76,18 @@ func (hm *HashMap) grow() {
} }
func (hm *HashMap) Put(key, value interface{}) { func (hm *HashMap) Put(key, value interface{}) {
hash := hm.GetHash(key) hash := hm.GetHash(key)
tlen := hm.table.Cap() tlen := hm.table.Cap()
index := hash % tlen index := hash % tlen
bkt := hm.table.GetWithNilSet(index) bkt := hm.table.GetWithNilSet(index, func(data []*avlTree, idx uint) {
bkt.Add(hash, key, value, hm.Compare) data[idx] = avlNew(hm.Compare)
})
if bkt.Put(key, value) {
hm.size++
hm.grow()
}
} }
func (hm *HashMap) Get(key interface{}) (interface{}, bool) { func (hm *HashMap) Get(key interface{}) (interface{}, bool) {
@ -91,7 +98,7 @@ func (hm *HashMap) Get(key interface{}) (interface{}, bool) {
bkt := hm.table.Get(index) bkt := hm.table.Get(index)
if bkt != nil { if bkt != nil {
return bkt.Get(key, hm.Compare), true return bkt.Get(key)
} }
return nil, false return nil, false
} }

View File

@ -26,11 +26,9 @@ func loadTestData() []int {
} }
func TestCount(t *testing.T) { func TestCount(t *testing.T) {
hm := New(HashInt, compare.Int) hm := New(HashInt, compare.Int)
// for i := 0; i < 100000; i++ {
for i := 0; i < 100000; i++ { // hm.Put(i, i)
hm.Put(i, i) // }
}
for i := 0; i < 100000; i++ { for i := 0; i < 100000; i++ {
hm.Put(i, i) hm.Put(i, i)
} }

View File

@ -8,13 +8,13 @@ type Table struct {
size uint size uint
growsize uint growsize uint
data []hmBucket data []*avlTree
cap uint cap uint
} }
func newTable() *Table { func newTable() *Table {
table := &Table{} table := &Table{}
table.data = make([]hmBucket, 16, 16) table.data = make([]*avlTree, 16, 16)
table.countCap() table.countCap()
return table return table
} }
@ -27,20 +27,30 @@ func (t *Table) Cap() uint {
return t.cap return t.cap
} }
func (t *Table) Traversal(every func(node *avlTree)) {
for _, z := range t.data {
every(z)
}
}
func (t *Table) Grow(size int) { func (t *Table) Grow(size int) {
zsize := len(t.data) + size zsize := len(t.data) + size
temp := make([]hmBucket, zsize, zsize) temp := make([]*avlTree, zsize, zsize)
copy(temp, t.data) copy(temp, t.data)
t.data = temp t.data = temp
t.countCap() t.countCap()
} }
func (t *Table) Get(idx uint) *hmBucket { func (t *Table) Get(idx uint) *avlTree {
return &(t.data[idx]) return t.data[idx]
} }
func (t *Table) GetWithNilSet(idx uint) *hmBucket { func (t *Table) GetWithNilSet(idx uint, DoSetValue func([]*avlTree, uint)) *avlTree {
return &(t.data[idx])
if t.data[idx] == nil {
DoSetValue(t.data, idx)
}
return t.data[idx]
} }
// func (arr *Table) Get(idx int) (interface{}, bool) { // func (arr *Table) Get(idx int) (interface{}, bool) {