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
|
|
|
}
|