-
Notifications
You must be signed in to change notification settings - Fork 0
/
bidimap.go
56 lines (49 loc) · 1.2 KB
/
bidimap.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package ipcall
import "sync"
// BidiMap is a concurrency-safe, bidirectional map implementation (allowing
// lookups by either key or value). NOTE: a BidiMap should only be used when
// there exists a bijection (one-to-one mapping) between the keys.
//
// The current implementaion builds on Go's `map` primitive, maintaining two
// maps (one for key and the other for value lookup). Synchronization is
// performed using a `sync.RWMutex`.
type BidiMap struct {
mu *sync.RWMutex
kv map[string]string
vk map[string]string
}
func NewBidiMap(initSize int) *BidiMap {
if initSize < 0 {
initSize = 0
}
return &BidiMap{
kv: make(map[string]string, initSize),
vk: make(map[string]string, initSize),
}
}
func (m *BidiMap) Add(key, val string) {
m.mu.Lock()
defer m.mu.Unlock()
m.kv[key] = val
m.kv[val] = key
}
func (m *BidiMap) GetByKey(key string) (string, bool) {
m.mu.RLock()
defer m.mu.RUnlock()
v, ok := m.kv[key]
return v, ok
}
func (m *BidiMap) GetByVal(val string) (string, bool) {
m.mu.RLock()
defer m.mu.RUnlock()
k, ok := m.vk[val]
return k, ok
}
func (m *BidiMap) Delete(key string) {
m.mu.Lock()
defer m.mu.Unlock()
if val, ok := m.kv[key]; ok {
delete(m.kv, key)
delete(m.vk, val)
}
}