github.com/gitbookio/syncgroup@v0.0.0-20181003125046-3e73b2e6a972/sharded.go (about)

     1  package syncgroup
     2  
     3  import (
     4  	"sync"
     5  
     6  	"github.com/GitbookIO/syncgroup/quickhash"
     7  )
     8  
     9  // ShardedMutexes shards calls to a list of sync.RWMutex by key
    10  type ShardedMutexes struct {
    11  	shards []*sync.RWMutex
    12  	n      uint64
    13  }
    14  
    15  func NewShardedMutexes() *ShardedMutexes {
    16  	var n uint64 = 2048
    17  	shards := make([]*sync.RWMutex, n)
    18  	// Init shard
    19  	for idx, _ := range shards {
    20  		shards[idx] = &sync.RWMutex{}
    21  	}
    22  
    23  	return &ShardedMutexes{
    24  		shards: shards,
    25  		n:      n,
    26  	}
    27  }
    28  
    29  func (sg *ShardedMutexes) Lock(key string) {
    30  	sg.getShard(key).Lock()
    31  }
    32  
    33  func (sg *ShardedMutexes) RLock(key string) {
    34  	sg.getShard(key).RLock()
    35  }
    36  
    37  func (sg *ShardedMutexes) Unlock(key string) {
    38  	sg.getShard(key).Unlock()
    39  }
    40  
    41  func (sg *ShardedMutexes) RUnlock(key string) {
    42  	sg.getShard(key).RUnlock()
    43  }
    44  
    45  func (sg *ShardedMutexes) Locker(key string) *sync.RWMutex {
    46  	return sg.getShard(key)
    47  }
    48  
    49  func (sg *ShardedMutexes) RLocker(key string) *sync.RWMutex {
    50  	return sg.getShard(key)
    51  }
    52  
    53  func (sg *ShardedMutexes) getShard(key string) *sync.RWMutex {
    54  	hash := quickhash.StrHash(key)
    55  	return sg.shards[hash%2048]
    56  }