1
- // AUTO-GENERATED by cmap-gen
2
- // DO NOT EDIT"
3
- // generated from github.com/OneOfOne/cmap/internal/cmap
1
+ // This file was automatically generated by genx.
2
+ // Any changes will be lost if this file is regenerated.
3
+ // see https://github.com/OneOfOne/genx
4
+ // command: genx -pkg ./internal/cmap -t KT=interface{} -t VT=interface{} -m -o ./cmap.go
4
5
5
6
package cmap
6
7
7
8
import (
8
9
"context"
9
10
"sync"
11
+
12
+ "github.com/OneOfOne/cmap/hashers"
10
13
)
11
14
15
+ // DefaultShardCount is the default number of shards to use when New() or NewFromJSON() are called. The default is 256.
16
+ const DefaultShardCount = 1 << 8
17
+
12
18
// CMap is a concurrent safe sharded map to scale on multiple cores.
13
19
type CMap struct {
14
20
shards []* LMap
15
21
keysPool sync.Pool
16
- // HashFn allows using a custom hash function that's used to determain the key's shard.
17
- // Defaults to DefaultKeyHasher.
22
+ // HashFn allows using a custom hash function that's used to determain the key's shard. Defaults to DefaultKeyHasher.
18
23
HashFn func (interface {}) uint32
19
24
}
20
25
@@ -31,17 +36,22 @@ func NewSize(shardCount int) *CMap {
31
36
} else if shardCount & (shardCount - 1 ) != 0 {
32
37
panic ("shardCount must be a power of 2" )
33
38
}
39
+
34
40
cm := & CMap {
35
41
shards : make ([]* LMap , shardCount ),
36
42
HashFn : DefaultKeyHasher ,
37
43
}
44
+
38
45
cm .keysPool .New = func () interface {} {
39
46
out := make ([]interface {}, 0 , DefaultShardCount ) // good starting round
40
- return & out // return a ptr to avoid extra allocation on Get/Put
47
+
48
+ return & out // return a ptr to avoid extra allocation on Get/Put
41
49
}
50
+
42
51
for i := range cm .shards {
43
52
cm .shards [i ] = NewLMapSize (shardCount )
44
53
}
54
+
45
55
return cm
46
56
}
47
57
@@ -58,7 +68,7 @@ func (cm *CMap) Set(key interface{}, val interface{}) {
58
68
}
59
69
60
70
// SetIfNotExists will only assign val to key if it wasn't already set.
61
- // Use `CMap. Update` if you need more logic.
71
+ // Use `Update` if you need more logic.
62
72
func (cm * CMap ) SetIfNotExists (key interface {}, val interface {}) (set bool ) {
63
73
h := cm .HashFn (key )
64
74
return cm .shards [h & uint32 (len (cm .shards )- 1 )].SetIfNotExists (key , val )
@@ -122,12 +132,14 @@ func (cm *CMap) Keys() []interface{} {
122
132
func (cm * CMap ) ForEach (fn func (key interface {}, val interface {}) bool ) bool {
123
133
keysP := cm .keysPool .Get ().(* []interface {})
124
134
defer cm .keysPool .Put (keysP )
135
+
125
136
for _ , lm := range cm .shards {
126
137
keys := (* keysP )[:0 ]
127
138
if ! lm .ForEach (keys , fn ) {
128
139
return false
129
140
}
130
141
}
142
+
131
143
return false
132
144
}
133
145
@@ -140,6 +152,7 @@ func (cm *CMap) ForEachLocked(fn func(key interface{}, val interface{}) bool) bo
140
152
return false
141
153
}
142
154
}
155
+
143
156
return true
144
157
}
145
158
@@ -192,6 +205,7 @@ func (cm *CMap) iterContext(ctx context.Context, ch chan<- *KV, locked bool) {
192
205
return true
193
206
}
194
207
}
208
+
195
209
if locked {
196
210
_ = cm .ForEachLocked (fn )
197
211
} else {
@@ -202,6 +216,9 @@ func (cm *CMap) iterContext(ctx context.Context, ch chan<- *KV, locked bool) {
202
216
// NumShards returns the number of shards in the map.
203
217
func (cm * CMap ) NumShards () int { return len (cm .shards ) }
204
218
219
+ // DefaultKeyHasher is an alias for hashers.TypeHasher32(key).
220
+ func DefaultKeyHasher (key interface {}) uint32 { return hashers .TypeHasher32 (key ) }
221
+
205
222
// LMap is a simple sync.RWMutex locked map.
206
223
// Used by CMap internally for sharding.
207
224
type LMap struct {
@@ -214,7 +231,7 @@ func NewLMap() *LMap {
214
231
return NewLMapSize (0 )
215
232
}
216
233
217
- // NewLMapSize is the equivalent of `m := make(map[interface{}]interface{} , cap)`
234
+ // NewLMapSize is the equivalent of `m := make(map[KT]VT , cap)`
218
235
func NewLMapSize (cap int ) * LMap {
219
236
return & LMap {
220
237
m : make (map [interface {}]interface {}, cap ),
@@ -306,6 +323,7 @@ func (lm *LMap) ForEach(keys []interface{}, fn func(key interface{}, val interfa
306
323
keys = append (keys , key )
307
324
}
308
325
lm .l .RUnlock ()
326
+
309
327
for _ , key := range keys {
310
328
lm .l .RLock ()
311
329
val , ok := lm .m [key ]
@@ -317,6 +335,7 @@ func (lm *LMap) ForEach(keys []interface{}, fn func(key interface{}, val interfa
317
335
return false
318
336
}
319
337
}
338
+
320
339
return true
321
340
}
322
341
@@ -326,11 +345,13 @@ func (lm *LMap) ForEach(keys []interface{}, fn func(key interface{}, val interfa
326
345
func (lm * LMap ) ForEachLocked (fn func (key interface {}, val interface {}) bool ) bool {
327
346
lm .l .RLock ()
328
347
defer lm .l .RUnlock ()
348
+
329
349
for key , val := range lm .m {
330
350
if ! fn (key , val ) {
331
351
return false
332
352
}
333
353
}
354
+
334
355
return true
335
356
}
336
357
0 commit comments