准备回滚到数组版本
This commit is contained in:
parent
48f48fe782
commit
db935ea11f
|
@ -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)) {
|
||||
n := bkt.data[bkt.size]
|
||||
n.hash = hash
|
||||
n.key = k
|
||||
n.value = v
|
||||
bkt.size++
|
||||
return
|
||||
}
|
||||
|
||||
bkt.data = append(bkt.data, &bucketNode{key: k, value: v, hash: hash})
|
||||
bkt.size++
|
||||
}
|
||||
|
||||
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)) {
|
||||
bkt.data[bkt.size] = node
|
||||
bkt.size++
|
||||
return
|
||||
}
|
||||
bkt.data = append(bkt.data, node)
|
||||
bkt.size++
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package hashmap
|
||||
package gomap
|
||||
|
||||
import "fmt"
|
||||
|
|
@ -12,8 +12,9 @@ type HashMap struct {
|
|||
|
||||
table *Table
|
||||
|
||||
GetHash HashCode
|
||||
Compare compare.Compare
|
||||
GetHash HashCode
|
||||
Compare compare.Compare
|
||||
|
||||
growsize uint
|
||||
size uint
|
||||
}
|
||||
|
@ -40,33 +41,34 @@ func (hm *HashMap) countNextGrow() {
|
|||
hm.growsize = hm.table.Cap() << 1
|
||||
}
|
||||
|
||||
var growcount = 0
|
||||
|
||||
func (hm *HashMap) grow() {
|
||||
if hm.size >= hm.growsize {
|
||||
|
||||
newsize := hm.size << 1
|
||||
// newtable := make([]*avlTree, newsize, newsize)
|
||||
hm.table.Grow(int(newsize - hm.size))
|
||||
nodelist := make([]*bucketNode, hm.size, hm.size)
|
||||
|
||||
var count = 0
|
||||
for i := 0; i < len(hm.table.data); i++ {
|
||||
curbkt := hm.table.data[i]
|
||||
tnodelist := curbkt.data
|
||||
for _, n := range tnodelist {
|
||||
nodelist[count] = n
|
||||
count++
|
||||
nodelist := make([]*avlNode, hm.size, hm.size)
|
||||
i := 0
|
||||
hm.table.Traversal(func(cur *avlTree) {
|
||||
if cur != nil {
|
||||
cur.Traversal(func(node *avlNode) bool {
|
||||
nodelist[i] = node
|
||||
i++
|
||||
return true
|
||||
})
|
||||
cur.Clear()
|
||||
}
|
||||
curbkt.size = 0
|
||||
}
|
||||
})
|
||||
|
||||
var hash, index uint
|
||||
for _, node := range nodelist {
|
||||
index := node.hash % hm.table.cap
|
||||
hash = hm.GetHash(node.key)
|
||||
index = hash % hm.table.cap
|
||||
//bkt := newtable[index]
|
||||
hm.table.data[index].AddNode(node, hm.Compare)
|
||||
// bkt.data
|
||||
// bkt.PutNode(node)
|
||||
bkt := hm.table.GetWithNilSet(index, func(data []*avlTree, idx uint) {
|
||||
data[idx] = avlNew(hm.Compare)
|
||||
})
|
||||
node.clearAttr()
|
||||
bkt.PutNode(node)
|
||||
}
|
||||
|
||||
hm.countNextGrow()
|
||||
|
@ -74,13 +76,18 @@ func (hm *HashMap) grow() {
|
|||
}
|
||||
|
||||
func (hm *HashMap) Put(key, value interface{}) {
|
||||
|
||||
hash := hm.GetHash(key)
|
||||
|
||||
tlen := hm.table.Cap()
|
||||
index := hash % tlen
|
||||
|
||||
bkt := hm.table.GetWithNilSet(index)
|
||||
bkt.Add(hash, key, value, hm.Compare)
|
||||
bkt := hm.table.GetWithNilSet(index, func(data []*avlTree, idx uint) {
|
||||
data[idx] = avlNew(hm.Compare)
|
||||
})
|
||||
if bkt.Put(key, value) {
|
||||
hm.size++
|
||||
hm.grow()
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
if bkt != nil {
|
||||
return bkt.Get(key, hm.Compare), true
|
||||
return bkt.Get(key)
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
|
|
@ -26,11 +26,9 @@ func loadTestData() []int {
|
|||
}
|
||||
func TestCount(t *testing.T) {
|
||||
hm := New(HashInt, compare.Int)
|
||||
|
||||
for i := 0; i < 100000; i++ {
|
||||
hm.Put(i, i)
|
||||
}
|
||||
|
||||
// for i := 0; i < 100000; i++ {
|
||||
// hm.Put(i, i)
|
||||
// }
|
||||
for i := 0; i < 100000; i++ {
|
||||
hm.Put(i, i)
|
||||
}
|
||||
|
|
|
@ -8,13 +8,13 @@ type Table struct {
|
|||
size uint
|
||||
growsize uint
|
||||
|
||||
data []hmBucket
|
||||
data []*avlTree
|
||||
cap uint
|
||||
}
|
||||
|
||||
func newTable() *Table {
|
||||
table := &Table{}
|
||||
table.data = make([]hmBucket, 16, 16)
|
||||
table.data = make([]*avlTree, 16, 16)
|
||||
table.countCap()
|
||||
return table
|
||||
}
|
||||
|
@ -27,20 +27,30 @@ func (t *Table) Cap() uint {
|
|||
return t.cap
|
||||
}
|
||||
|
||||
func (t *Table) Traversal(every func(node *avlTree)) {
|
||||
for _, z := range t.data {
|
||||
every(z)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Table) Grow(size int) {
|
||||
zsize := len(t.data) + size
|
||||
temp := make([]hmBucket, zsize, zsize)
|
||||
temp := make([]*avlTree, zsize, zsize)
|
||||
copy(temp, t.data)
|
||||
t.data = temp
|
||||
t.countCap()
|
||||
}
|
||||
|
||||
func (t *Table) Get(idx uint) *hmBucket {
|
||||
return &(t.data[idx])
|
||||
func (t *Table) Get(idx uint) *avlTree {
|
||||
return t.data[idx]
|
||||
}
|
||||
|
||||
func (t *Table) GetWithNilSet(idx uint) *hmBucket {
|
||||
return &(t.data[idx])
|
||||
func (t *Table) GetWithNilSet(idx uint, DoSetValue func([]*avlTree, uint)) *avlTree {
|
||||
|
||||
if t.data[idx] == nil {
|
||||
DoSetValue(t.data, idx)
|
||||
}
|
||||
return t.data[idx]
|
||||
}
|
||||
|
||||
// func (arr *Table) Get(idx int) (interface{}, bool) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user