structure/hashmap/hashmap.go

104 lines
1.9 KiB
Go
Raw Normal View History

2019-04-16 19:22:07 +00:00
package hashmap
import (
2019-04-18 01:39:44 +00:00
"474420502.top/eson/structure/compare"
2019-04-16 19:22:07 +00:00
)
2019-04-18 01:39:44 +00:00
type HashCode func(key interface{}) uint
2019-04-16 19:22:07 +00:00
type HashMap struct {
2019-04-21 05:31:39 +00:00
growfactor uint
slimmingfactor uint
2019-04-22 06:06:19 +00:00
table *Table
2019-04-16 19:22:07 +00:00
2019-04-18 01:39:44 +00:00
GetHash HashCode
Compare compare.Compare
2019-04-21 05:31:39 +00:00
growsize uint
size uint
2019-04-18 01:39:44 +00:00
}
2019-04-16 19:22:07 +00:00
func HashInt(key interface{}) uint {
thekey := uint(key.(int))
hbit := thekey & 0xffffffff
lbit := (thekey & 0xffffffff00000000) >> 32
return lbit ^ hbit
}
2019-04-18 01:39:44 +00:00
func New(hcode HashCode, comp compare.Compare) *HashMap {
2019-04-16 19:22:07 +00:00
hm := &HashMap{}
hm.growfactor = 2
2019-04-18 01:39:44 +00:00
hm.GetHash = hcode
hm.Compare = comp
2019-04-22 06:06:19 +00:00
// initcap := uint(8)
hm.table = newTable()
2019-04-21 20:46:07 +00:00
hm.countNextGrow()
2019-04-16 19:22:07 +00:00
return hm
}
2019-04-21 20:46:07 +00:00
func (hm *HashMap) countNextGrow() {
2019-04-22 19:05:25 +00:00
hm.growsize = hm.table.Cap() << 1
2019-04-21 20:46:07 +00:00
}
2019-04-21 05:31:39 +00:00
func (hm *HashMap) grow() {
if hm.size >= hm.growsize {
newsize := hm.size << 1
2019-04-22 06:06:19 +00:00
// newtable := make([]*avlTree, newsize, newsize)
hm.table.Grow(int(newsize - hm.size))
2019-04-22 04:53:23 +00:00
nodelist := make([]*avlNode, hm.size, hm.size)
i := 0
2019-04-22 06:06:19 +00:00
hm.table.Traversal(func(cur *avlTree) {
2019-04-21 20:46:07 +00:00
if cur != nil {
2019-04-22 04:53:23 +00:00
cur.Traversal(func(node *avlNode) bool {
nodelist[i] = node
i++
2019-04-21 20:46:07 +00:00
return true
})
2019-04-22 06:06:19 +00:00
cur.Clear()
2019-04-21 05:31:39 +00:00
}
2019-04-22 06:06:19 +00:00
})
2019-04-22 04:53:23 +00:00
var hash, index uint
for _, node := range nodelist {
hash = hm.GetHash(node.key)
2019-04-22 19:05:25 +00:00
index = hash % hm.table.cap
2019-04-22 06:06:19 +00:00
//bkt := newtable[index]
2019-04-22 19:05:25 +00:00
bkt := hm.table.GetWithNilSet(index, func(data []*avlTree, idx uint) {
data[idx] = avlNew(hm.Compare)
2019-04-22 06:06:19 +00:00
})
2019-04-22 04:53:23 +00:00
bkt.PutNode(node)
2019-04-21 05:31:39 +00:00
}
2019-04-22 06:06:19 +00:00
2019-04-21 20:46:07 +00:00
hm.countNextGrow()
2019-04-21 05:31:39 +00:00
}
}
2019-04-16 19:22:07 +00:00
func (hm *HashMap) Put(key, value interface{}) {
hash := hm.GetHash(key)
2019-04-21 05:31:39 +00:00
2019-04-22 06:06:19 +00:00
tlen := hm.table.Cap()
2019-04-21 05:31:39 +00:00
index := hash % tlen
2019-04-22 19:05:25 +00:00
bkt := hm.table.GetWithNilSet(index, func(data []*avlTree, idx uint) {
data[idx] = avlNew(hm.Compare)
2019-04-22 06:06:19 +00:00
})
2019-04-21 20:46:07 +00:00
if bkt.Put(key, value) {
hm.size++
hm.grow()
}
}
2019-04-21 05:31:39 +00:00
2019-04-21 20:46:07 +00:00
func (hm *HashMap) Get(key interface{}) (interface{}, bool) {
hash := hm.GetHash(key)
2019-04-21 05:31:39 +00:00
2019-04-22 06:06:19 +00:00
tlen := hm.table.Cap()
2019-04-21 20:46:07 +00:00
index := hash % tlen
2019-04-22 06:06:19 +00:00
bkt := hm.table.Get(index)
2019-04-21 20:46:07 +00:00
if bkt != nil {
return bkt.Get(key)
}
return nil, false
2019-04-16 19:22:07 +00:00
}