Use RWMutex in NSMap and reduce lock area

Signed-off-by: Jin Dong <djdongjin95@gmail.com>
This commit is contained in:
Jin Dong 2023-06-09 18:21:16 +00:00
parent 78b4af74a4
commit 9e09bfb590

View File

@ -31,7 +31,7 @@ type object interface {
// NSMap extends Map type with a notion of namespaces passed via Context. // NSMap extends Map type with a notion of namespaces passed via Context.
type NSMap[T object] struct { type NSMap[T object] struct {
mu sync.Mutex mu sync.RWMutex
objects map[string]map[string]T objects map[string]map[string]T
} }
@ -44,13 +44,14 @@ func NewNSMap[T object]() *NSMap[T] {
// Get a task // Get a task
func (m *NSMap[T]) Get(ctx context.Context, id string) (T, error) { func (m *NSMap[T]) Get(ctx context.Context, id string) (T, error) {
m.mu.Lock()
defer m.mu.Unlock()
namespace, err := namespaces.NamespaceRequired(ctx) namespace, err := namespaces.NamespaceRequired(ctx)
var t T var t T
if err != nil { if err != nil {
return t, err return t, err
} }
m.mu.RLock()
defer m.mu.RUnlock()
tasks, ok := m.objects[namespace] tasks, ok := m.objects[namespace]
if !ok { if !ok {
return t, errdefs.ErrNotFound return t, errdefs.ErrNotFound
@ -64,8 +65,8 @@ func (m *NSMap[T]) Get(ctx context.Context, id string) (T, error) {
// GetAll objects under a namespace // GetAll objects under a namespace
func (m *NSMap[T]) GetAll(ctx context.Context, noNS bool) ([]T, error) { func (m *NSMap[T]) GetAll(ctx context.Context, noNS bool) ([]T, error) {
m.mu.Lock() m.mu.RLock()
defer m.mu.Unlock() defer m.mu.RUnlock()
var o []T var o []T
if noNS { if noNS {
for ns := range m.objects { for ns := range m.objects {
@ -100,10 +101,10 @@ func (m *NSMap[T]) Add(ctx context.Context, t T) error {
// AddWithNamespace adds a task with the provided namespace // AddWithNamespace adds a task with the provided namespace
func (m *NSMap[T]) AddWithNamespace(namespace string, t T) error { func (m *NSMap[T]) AddWithNamespace(namespace string, t T) error {
id := t.ID()
m.mu.Lock() m.mu.Lock()
defer m.mu.Unlock() defer m.mu.Unlock()
id := t.ID()
if _, ok := m.objects[namespace]; !ok { if _, ok := m.objects[namespace]; !ok {
m.objects[namespace] = make(map[string]T) m.objects[namespace] = make(map[string]T)
} }
@ -116,12 +117,13 @@ func (m *NSMap[T]) AddWithNamespace(namespace string, t T) error {
// Delete a task // Delete a task
func (m *NSMap[T]) Delete(ctx context.Context, id string) { func (m *NSMap[T]) Delete(ctx context.Context, id string) {
m.mu.Lock()
defer m.mu.Unlock()
namespace, err := namespaces.NamespaceRequired(ctx) namespace, err := namespaces.NamespaceRequired(ctx)
if err != nil { if err != nil {
return return
} }
m.mu.Lock()
defer m.mu.Unlock()
tasks, ok := m.objects[namespace] tasks, ok := m.objects[namespace]
if ok { if ok {
delete(tasks, id) delete(tasks, id)
@ -129,8 +131,8 @@ func (m *NSMap[T]) Delete(ctx context.Context, id string) {
} }
func (m *NSMap[T]) IsEmpty() bool { func (m *NSMap[T]) IsEmpty() bool {
m.mu.Lock() m.mu.RLock()
defer m.mu.Unlock() defer m.mu.RUnlock()
for ns := range m.objects { for ns := range m.objects {
if len(m.objects[ns]) > 0 { if len(m.objects[ns]) > 0 {