@@ -5,16 +5,11 @@ import (
5
5
"sync"
6
6
"sync/atomic"
7
7
"time"
8
-
9
- "github.com/patrickmn/go-cache"
10
8
)
11
9
12
10
type RegistrationDB struct {
13
11
sync.RWMutex
14
- registrationMap map [Registration ]ProducerMap
15
-
16
- cachedMutex sync.RWMutex
17
- cachedFindProducersResults * cache.Cache
12
+ registrationMap * sync.Map
18
13
}
19
14
20
15
type MetaDB struct {
@@ -64,8 +59,7 @@ func (p *Producer) IsTombstoned(lifetime time.Duration) bool {
64
59
65
60
func NewRegistrationDB () * RegistrationDB {
66
61
return & RegistrationDB {
67
- registrationMap : make (map [Registration ]ProducerMap ),
68
- cachedFindProducersResults : cache .New (1 * time .Minute , 5 * time .Minute ),
62
+ registrationMap : & sync.Map {},
69
63
}
70
64
}
71
65
@@ -77,12 +71,7 @@ func NewMetaDB() *MetaDB {
77
71
78
72
// add a registration key
79
73
func (r * RegistrationDB ) AddRegistration (k Registration ) {
80
- r .Lock ()
81
- defer r .Unlock ()
82
- _ , ok := r .registrationMap [k ]
83
- if ! ok {
84
- r .registrationMap [k ] = make (map [string ]* Producer )
85
- }
74
+ r .registrationMap .LoadOrStore (k , make (ProducerMap ))
86
75
}
87
76
88
77
// add a registration key
@@ -123,123 +112,111 @@ func (m *MetaDB) FindRegistrations(category string, key string, subkey string) R
123
112
func (r * RegistrationDB ) AddProducer (k Registration , p * Producer ) bool {
124
113
r .Lock ()
125
114
defer r .Unlock ()
126
- _ , ok := r .registrationMap [k ]
127
- if ! ok {
128
- r .registrationMap [k ] = make (map [string ]* Producer )
129
- }
130
- producers := r .registrationMap [k ]
115
+ val , _ := r .registrationMap .LoadOrStore (k , make (ProducerMap ))
116
+ producers := val .(ProducerMap )
131
117
_ , found := producers [p .peerInfo .id ]
132
118
if found == false {
133
119
producers [p .peerInfo .id ] = p
134
120
}
121
+
135
122
return ! found
136
123
}
137
124
138
125
// remove a producer from a registration
139
126
func (r * RegistrationDB ) RemoveProducer (k Registration , id string ) (bool , int ) {
140
127
r .Lock ()
141
128
defer r .Unlock ()
142
- producers , ok := r .registrationMap [ k ]
129
+ value , ok := r .registrationMap . Load ( k )
143
130
if ! ok {
144
131
return false , 0
145
132
}
133
+ producers := value .(ProducerMap )
146
134
removed := false
147
135
if _ , exists := producers [id ]; exists {
148
136
removed = true
149
137
}
150
138
151
139
// Note: this leaves keys in the DB even if they have empty lists
152
140
delete (producers , id )
141
+
153
142
return removed , len (producers )
154
143
}
155
144
156
145
// remove a Registration and all it's producers
157
146
func (r * RegistrationDB ) RemoveRegistration (k Registration ) {
158
- r .Lock ()
159
- defer r .Unlock ()
160
- delete (r .registrationMap , k )
147
+ r .registrationMap .Delete (k )
161
148
}
162
149
163
150
func (r * RegistrationDB ) needFilter (key string , subkey string ) bool {
164
151
return key == "*" || subkey == "*"
165
152
}
166
153
167
154
func (r * RegistrationDB ) FindRegistrations (category string , key string , subkey string ) Registrations {
168
- r .RLock ()
169
- defer r .RUnlock ()
170
155
if ! r .needFilter (key , subkey ) {
171
156
k := Registration {category , key , subkey }
172
- if _ , ok := r .registrationMap [ k ] ; ok {
157
+ if _ , ok := r .registrationMap . Load ( k ) ; ok {
173
158
return Registrations {k }
174
159
}
175
160
return Registrations {}
176
161
}
177
162
results := Registrations {}
178
- for k := range r . registrationMap {
179
- if ! k .IsMatch (category , key , subkey ) {
180
- continue
163
+ r . registrationMap . Range ( func ( k , _ interface {}) bool {
164
+ if k .( Registration ) .IsMatch (category , key , subkey ) {
165
+ results = append ( results , k .( Registration ))
181
166
}
182
- results = append ( results , k )
183
- }
167
+ return true
168
+ })
184
169
return results
185
170
}
186
171
187
172
func (r * RegistrationDB ) FindProducers (category string , key string , subkey string ) Producers {
188
- r .cachedMutex .RLock ()
189
- cachedKey := fmt .Sprintf ("%s:%s:%s" , category , key , subkey )
190
-
191
- if val , found := r .cachedFindProducersResults .Get (cachedKey ); found {
192
- r .cachedMutex .RUnlock ()
193
- return val .(Producers )
194
- }
195
-
196
- r .cachedMutex .RUnlock ()
197
-
198
- r .cachedMutex .Lock ()
199
- defer r .cachedMutex .Unlock ()
200
-
201
- if val , found := r .cachedFindProducersResults .Get (cachedKey ); found {
202
- return val .(Producers )
203
- }
204
-
205
- r .RLock ()
206
- defer r .RUnlock ()
207
-
208
173
if ! r .needFilter (key , subkey ) {
209
174
k := Registration {category , key , subkey }
210
- r .cachedFindProducersResults .Set (cachedKey , ProducerMap2Slice (r .registrationMap [k ]), cache .DefaultExpiration )
211
- return ProducerMap2Slice (r .registrationMap [k ])
175
+ val , _ := r .registrationMap .Load (k )
176
+
177
+ r .RLock ()
178
+ defer r .RUnlock ()
179
+ return ProducerMap2Slice (val .(ProducerMap ))
212
180
}
213
181
182
+ r .RLock ()
214
183
results := make (map [string ]struct {})
215
184
var retProducers Producers
216
- for k , producers := range r . registrationMap {
217
- if ! k .IsMatch (category , key , subkey ) {
218
- continue
219
- }
220
- for _ , producer := range producers {
221
- _ , found := results [ producer . peerInfo . id ]
222
- if found == false {
223
- results [ producer . peerInfo . id ] = struct {}{}
224
- retProducers = append ( retProducers , producer )
185
+ r . registrationMap . Range ( func ( k , v interface {}) bool {
186
+ if k .( Registration ) .IsMatch (category , key , subkey ) {
187
+ producers := v .( ProducerMap )
188
+ for _ , producer := range producers {
189
+ _ , found := results [ producer . peerInfo . id ]
190
+ if found == false {
191
+ results [ producer . peerInfo . id ] = struct {}{}
192
+ retProducers = append ( retProducers , producer )
193
+ }
225
194
}
226
195
}
227
- }
228
196
229
- r .cachedFindProducersResults .Set (cachedKey , retProducers , cache .DefaultExpiration )
197
+ return true
198
+ })
199
+
200
+ r .RUnlock ()
230
201
231
202
return retProducers
232
203
}
233
204
234
205
func (r * RegistrationDB ) LookupRegistrations (id string ) Registrations {
235
206
r .RLock ()
236
- defer r . RUnlock ()
207
+
237
208
results := Registrations {}
238
- for k , producers := range r .registrationMap {
209
+ r .registrationMap .Range (func (k , v interface {}) bool {
210
+ producers := v .(ProducerMap )
239
211
if _ , exists := producers [id ]; exists {
240
- results = append (results , k )
212
+ results = append (results , k .( Registration ) )
241
213
}
242
- }
214
+
215
+ return true
216
+ })
217
+
218
+ r .RUnlock ()
219
+
243
220
return results
244
221
}
245
222
0 commit comments