lotus/lib/shardedmutex/shardedmutex.go
Mikers 5e5a81bf23
add go linter - "unused" (#11235)
* add go linter - "unused"

* use _ to name unused but needed padding variable

* remove unused code

* add queue test to appease unused linter

* remove unused code in test

* remove unused func

* remove unused struct identified by linter

* remove unused variable

* remove unused code

* remove unused file

* remove unused struct

* remove unused function

* remove unused observe peers function in raft

* remove unused declareFaults function

* annotate nolint:unused on needed methods
2023-09-05 12:19:43 -10:00

76 lines
1.6 KiB
Go

package shardedmutex
import (
"hash/maphash"
"sync"
)
const cacheline = 64
// padding a mutex to a cacheline improves performance as the cachelines are not contested
// name old time/op new time/op delta
// Locks-8 74.6ns ± 7% 12.3ns ± 2% -83.54% (p=0.000 n=20+18)
type paddedMutex struct {
mt sync.Mutex
_ [cacheline - 8]uint8
}
type ShardedMutex struct {
shards []paddedMutex
}
// New creates a new ShardedMutex with N shards
func New(nShards int) ShardedMutex {
if nShards < 1 {
panic("n_shards cannot be less than 1")
}
return ShardedMutex{
shards: make([]paddedMutex, nShards),
}
}
func (sm ShardedMutex) Shards() int {
return len(sm.shards)
}
func (sm ShardedMutex) Lock(shard int) {
sm.shards[shard].mt.Lock()
}
func (sm ShardedMutex) Unlock(shard int) {
sm.shards[shard].mt.Unlock()
}
func (sm ShardedMutex) GetLock(shard int) sync.Locker {
return &sm.shards[shard].mt
}
type ShardedMutexFor[K any] struct {
inner ShardedMutex
hasher func(maphash.Seed, K) uint64
seed maphash.Seed
}
func NewFor[K any](hasher func(maphash.Seed, K) uint64, nShards int) ShardedMutexFor[K] {
return ShardedMutexFor[K]{
inner: New(nShards),
hasher: hasher,
seed: maphash.MakeSeed(),
}
}
func (sm ShardedMutexFor[K]) shardFor(key K) int {
return int(sm.hasher(sm.seed, key) % uint64(len(sm.inner.shards)))
}
func (sm ShardedMutexFor[K]) Lock(key K) {
sm.inner.Lock(sm.shardFor(key))
}
func (sm ShardedMutexFor[K]) Unlock(key K) {
sm.inner.Unlock(sm.shardFor(key))
}
func (sm ShardedMutexFor[K]) GetLock(key K) sync.Locker {
return sm.inner.GetLock(sm.shardFor(key))
}