optimize locks for sinterstore/sunionstore/sdiffstore

This commit is contained in:
hdt3213
2021-05-27 22:06:57 +08:00
parent f1455534d4
commit 6ee2789d6f
3 changed files with 54 additions and 15 deletions

View File

@@ -126,3 +126,41 @@ func (locks *Locks) RUnLocks(keys ...string) {
mu.RUnlock() mu.RUnlock()
} }
} }
func (locks *Locks) RWLocks(writeKeys []string, readKeys []string) {
keys := append(writeKeys, readKeys...)
indices := locks.toLockIndices(keys, false)
writeIndices := locks.toLockIndices(writeKeys, false)
writeIndexSet := make(map[uint32]struct{})
for _, idx := range writeIndices {
writeIndexSet[idx] = struct{}{}
}
for _, index := range indices {
_, w := writeIndexSet[index]
mu := locks.table[index]
if w {
mu.Lock()
} else {
mu.RLock()
}
}
}
func (locks *Locks) RWUnLocks(writeKeys []string, readKeys []string) {
keys := append(writeKeys, readKeys...)
indices := locks.toLockIndices(keys, true)
writeIndices := locks.toLockIndices(writeKeys, true)
writeIndexSet := make(map[uint32]struct{})
for _, idx := range writeIndices {
writeIndexSet[idx] = struct{}{}
}
for _, index := range indices {
_, w := writeIndexSet[index]
mu := locks.table[index]
if w {
mu.Unlock()
} else {
mu.RUnlock()
}
}
}

10
db.go
View File

@@ -220,6 +220,16 @@ func (db *DB) RUnLocks(keys ...string) {
db.locker.RUnLocks(keys...) db.locker.RUnLocks(keys...)
} }
// RWLocks lock keys for writing and reading
func (db *DB) RWLocks(writeKeys []string, readKeys []string) {
db.locker.RWLocks(writeKeys, readKeys)
}
// RWUnLocks unlock keys for writing and reading
func (db *DB) RWUnLocks(writeKeys []string, readKeys []string) {
db.locker.RWUnLocks(writeKeys, readKeys)
}
/* ---- TTL Functions ---- */ /* ---- TTL Functions ---- */
func genExpireTask(key string) string { func genExpireTask(key string) string {

21
set.go
View File

@@ -208,11 +208,8 @@ func execSInterStore(db *DB, args [][]byte) redis.Reply {
} }
// lock // lock
lockedKeySet := HashSet.Make(keys...) db.RWLocks([]string{dest}, keys)
lockedKeySet.Add(dest) defer db.RWUnLocks([]string{dest}, keys)
lockedKeys := lockedKeySet.ToSlice()
db.Locks(lockedKeys...)
defer db.UnLocks(lockedKeys...)
var result *HashSet.Set var result *HashSet.Set
for _, key := range keys { for _, key := range keys {
@@ -299,11 +296,8 @@ func execSUnionStore(db *DB, args [][]byte) redis.Reply {
} }
// lock // lock
lockedKeySet := HashSet.Make(keys...) db.RWLocks([]string{dest}, keys)
lockedKeySet.Add(dest) defer db.RWUnLocks([]string{dest}, keys)
lockedKeys := lockedKeySet.ToSlice()
db.Locks(lockedKeys...)
defer db.UnLocks(lockedKeys...)
var result *HashSet.Set var result *HashSet.Set
for _, key := range keys { for _, key := range keys {
@@ -397,11 +391,8 @@ func execSDiffStore(db *DB, args [][]byte) redis.Reply {
} }
// lock // lock
lockedKeySet := HashSet.Make(keys...) db.RWLocks([]string{dest}, keys)
lockedKeySet.Add(dest) defer db.RWUnLocks([]string{dest}, keys)
lockedKeys := lockedKeySet.ToSlice()
db.Locks(lockedKeys...)
defer db.UnLocks(lockedKeys...)
var result *HashSet.Set var result *HashSet.Set
for i, key := range keys { for i, key := range keys {