structure/hashmap/hashmap.go
2019-05-06 18:40:09 +08:00

98 lines
1.8 KiB
Go

package hashmap
import (
"474420502.top/eson/structure/compare"
)
type HashCode func(key interface{}) uint
type HashMap struct {
growfactor uint
slimmingfactor uint
table *Table
GetHash HashCode
Compare compare.Compare
growsize uint
size uint
}
func HashInt(key interface{}) uint {
thekey := uint(key.(int))
hbit := thekey & 0xffffffff
lbit := (thekey & 0xffffffff00000000) >> 32
return lbit ^ hbit
}
func New(hcode HashCode, comp compare.Compare) *HashMap {
hm := &HashMap{}
hm.growfactor = 2
hm.GetHash = hcode
hm.Compare = comp
// initcap := uint(8)
hm.table = newTable()
hm.countNextGrow()
return hm
}
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++
}
curbkt.size = 0
}
for _, node := range nodelist {
index := node.hash % hm.table.cap
//bkt := newtable[index]
hm.table.data[index].AddNode(node, hm.Compare)
// bkt.data
// bkt.PutNode(node)
}
hm.countNextGrow()
}
}
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)
}
func (hm *HashMap) Get(key interface{}) (interface{}, bool) {
hash := hm.GetHash(key)
tlen := hm.table.Cap()
index := hash % tlen
bkt := hm.table.Get(index)
if bkt != nil {
return bkt.Get(key, hm.Compare), true
}
return nil, false
}