package lockkey

import (
	"fmt"
	"sync"
)

type LockByKey struct {
	m map[string]*sync.RWMutex
	l sync.Mutex
}

func NewLockByKey() *LockByKey {
	return &LockByKey{m: make(map[string]*sync.RWMutex)}
}

func (lk *LockByKey) Lock(key string) {
	lk.l.Lock()
	defer lk.l.Unlock()

	mu, ok := lk.m[key]
	if !ok {
		mu = &sync.RWMutex{}
		lk.m[key] = mu
	}

	mu.Lock()
}

func (lk *LockByKey) Unlock(key string) {
	lk.l.Lock()
	defer lk.l.Unlock()

	mu, ok := lk.m[key]
	if !ok {
		panic(fmt.Sprintf("unlock non-existent key: %v", key))
	}

	mu.Unlock()
}
