/
map.go
67 lines (56 loc) · 1.9 KB
/
map.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
57
58
59
60
61
62
63
64
65
66
67
package astikit
import (
"fmt"
"sync"
)
// BiMap represents a bidirectional map
type BiMap struct {
forward map[interface{}]interface{}
inverse map[interface{}]interface{}
m *sync.Mutex
}
// NewBiMap creates a new BiMap
func NewBiMap() *BiMap {
return &BiMap{
forward: make(map[interface{}]interface{}),
inverse: make(map[interface{}]interface{}),
m: &sync.Mutex{},
}
}
func (m *BiMap) get(k interface{}, i map[interface{}]interface{}) (v interface{}, ok bool) {
m.m.Lock()
defer m.m.Unlock()
v, ok = i[k]
return
}
// Get gets the value in the forward map based on the provided key
func (m *BiMap) Get(k interface{}) (interface{}, bool) { return m.get(k, m.forward) }
// GetInverse gets the value in the inverse map based on the provided key
func (m *BiMap) GetInverse(k interface{}) (interface{}, bool) { return m.get(k, m.inverse) }
// MustGet gets the value in the forward map based on the provided key and panics if key is not found
func (m *BiMap) MustGet(k interface{}) interface{} {
v, ok := m.get(k, m.forward)
if !ok {
panic(fmt.Sprintf("astikit: key %+v not found in foward map", k))
}
return v
}
// MustGetInverse gets the value in the inverse map based on the provided key and panics if key is not found
func (m *BiMap) MustGetInverse(k interface{}) interface{} {
v, ok := m.get(k, m.inverse)
if !ok {
panic(fmt.Sprintf("astikit: key %+v not found in inverse map", k))
}
return v
}
func (m *BiMap) set(k, v interface{}, f, i map[interface{}]interface{}) *BiMap {
m.m.Lock()
defer m.m.Unlock()
f[k] = v
i[v] = k
return m
}
// Set sets the value in the forward and inverse map for the provided forward key
func (m *BiMap) Set(k, v interface{}) *BiMap { return m.set(k, v, m.forward, m.inverse) }
// SetInverse sets the value in the forward and inverse map for the provided inverse key
func (m *BiMap) SetInverse(k, v interface{}) *BiMap { return m.set(k, v, m.inverse, m.forward) }