mirror of
https://github.com/donl/bimap.git
synced 2026-06-30 06:12:04 -06:00
Add immutability option
This commit is contained in:
parent
ac919cfb98
commit
f7fe0fd5da
3 changed files with 65 additions and 2 deletions
|
|
@ -19,5 +19,5 @@ biMap.Size() // == 0
|
|||
biMap2 := bimap.NewBiMap()
|
||||
biMap2.Insert("key", 1) // Notice different types
|
||||
val, ok := biMap2.Get("key") // Returns 1
|
||||
val, ok = biMap2.InverseGet(1) //Return "key"
|
||||
val, ok = biMap2.InverseGet(1) // Returns "key"
|
||||
```
|
||||
|
|
|
|||
27
bimap.go
27
bimap.go
|
|
@ -4,16 +4,23 @@ import "sync"
|
|||
|
||||
type biMap struct {
|
||||
s sync.RWMutex
|
||||
immutable bool
|
||||
forward map[interface{}]interface{}
|
||||
inverse map[interface{}]interface{}
|
||||
}
|
||||
|
||||
func NewBiMap() *biMap {
|
||||
return &biMap{forward: make(map[interface{}]interface{}), inverse: make(map[interface{}]interface{})}
|
||||
return &biMap{forward: make(map[interface{}]interface{}), inverse: make(map[interface{}]interface{}), immutable:false}
|
||||
}
|
||||
|
||||
|
||||
func (b *biMap) Insert(k interface{}, v interface{}) {
|
||||
b.s.RLock()
|
||||
if b.immutable {
|
||||
panic("Cannot modify immutable map")
|
||||
}
|
||||
b.s.RUnlock()
|
||||
|
||||
b.s.Lock()
|
||||
defer b.s.Unlock()
|
||||
b.forward[k] = v
|
||||
|
|
@ -56,6 +63,12 @@ func (b *biMap) InverseGet(v interface{}) (interface{}, bool) {
|
|||
}
|
||||
|
||||
func (b *biMap) Delete(k interface{}) {
|
||||
b.s.RLock()
|
||||
if b.immutable {
|
||||
panic("Cannot modify immutable map")
|
||||
}
|
||||
b.s.RUnlock()
|
||||
|
||||
if !b.Exists(k) {
|
||||
return
|
||||
}
|
||||
|
|
@ -67,6 +80,12 @@ func (b *biMap) Delete(k interface{}) {
|
|||
}
|
||||
|
||||
func (b *biMap) InverseDelete(v interface{}) {
|
||||
b.s.RLock()
|
||||
if b.immutable {
|
||||
panic("Cannot modify immutable map")
|
||||
}
|
||||
b.s.RUnlock()
|
||||
|
||||
if !b.InverseExists(v) {
|
||||
return
|
||||
}
|
||||
|
|
@ -83,4 +102,10 @@ func (b*biMap) Size() int{
|
|||
b.s.RLock()
|
||||
defer b.s.RUnlock()
|
||||
return len(b.forward)
|
||||
}
|
||||
|
||||
func (b *biMap) SetImmutable() {
|
||||
b.s.Lock()
|
||||
defer b.s.Unlock()
|
||||
b.immutable = true
|
||||
}
|
||||
|
|
@ -154,6 +154,44 @@ func TestBiMap_WithVaryingType(t *testing.T) {
|
|||
|
||||
}
|
||||
|
||||
func TestBiMap_SetImmutable(t *testing.T) {
|
||||
actual := NewBiMap()
|
||||
dummyKey := "Dummy key"
|
||||
dummyVal := 3
|
||||
|
||||
actual.Insert(dummyKey, dummyVal)
|
||||
|
||||
actual.SetImmutable()
|
||||
|
||||
assert.Panics(t, func() {
|
||||
actual.Delete(dummyKey)
|
||||
}, "It should panic on a mutation operation")
|
||||
|
||||
val, _ := actual.Get(dummyKey)
|
||||
|
||||
assert.Equal(t, dummyVal, val, "It should still have the value")
|
||||
|
||||
assert.Panics(t, func() {
|
||||
actual.InverseDelete(dummyVal)
|
||||
}, "It should panic on a mutation operation")
|
||||
|
||||
key, _ := actual.InverseGet(dummyVal)
|
||||
|
||||
assert.Equal(t, dummyKey, key, "It should still have the key")
|
||||
|
||||
size := actual.Size()
|
||||
|
||||
assert.Equal(t, 1, size, "Size should be one")
|
||||
|
||||
assert.Panics(t, func() {
|
||||
actual.Insert("New", 1)
|
||||
}, "It should panic on a mutation operation")
|
||||
|
||||
size = actual.Size()
|
||||
|
||||
assert.Equal(t, 1, size, "Size should be one")
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue