-
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"
)
type chainedHashMap struct {
hashMapBase
backets []*list.List
}
func (h *chainedHashMap) Init(cap uint32) {
h.hashMapBase.Init(cap)
if cap == 0 {
h.backets = nil
} else {
h.backets = make([]*list.List, h.Cap, h.Cap)
}
}
func (h *chainedHashMap) Move(cap uint32) {
oldBackets := h.backets
h.Init(cap)
for _, list := range oldBackets {
if list != nil {
for e := list.Front(); e != nil; e = e.Next() {
h.HashInsert(e.Value.(hashElement).Key, e.Value.(hashElement).Value)
}
}
}
}
func (h *chainedHashMap) hash(key interface{}) uint32 {
hashValue := h.HashFunc(key, sha1.New())
mb := big.NewInt(int64(h.Cap))
hashValue.Mod(hashValue, mb)
return uint32(hashValue.Uint64())
}
func (h *chainedHashMap) existInList(key interface{}, list *list.List) (*list.Element, bool) {
for e := list.Front(); e != nil; e = e.Next() {
if e.Value.(hashElement).Key == key {
return e, true
}
}
return nil, false
}
func (h *chainedHashMap) HashInsert(key interface{}, value interface{}) {
h.UpScale()
hashKey := h.hash(key)
if h.backets[hashKey] == nil {
h.backets[hashKey] = list.New()
}
e := hashElement{Key: key, Value: value}
le, exist := h.existInList(key, h.backets[hashKey])
if exist {
le.Value = e
} else {
h.backets[hashKey].PushFront(e)
h.Count++
}
}
func (h *chainedHashMap) HashGet(key interface{}) (interface{}, bool) {
if h.Count != 0 {
hashKey := h.hash(key)
if h.backets[hashKey] == nil {
return nil, false
}
le, exist := h.existInList(key, h.backets[hashKey])
if exist {
return le.Value.(hashElement).Value, true
}
}
return nil, false
}
func (h *chainedHashMap) HashDelete(key interface{}) {
hashKey := h.hash(key)
if h.backets[hashKey] == nil {
return
}
le, exist := h.existInList(key, h.backets[hashKey])
if exist {
h.backets[hashKey].Remove(le)
}
if h.backets[hashKey].Len() == 0 {
h.backets[hashKey] = nil
h.Count--
}
h.DownScale()
}
func newChainedHashMap() *chainedHashMap {
h := new(chainedHashMap)
h.hashMapBase.hashMap = h
h.hashMapBase.scaleableMap = h
return h
}