1
1
// This file was automatically generated by genx.
2
2
// Any changes will be lost if this file is regenerated.
3
3
// see https://github.com/OneOfOne/genx
4
- // cmd: genx -pkg github.com/OneOfOne/cmap -v -t KT=interface{},VT=interface{} -m -o ./cmap_iface_iface.go
4
+ // cmd: genx -pkg github.com/OneOfOne/cmap -v -m - t KT=interface{},VT=interface{} -o ./cmap_iface_iface.go
5
5
// +build !genx
6
6
7
7
package cmap
@@ -20,8 +20,6 @@ const DefaultShardCount = 1 << 8
20
20
type CMap struct {
21
21
shards []* LMap
22
22
keysPool sync.Pool
23
- // HashFn allows using a custom hash function that's used to determain the key's shard. Defaults to DefaultKeyHasher.
24
- HashFn func (interface {}) uint32
25
23
}
26
24
27
25
// New is an alias for NewSize(DefaultShardCount)
@@ -40,7 +38,6 @@ func NewSize(shardCount int) *CMap {
40
38
41
39
cm := & CMap {
42
40
shards : make ([]* LMap , shardCount ),
43
- HashFn : DefaultKeyHasher ,
44
41
}
45
42
46
43
cm .keysPool .New = func () interface {} {
@@ -58,63 +55,63 @@ func NewSize(shardCount int) *CMap {
58
55
59
56
// ShardForKey returns the LMap that may hold the specific key.
60
57
func (cm * CMap ) ShardForKey (key interface {}) * LMap {
61
- h := cm . HashFn (key )
58
+ h := hasher (key )
62
59
return cm .shards [h & uint32 (len (cm .shards )- 1 )]
63
60
}
64
61
65
62
// Set is the equivalent of `map[key] = val`.
66
63
func (cm * CMap ) Set (key interface {}, val interface {}) {
67
- h := cm . HashFn (key )
64
+ h := hasher (key )
68
65
cm .shards [h & uint32 (len (cm .shards )- 1 )].Set (key , val )
69
66
}
70
67
71
68
// SetIfNotExists will only assign val to key if it wasn't already set.
72
69
// Use `Update` if you need more logic.
73
70
func (cm * CMap ) SetIfNotExists (key interface {}, val interface {}) (set bool ) {
74
- h := cm . HashFn (key )
71
+ h := hasher (key )
75
72
return cm .shards [h & uint32 (len (cm .shards )- 1 )].SetIfNotExists (key , val )
76
73
}
77
74
78
75
// Get is the equivalent of `val := map[key]`.
79
76
func (cm * CMap ) Get (key interface {}) (val interface {}) {
80
- h := cm . HashFn (key )
77
+ h := hasher (key )
81
78
return cm .shards [h & uint32 (len (cm .shards )- 1 )].Get (key )
82
79
}
83
80
84
81
// GetOK is the equivalent of `val, ok := map[key]`.
85
82
func (cm * CMap ) GetOK (key interface {}) (val interface {}, ok bool ) {
86
- h := cm . HashFn (key )
83
+ h := hasher (key )
87
84
return cm .shards [h & uint32 (len (cm .shards )- 1 )].GetOK (key )
88
85
}
89
86
90
87
// Has is the equivalent of `_, ok := map[key]`.
91
88
func (cm * CMap ) Has (key interface {}) bool {
92
- h := cm . HashFn (key )
89
+ h := hasher (key )
93
90
return cm .shards [h & uint32 (len (cm .shards )- 1 )].Has (key )
94
91
}
95
92
96
93
// Delete is the equivalent of `delete(map, key)`.
97
94
func (cm * CMap ) Delete (key interface {}) {
98
- h := cm . HashFn (key )
95
+ h := hasher (key )
99
96
cm .shards [h & uint32 (len (cm .shards )- 1 )].Delete (key )
100
97
}
101
98
102
99
// DeleteAndGet is the equivalent of `oldVal := map[key]; delete(map, key)`.
103
100
func (cm * CMap ) DeleteAndGet (key interface {}) interface {} {
104
- h := cm . HashFn (key )
101
+ h := hasher (key )
105
102
return cm .shards [h & uint32 (len (cm .shards )- 1 )].DeleteAndGet (key )
106
103
}
107
104
108
105
// Update calls `fn` with the key's old value (or nil) and assign the returned value to the key.
109
106
// The shard containing the key will be locked, it is NOT safe to call other cmap funcs inside `fn`.
110
107
func (cm * CMap ) Update (key interface {}, fn func (oldval interface {}) (newval interface {})) {
111
- h := cm . HashFn (key )
108
+ h := hasher (key )
112
109
cm .shards [h & uint32 (len (cm .shards )- 1 )].Update (key , fn )
113
110
}
114
111
115
112
// Swap is the equivalent of `oldVal, map[key] = map[key], newVal`.
116
113
func (cm * CMap ) Swap (key interface {}, val interface {}) interface {} {
117
- h := cm . HashFn (key )
114
+ h := hasher (key )
118
115
return cm .shards [h & uint32 (len (cm .shards )- 1 )].Swap (key , val )
119
116
}
120
117
@@ -166,6 +163,19 @@ func (cm *CMap) Len() int {
166
163
return ln
167
164
}
168
165
166
+ // ShardDistribution returns the distribution of data amoung all shards.
167
+ // Useful for debugging the efficiency of a hash.
168
+ func (cm * CMap ) ShardDistribution () []float64 {
169
+ var (
170
+ out = make ([]float64 , len (cm .shards ))
171
+ ln = float64 (cm .Len ())
172
+ )
173
+ for i := range out {
174
+ out [i ] = float64 (cm .shards [i ].Len ()) / ln
175
+ }
176
+ return out
177
+ }
178
+
169
179
// KV holds the key/value returned when Iter is called.
170
180
type KV struct {
171
181
Key interface {}
@@ -217,8 +227,7 @@ func (cm *CMap) iterContext(ctx context.Context, ch chan<- *KV, locked bool) {
217
227
// NumShards returns the number of shards in the map.
218
228
func (cm * CMap ) NumShards () int { return len (cm .shards ) }
219
229
220
- // DefaultKeyHasher is an alias for hashers.TypeHasher32(key).
221
- func DefaultKeyHasher (key interface {}) uint32 { return hashers .TypeHasher32 (key ) }
230
+ func hasher (key interface {}) uint32 { return hashers .TypeHasher32 (key ) }
222
231
223
232
// LMap is a simple sync.RWMutex locked map.
224
233
// Used by CMap internally for sharding.
@@ -232,7 +241,7 @@ func NewLMap() *LMap {
232
241
return NewLMapSize (0 )
233
242
}
234
243
235
- // NewLMapSize is the equivalent of `m := make(map[KT]VT , cap)`
244
+ // NewLMapSize is the equivalent of `m := make(map[interface{}]interface{} , cap)`
236
245
func NewLMapSize (cap int ) * LMap {
237
246
return & LMap {
238
247
m : make (map [interface {}]interface {}, cap ),
0 commit comments