Skip to content

Commit 4c5d25a

Browse files
committed
[orcaman#136] Add custom shard count value in concurrent map
1 parent 85296bc commit 4c5d25a

File tree

1 file changed

+21
-14
lines changed

1 file changed

+21
-14
lines changed

concurrent_map.go

+21-14
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ type Stringer interface {
1616
// A "thread" safe map of type string:Anything.
1717
// To avoid lock bottlenecks this map is dived to several (SHARD_COUNT) map shards.
1818
type ConcurrentMap[K comparable, V any] struct {
19-
shards []*ConcurrentMapShared[K, V]
20-
sharding func(key K) uint32
19+
shards []*ConcurrentMapShared[K, V]
20+
sharding func(key K) uint32
21+
shardCount uint32
2122
}
2223

2324
// A "thread" safe string to anything map.
@@ -26,35 +27,41 @@ type ConcurrentMapShared[K comparable, V any] struct {
2627
sync.RWMutex // Read Write mutex, guards access to internal map.
2728
}
2829

29-
func create[K comparable, V any](sharding func(key K) uint32) ConcurrentMap[K, V] {
30+
func create[K comparable, V any](sharding func(key K) uint32, shardCount uint32) ConcurrentMap[K, V] {
3031
m := ConcurrentMap[K, V]{
31-
sharding: sharding,
32-
shards: make([]*ConcurrentMapShared[K, V], SHARD_COUNT),
32+
sharding: sharding,
33+
shards: make([]*ConcurrentMapShared[K, V], shardCount),
34+
shardCount: shardCount,
3335
}
34-
for i := 0; i < SHARD_COUNT; i++ {
36+
for i := 0; i < int(m.shardCount); i++ {
3537
m.shards[i] = &ConcurrentMapShared[K, V]{items: make(map[K]V)}
3638
}
3739
return m
3840
}
3941

4042
// Creates a new concurrent map.
4143
func New[V any]() ConcurrentMap[string, V] {
42-
return create[string, V](fnv32)
44+
return create[string, V](fnv32, uint32(SHARD_COUNT))
4345
}
4446

4547
// Creates a new concurrent map.
4648
func NewStringer[K Stringer, V any]() ConcurrentMap[K, V] {
47-
return create[K, V](strfnv32[K])
49+
return create[K, V](strfnv32[K], uint32(SHARD_COUNT))
4850
}
4951

5052
// Creates a new concurrent map.
5153
func NewWithCustomShardingFunction[K comparable, V any](sharding func(key K) uint32) ConcurrentMap[K, V] {
52-
return create[K, V](sharding)
54+
return create[K, V](sharding, uint32(SHARD_COUNT))
55+
}
56+
57+
// NewWithCustomShardingCountFunction Create a new concurrent map using the given shardCount
58+
func NewWithCustomShardingCountFunction[K comparable, V any](sharding func(key K) uint32, shardCount uint32) ConcurrentMap[K, V] {
59+
return create[K, V](sharding, shardCount)
5360
}
5461

5562
// GetShard returns shard under given key
5663
func (m ConcurrentMap[K, V]) GetShard(key K) *ConcurrentMapShared[K, V] {
57-
return m.shards[uint(m.sharding(key))%uint(SHARD_COUNT)]
64+
return m.shards[uint(m.sharding(key))%uint(m.shardCount)]
5865
}
5966

6067
func (m ConcurrentMap[K, V]) MSet(data map[K]V) {
@@ -119,7 +126,7 @@ func (m ConcurrentMap[K, V]) Get(key K) (V, bool) {
119126
// Count returns the number of elements within the map.
120127
func (m ConcurrentMap[K, V]) Count() int {
121128
count := 0
122-
for i := 0; i < SHARD_COUNT; i++ {
129+
for i := 0; i < int(m.shardCount); i++ {
123130
shard := m.shards[i]
124131
shard.RLock()
125132
count += len(shard.items)
@@ -228,9 +235,9 @@ func snapshot[K comparable, V any](m ConcurrentMap[K, V]) (chans []chan Tuple[K,
228235
if len(m.shards) == 0 {
229236
panic(`cmap.ConcurrentMap is not initialized. Should run New() before usage.`)
230237
}
231-
chans = make([]chan Tuple[K, V], SHARD_COUNT)
238+
chans = make([]chan Tuple[K, V], m.shardCount)
232239
wg := sync.WaitGroup{}
233-
wg.Add(SHARD_COUNT)
240+
wg.Add(int(m.shardCount))
234241
// Foreach shard.
235242
for index, shard := range m.shards {
236243
go func(index int, shard *ConcurrentMapShared[K, V]) {
@@ -303,7 +310,7 @@ func (m ConcurrentMap[K, V]) Keys() []K {
303310
go func() {
304311
// Foreach shard.
305312
wg := sync.WaitGroup{}
306-
wg.Add(SHARD_COUNT)
313+
wg.Add(int(m.shardCount))
307314
for _, shard := range m.shards {
308315
go func(shard *ConcurrentMapShared[K, V]) {
309316
// Foreach key, value pair.

0 commit comments

Comments
 (0)