代码拉取完成,页面将自动刷新
package tlock
import (
"fmt"
"hash/crc32"
"sort"
"time"
)
const defaultKeySlotSize = 1024
type KeyLockerGroup struct {
set []*refLockSet
}
func NewKeyLockerGroup() *KeyLockerGroup {
g := new(KeyLockerGroup)
g.set = make([]*refLockSet, defaultKeySlotSize)
for i := 0; i < defaultKeySlotSize; i++ {
g.set[i] = newRefLockSet()
}
return g
}
func (g *KeyLockerGroup) getSet(key string) *refLockSet {
index := crc32.ChecksumIEEE([]byte(key)) % uint32(defaultKeySlotSize)
return g.set[index]
}
func (g *KeyLockerGroup) Lock(keys ...string) {
// use a very long timeout
b := g.LockTimeout(InfiniteTimeout, keys...)
if !b {
panic("Wait lock too long, panic")
}
}
func removeDuplicatedItems(keys ...string) []string {
if len(keys) <= 1 {
return keys
}
m := make(map[string]struct{}, len(keys))
p := make([]string, 0, len(keys))
for _, key := range keys {
if _, ok := m[key]; !ok {
m[key] = struct{}{}
p = append(p, key)
}
}
return p
}
func (g *KeyLockerGroup) LockTimeout(timeout time.Duration, keys ...string) bool {
if len(keys) == 0 {
panic("empty keys, panic")
}
// remove duplicated items
keys = removeDuplicatedItems(keys...)
// Sort keys to avoid deadlock
sort.Strings(keys)
timer := time.NewTimer(timeout)
defer timer.Stop()
grapNum := 0
for _, key := range keys {
s := g.getSet(key)
m := s.Get(key)
b := LockWithTimer(m, timer)
if !b {
s.Put(key, m)
g.Unlock(keys[0:grapNum]...)
return false
} else {
grapNum++
}
}
return true
}
func (g *KeyLockerGroup) Unlock(keys ...string) {
if len(keys) == 0 {
return
}
// remove duplicated items
keys = removeDuplicatedItems(keys...)
// Reverse Sort keys to avoid deadlock
sort.Sort(sort.Reverse(sort.StringSlice(keys)))
for _, key := range keys {
m := g.getSet(key).RawGet(key)
if m == nil {
panic(fmt.Sprintf("%s is not locked, panic", key))
}
m.Unlock()
g.getSet(key).Put(key, m)
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。