perf: shorten lock time & optimize map`s value type

- shorten the lock time of concurrent.go`s function "Put"
 - slightly optimize the value`s type of map concurrent.go`s function "RandomDistinctKeys" & avoid duplicate input the same map`s key

fix: uses the provided seed value to initialize the function rand, for fixing the generation of the same int in the case of multiple executions.

Limited ability, make it better~
This commit is contained in:
zhengtianyi
2022-11-09 11:13:59 +08:00
committed by finley
parent 32a9667eb6
commit fe07c8ce39

View File

@@ -5,6 +5,7 @@ import (
"math/rand" "math/rand"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time"
) )
// ConcurrentDict is thread safe map using sharding lock // ConcurrentDict is thread safe map using sharding lock
@@ -108,6 +109,7 @@ func (dict *ConcurrentDict) Put(key string, val interface{}) (result int) {
hashCode := fnv32(key) hashCode := fnv32(key)
index := dict.spread(hashCode) index := dict.spread(hashCode)
shard := dict.getShard(index) shard := dict.getShard(index)
dict.addCount()
shard.mutex.Lock() shard.mutex.Lock()
defer shard.mutex.Unlock() defer shard.mutex.Unlock()
@@ -116,7 +118,6 @@ func (dict *ConcurrentDict) Put(key string, val interface{}) (result int) {
return 0 return 0
} }
shard.m[key] = val shard.m[key] = val
dict.addCount()
return 1 return 1
} }
@@ -244,8 +245,9 @@ func (dict *ConcurrentDict) RandomKeys(limit int) []string {
shardCount := len(dict.table) shardCount := len(dict.table)
result := make([]string, limit) result := make([]string, limit)
nR := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < limit; { for i := 0; i < limit; {
shard := dict.getShard(uint32(rand.Intn(shardCount))) shard := dict.getShard(uint32(nR.Intn(shardCount)))
if shard == nil { if shard == nil {
continue continue
} }
@@ -266,16 +268,19 @@ func (dict *ConcurrentDict) RandomDistinctKeys(limit int) []string {
} }
shardCount := len(dict.table) shardCount := len(dict.table)
result := make(map[string]bool) result := make(map[string]struct{})
nR := rand.New(rand.NewSource(time.Now().UnixNano()))
for len(result) < limit { for len(result) < limit {
shardIndex := uint32(rand.Intn(shardCount)) shardIndex := uint32(nR.Intn(shardCount))
shard := dict.getShard(shardIndex) shard := dict.getShard(shardIndex)
if shard == nil { if shard == nil {
continue continue
} }
key := shard.RandomKey() key := shard.RandomKey()
if key != "" { if key != "" {
result[key] = true if _, exists := result[key]; !exists {
result[key] = struct{}{}
}
} }
} }
arr := make([]string, limit) arr := make([]string, limit)