edge/pkg/storage/driver/cache/lfu/synchronizer.go

57 lines
957 B
Go

package lfu
import (
"sync"
"github.com/pkg/errors"
)
type Synchronizer[K comparable] struct {
index *Map[K, *sync.RWMutex]
}
func (s *Synchronizer[K]) Remove(key K) {
s.index.Delete(key)
}
func (s *Synchronizer[K]) ReadTx(key K, fn func(upgrade func(fn func())) error) error {
mutex, _ := s.index.GetOrSet(key, &sync.RWMutex{})
mutex.RLock()
defer mutex.RUnlock()
upgrade := func(fn func()) {
mutex.RUnlock()
mutex.Lock()
defer func() {
mutex.Unlock()
mutex.RLock()
}()
fn()
}
if err := fn(upgrade); err != nil {
return errors.WithStack(err)
}
return nil
}
func (s *Synchronizer[K]) WriteTx(key K, fn func() error) error {
mutex, _ := s.index.GetOrSet(key, &sync.RWMutex{})
mutex.Lock()
defer mutex.Unlock()
if err := fn(); err != nil {
return errors.WithStack(err)
}
return nil
}
func NewSynchronizer[K comparable]() *Synchronizer[K] {
return &Synchronizer[K]{
index: NewMap[K, *sync.RWMutex](),
}
}