-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstore.go
151 lines (124 loc) · 2.69 KB
/
store.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package gocache
import (
"sync"
"sync/atomic"
)
// SyncMap 并发Map 当数据竞争大时,多核CPU时,使用比RwMap性能好,缺点空间占用会多点
type SyncMap struct {
store sync.Map
// about the value, Store func, I don't know if it exists
size int64
}
func NewSyncMap() *SyncMap {
s := SyncMap{
store: sync.Map{},
}
return &s
}
func (s *SyncMap) Load(key string) (value interface{}, ok bool) {
value, ok = s.store.Load(key)
return
}
func (s *SyncMap) Store(key string, value interface{}) {
s.store.Store(key, value)
}
func (s *SyncMap) Delete(key string) {
_, loaded := s.store.Load(key)
if loaded {
atomic.AddInt64(&s.size, -1)
}
s.store.Delete(key)
}
func (s *SyncMap) LoadOrStore(key string, value interface{}) (actual interface{}, loaded bool) {
v, loaded := s.store.LoadOrStore(key, value)
if !loaded {
atomic.AddInt64(&s.size, 1)
}
return v, loaded
}
func (s *SyncMap) Exists(key string) bool {
_, ok := s.Load(key)
return ok
}
func (s *SyncMap) Range(fn func(k string, v interface{}) bool) {
s.store.Range(func(key, value interface{}) bool {
return fn(key.(string), value)
})
}
func (s *SyncMap) Flush() {
s.store = sync.Map{}
atomic.StoreInt64(&s.size, 0)
}
func (s *SyncMap) Size() int64 {
size := atomic.LoadInt64(&s.size)
if size < 0 {
return 0
}
return size
}
// RWMap 读写Map 当数据竞争不强,或读取多时。使用节省空间更快
type RWMap struct {
rwMutex sync.RWMutex
store map[string]interface{}
}
func NewRWMap() *RWMap {
s := RWMap{
rwMutex: sync.RWMutex{},
store: make(map[string]interface{}),
}
return &s
}
func (s *RWMap) Load(key string) (value interface{}, ok bool) {
s.rwMutex.RLock()
value, ok = s.store[key]
s.rwMutex.RUnlock()
return value, ok
}
func (s *RWMap) Store(key string, value interface{}) {
s.rwMutex.Lock()
s.store[key] = value
s.rwMutex.Unlock()
}
func (s *RWMap) Delete(key string) {
s.rwMutex.Lock()
delete(s.store, key)
s.rwMutex.Unlock()
}
func (s *RWMap) LoadOrStore(key string, value interface{}) (actual interface{}, loaded bool) {
s.rwMutex.Lock()
defer s.rwMutex.Unlock()
v, ok := s.store[key]
if ok {
loaded = ok
actual = v
}
s.store[key] = value
if !loaded {
actual = value
}
return actual, loaded
}
func (s *RWMap) Exists(key string) bool {
_, ok := s.Load(key)
return ok
}
func (s *RWMap) Range(f func(k string, v interface{}) bool) {
s.rwMutex.RLock()
defer s.rwMutex.RUnlock()
for k, v := range s.store {
if !f(k, v) {
break
}
}
}
func (s *RWMap) Flush() {
s.rwMutex.Lock()
s.store = make(map[string]interface{})
s.rwMutex.Unlock()
}
func (s *RWMap) Size() int64 {
s.rwMutex.Lock()
size := len(s.store)
s.rwMutex.Unlock()
return int64(size)
}