v0.0.615 MultiMutex
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m55s
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m55s
This commit is contained in:
93
dataext/multiMutex.go
Normal file
93
dataext/multiMutex.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package dataext
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MultiMutex is a simple map[key -> mutex]
|
||||
type MultiMutex[TKey comparable] struct {
|
||||
mutextMap *SyncMap[TKey, *CASMutex]
|
||||
}
|
||||
|
||||
func NewMultiMutex[TKey comparable]() *MultiMutex[TKey] {
|
||||
return &MultiMutex[TKey]{
|
||||
mutextMap: NewSyncMap[TKey, *CASMutex](),
|
||||
}
|
||||
}
|
||||
|
||||
// TryLockWithContext attempts to acquire the lock, blocking until resources
|
||||
// are available or ctx is done (timeout or cancellation).
|
||||
func (mm *MultiMutex[TKey]) TryLockWithContext(ctx context.Context, key TKey) bool {
|
||||
lck := mm.mutextMap.GetAndSetIfNotContainsFunc(key, NewCASMutex)
|
||||
return lck.TryLockWithContext(ctx)
|
||||
}
|
||||
|
||||
// Lock acquires the lock.
|
||||
// If it is currently held by others, Lock will wait until it has a chance to acquire it.
|
||||
func (mm *MultiMutex[TKey]) Lock(key TKey) {
|
||||
lck := mm.mutextMap.GetAndSetIfNotContainsFunc(key, NewCASMutex)
|
||||
lck.Lock()
|
||||
}
|
||||
|
||||
// TryLock attempts to acquire the lock without blocking.
|
||||
// Return false if someone is holding it now.
|
||||
func (mm *MultiMutex[TKey]) TryLock(key TKey) bool {
|
||||
lck := mm.mutextMap.GetAndSetIfNotContainsFunc(key, NewCASMutex)
|
||||
return lck.TryLock()
|
||||
}
|
||||
|
||||
// TryLockWithTimeout attempts to acquire the lock within a period of time.
|
||||
// Return false if spending time is more than duration and no chance to acquire it.
|
||||
func (mm *MultiMutex[TKey]) TryLockWithTimeout(key TKey, duration time.Duration) bool {
|
||||
lck := mm.mutextMap.GetAndSetIfNotContainsFunc(key, NewCASMutex)
|
||||
return lck.TryLockWithTimeout(duration)
|
||||
}
|
||||
|
||||
// Unlock releases the lock.
|
||||
func (mm *MultiMutex[TKey]) Unlock(key TKey) {
|
||||
lck := mm.mutextMap.GetAndSetIfNotContainsFunc(key, NewCASMutex)
|
||||
lck.Unlock()
|
||||
}
|
||||
|
||||
// RTryLockWithContext attempts to acquire the read lock, blocking until resources
|
||||
// are available or ctx is done (timeout or cancellation).
|
||||
func (mm *MultiMutex[TKey]) RTryLockWithContext(ctx context.Context, key TKey) bool {
|
||||
lck := mm.mutextMap.GetAndSetIfNotContainsFunc(key, NewCASMutex)
|
||||
return lck.RTryLockWithContext(ctx)
|
||||
}
|
||||
|
||||
// RLock acquires the read lock.
|
||||
// If it is currently held by others writing, RLock will wait until it has a chance to acquire it.
|
||||
func (mm *MultiMutex[TKey]) RLock(key TKey) {
|
||||
lck := mm.mutextMap.GetAndSetIfNotContainsFunc(key, NewCASMutex)
|
||||
lck.RLock()
|
||||
}
|
||||
|
||||
// RTryLock attempts to acquire the read lock without blocking.
|
||||
// Return false if someone is writing it now.
|
||||
func (mm *MultiMutex[TKey]) RTryLock(key TKey) bool {
|
||||
lck := mm.mutextMap.GetAndSetIfNotContainsFunc(key, NewCASMutex)
|
||||
return lck.RTryLock()
|
||||
}
|
||||
|
||||
// RTryLockWithTimeout attempts to acquire the read lock within a period of time.
|
||||
// Return false if spending time is more than duration and no chance to acquire it.
|
||||
func (mm *MultiMutex[TKey]) RTryLockWithTimeout(duration time.Duration, key TKey) bool {
|
||||
lck := mm.mutextMap.GetAndSetIfNotContainsFunc(key, NewCASMutex)
|
||||
return lck.RTryLockWithTimeout(duration)
|
||||
}
|
||||
|
||||
// RUnlock releases the read lock.
|
||||
func (mm *MultiMutex[TKey]) RUnlock(key TKey) {
|
||||
lck := mm.mutextMap.GetAndSetIfNotContainsFunc(key, NewCASMutex)
|
||||
lck.RUnlock()
|
||||
}
|
||||
|
||||
// RLocker returns a Locker interface that implements the Lock and Unlock methods
|
||||
// by calling CASMutex.RLock and CASMutex.RUnlock.
|
||||
func (mm *MultiMutex[TKey]) RLocker(key TKey) sync.Locker {
|
||||
lck := mm.mutextMap.GetAndSetIfNotContainsFunc(key, NewCASMutex)
|
||||
return lck.RLocker()
|
||||
}
|
||||
Reference in New Issue
Block a user