- Notifications
You must be signed in to change notification settings - Fork 121
/
Copy pathchainedHashMap.go
102 lines (92 loc) · 2.1 KB
/
chainedHashMap.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package hashMap
import (
"container/list"
"crypto/sha1"
"math/big"
)
typechainedHashMapstruct {
hashMapBase
backets []*list.List
}
func (h*chainedHashMap) Init(capuint32) {
h.hashMapBase.Init(cap)
ifcap==0 {
h.backets=nil
} else {
h.backets=make([]*list.List, h.Cap, h.Cap)
}
}
func (h*chainedHashMap) Move(capuint32) {
oldBackets:=h.backets
h.Init(cap)
for_, list:=rangeoldBackets {
iflist!=nil {
fore:=list.Front(); e!=nil; e=e.Next() {
h.HashInsert(e.Value.(hashElement).Key, e.Value.(hashElement).Value)
}
}
}
}
func (h*chainedHashMap) hash(keyinterface{}) uint32 {
hashValue:=h.HashFunc(key, sha1.New())
mb:=big.NewInt(int64(h.Cap))
hashValue.Mod(hashValue, mb)
returnuint32(hashValue.Uint64())
}
func (h*chainedHashMap) existInList(keyinterface{}, list*list.List) (*list.Element, bool) {
fore:=list.Front(); e!=nil; e=e.Next() {
ife.Value.(hashElement).Key==key {
returne, true
}
}
returnnil, false
}
func (h*chainedHashMap) HashInsert(keyinterface{}, valueinterface{}) {
h.UpScale()
hashKey:=h.hash(key)
ifh.backets[hashKey] ==nil {
h.backets[hashKey] =list.New()
}
e:=hashElement{Key: key, Value: value}
le, exist:=h.existInList(key, h.backets[hashKey])
ifexist {
le.Value=e
} else {
h.backets[hashKey].PushFront(e)
h.Count++
}
}
func (h*chainedHashMap) HashGet(keyinterface{}) (interface{}, bool) {
ifh.Count!=0 {
hashKey:=h.hash(key)
ifh.backets[hashKey] ==nil {
returnnil, false
}
le, exist:=h.existInList(key, h.backets[hashKey])
ifexist {
returnle.Value.(hashElement).Value, true
}
}
returnnil, false
}
func (h*chainedHashMap) HashDelete(keyinterface{}) {
hashKey:=h.hash(key)
ifh.backets[hashKey] ==nil {
return
}
le, exist:=h.existInList(key, h.backets[hashKey])
ifexist {
h.backets[hashKey].Remove(le)
}
ifh.backets[hashKey].Len() ==0 {
h.backets[hashKey] =nil
h.Count--
}
h.DownScale()
}
funcnewChainedHashMap() *chainedHashMap {
h:=new(chainedHashMap)
h.hashMapBase.hashMap=h
h.hashMapBase.scaleableMap=h
returnh
}