structure/hashmap/hashmap.go

98 lines
1.8 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-05-06 09:01:18 +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-05-06 09:01:18 +00:00
var growcount = 0
2019-04-21 05:31:39 +00:00
func (hm *HashMap) grow() {
if hm.size >= hm.growsize {
2019-05-06 09:01:18 +00:00
2019-04-21 05:31:39 +00:00
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-05-06 10:40:09 +00:00
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++
2019-04-21 05:31:39 +00:00
}
2019-05-06 10:40:09 +00:00
curbkt.size = 0
}
2019-04-22 06:06:19 +00:00
2019-04-22 04:53:23 +00:00
for _, node := range nodelist {
2019-05-06 10:40:09 +00:00
index := node.hash % hm.table.cap
2019-04-22 06:06:19 +00:00
//bkt := newtable[index]
2019-05-06 10:40:09 +00:00
hm.table.data[index].AddNode(node, hm.Compare)
// bkt.data
// 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{}) {
2019-04-21 05:31:39 +00:00
2019-05-06 09:01:18 +00:00
hash := hm.GetHash(key)
2019-04-22 06:06:19 +00:00
tlen := hm.table.Cap()
2019-04-21 05:31:39 +00:00
index := hash % tlen
2019-05-06 10:40:09 +00:00
bkt := hm.table.GetWithNilSet(index)
bkt.Add(hash, key, value, hm.Compare)
2019-04-21 20:46:07 +00:00
}
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 {
2019-05-06 10:40:09 +00:00
return bkt.Get(key, hm.Compare), true
2019-04-21 20:46:07 +00:00
}
return nil, false
2019-04-16 19:22:07 +00:00
}