41 lines
		
	
	
		
			551 B
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			41 lines
		
	
	
		
			551 B
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								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()
							 | 
						||
| 
								 | 
							
								}
							 |