-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathhashmap.go
100 lines (85 loc) · 1.56 KB
/
hashmap.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
// NOTICE: hashmap is not ok when enable data race detection.
package lc
import (
"time"
"github.com/simplejia/utils"
)
type Elem struct {
key string
value interface{}
birth int64
}
type HashMap struct {
elems []*Elem
bnum int
blen int
}
func (m *HashMap) Init(num int) *HashMap {
if m == nil {
m = new(HashMap)
}
m.blen = 100
m.bnum = int(float64(num)*1.2)/m.blen + 1
m.elems = make([]*Elem, m.blen*m.bnum)
return m
}
func (m *HashMap) getElem(key string) (elem *Elem, pos int) {
hash := utils.Hash33(key)
index := (hash % m.bnum) * m.blen
var oldRecord *Elem
var freeRecordFlag bool
for i := 0; i < m.blen; i++ {
j := index + i
tmpRecord := m.elems[j]
if tmpRecord == nil {
pos = j
freeRecordFlag = true
continue
}
if tmpRecord.key == key {
pos = j
elem = tmpRecord
break
}
if freeRecordFlag {
continue
}
if oldRecord == nil || oldRecord.birth > tmpRecord.birth {
oldRecord = tmpRecord
pos = j
continue
}
}
return
}
func (m *HashMap) Len() int {
return len(m.elems)
}
func (m *HashMap) Get(key string) (value interface{}, ok bool) {
elem, _ := m.getElem(key)
if elem != nil {
value, ok = elem.value, true
}
return
}
func (m *HashMap) Set(key string, value interface{}) {
now := time.Now().Unix()
elem, pos := m.getElem(key)
if elem != nil {
elem.value, elem.birth = value, now
} else {
m.elems[pos] = &Elem{
key: key,
value: value,
birth: now,
}
}
return
}
func (m *HashMap) Delete(key string) {
elem, pos := m.getElem(key)
if elem != nil {
m.elems[pos] = nil
}
return
}