Skip to content

Commit

Permalink
Merge pull request #11 from spekary/RemoveSetChanged
Browse files Browse the repository at this point in the history
Some interfaces are not comparable, so SetChanged will not work on them.
  • Loading branch information
spekary authored Aug 7, 2019
2 parents a8ba763 + 9c71237 commit 8d2c703
Show file tree
Hide file tree
Showing 18 changed files with 299 additions and 246 deletions.
21 changes: 2 additions & 19 deletions pkg/maps/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,26 +47,7 @@ func (o *Map) Clear() {
o.items = nil
}

// SetChanged sets the key to the value and returns a boolean indicating whether doing this caused
// the map to change. It will return true if the key did not first exist, or if the value associated
// with the key was different than the new value.
func (o *Map) SetChanged(key string, val interface{}) (changed bool) {
var ok bool
var oldVal interface{}

if o == nil {
panic("The map must be created before being used.")
}
if o.items == nil {
o.items = make(map[string]interface{})
}

if oldVal, ok = o.items[key]; !ok || oldVal != val {
o.items[key] = val
changed = true
}
return
}

// Set sets the key to the given value
func (o *Map) Set(key string, val interface{}) {
Expand Down Expand Up @@ -159,6 +140,8 @@ func (o *Map) Has(key string) (exists bool) {
return
}



// Values returns a slice of the values. It will return a nil slice if the map is empty.
// Multiple calls to Values will result in the same list of values, but may be in a different order.
func (o *Map) Values() (vals []interface{}) {
Expand Down
25 changes: 0 additions & 25 deletions pkg/maps/map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,6 @@ func TestMap(t *testing.T) {
t.Error("Set after clear failed.")
}

m.Clear()
m.SetChanged("E", 15.5)
if m.Get("E") != 15.5 {
t.Error("SetChanged after clear failed.")
}

n := m.Copy()
if n.Get("E") != 15.5 {
t.Error("Copy failed.")
Expand Down Expand Up @@ -133,25 +127,6 @@ func TestEmpty(t *testing.T) {

}

func TestMapChange(t *testing.T) {
m := NewMap()

m.Set("B", "This")
m.Set("A", "That")
m.Set("C", 5)

if changed := m.SetChanged("D", 6); !changed {
t.Error("Set did not produce a change flag")
}

if changed := m.SetChanged("D", 6); changed {
t.Error("Set again erroneously produced a change flag")
}

if changed := m.SetChanged("D", "That"); !changed {
t.Error("Set again did not produce a change flag")
}
}

func TestMapNotEqual(t *testing.T) {
m := NewMap()
Expand Down
23 changes: 2 additions & 21 deletions pkg/maps/safemap.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,28 +52,7 @@ func (o *SafeMap) Clear() {
o.Unlock()
}

// SetChanged sets the key to the value and returns a boolean indicating whether doing this caused
// the map to change. It will return true if the key did not first exist, or if the value associated
// with the key was different than the new value.
func (o *SafeMap) SetChanged(key string, val interface{}) (changed bool) {
var ok bool
var oldVal interface{}

if o == nil {
panic("The map must be created before being used.")
}
o.Lock()
if o.items == nil {
o.items = make(map[string]interface{})
}

if oldVal, ok = o.items[key]; !ok || oldVal != val {
o.items[key] = val
changed = true
}
o.Unlock()
return
}

// Set sets the key to the given value
func (o *SafeMap) Set(key string, val interface{}) {
Expand Down Expand Up @@ -174,6 +153,8 @@ func (o *SafeMap) Has(key string) (exists bool) {
return
}



// Values returns a slice of the values. It will return a nil slice if the map is empty.
// Multiple calls to Values will result in the same list of values, but may be in a different order.
func (o *SafeMap) Values() (vals []interface{}) {
Expand Down
25 changes: 0 additions & 25 deletions pkg/maps/safemap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,6 @@ func TestSafeMap(t *testing.T) {
t.Error("Set after clear failed.")
}

m.Clear()
m.SetChanged("E", 15.5)
if m.Get("E") != 15.5 {
t.Error("SetChanged after clear failed.")
}

n := m.Copy()
if n.Get("E") != 15.5 {
t.Error("Copy failed.")
Expand Down Expand Up @@ -133,25 +127,6 @@ func TestSafeEmpty(t *testing.T) {

}

func TestSafeMapChange(t *testing.T) {
m := NewSafeMap()

m.Set("B", "This")
m.Set("A", "That")
m.Set("C", 5)

if changed := m.SetChanged("D", 6); !changed {
t.Error("Set did not produce a change flag")
}

if changed := m.SetChanged("D", 6); changed {
t.Error("Set again erroneously produced a change flag")
}

if changed := m.SetChanged("D", "That"); !changed {
t.Error("Set again did not produce a change flag")
}
}

func TestSafeMapNotEqual(t *testing.T) {
m := NewSafeMap()
Expand Down
64 changes: 28 additions & 36 deletions pkg/maps/safeslicemap.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,11 @@ func keySortSafeSliceMap(key1, key2 string, val1, val2 interface{}) bool {



// SetChanged sets the value.
// It returns true if something in the map changed. If the key
// was already in the map, and you have not provided a sort function,
// the order will not change, but the value will be replaced. If you wanted the
// order to change, you must Delete then call SetChanged. If you have previously set a sort function,
// the order will be updated.
func (o *SafeSliceMap) SetChanged(key string, val interface{}) (changed bool) {


// Set sets the given key to the given value.
// If the key already exists, the range order will not change.
func (o *SafeSliceMap) Set(key string, val interface{}) {
var ok bool
var oldVal interface{}

Expand All @@ -101,42 +99,34 @@ func (o *SafeSliceMap) SetChanged(key string, val interface{}) (changed bool) {
o.items = make(map[string]interface{})
}

if oldVal, ok = o.items[key]; !ok || oldVal != val {
if o.lessF != nil {
if ok {
// delete old key location
loc := sort.Search (len(o.items), func(n int) bool {
return !o.lessF(o.order[n], key, o.items[o.order[n]], oldVal)
})
o.order = append(o.order[:loc], o.order[loc+1:]...)
}

loc := sort.Search (len(o.order), func(n int) bool {
return o.lessF(key, o.order[n], val, o.items[o.order[n]])
_, ok = o.items[key]
if o.lessF != nil {
if ok {
// delete old key location
loc := sort.Search (len(o.items), func(n int) bool {
return !o.lessF(o.order[n], key, o.items[o.order[n]], oldVal)
})
// insert
o.order = append(o.order[:loc], o.order[loc+1:]...)
}

loc := sort.Search (len(o.order), func(n int) bool {
return o.lessF(key, o.order[n], val, o.items[o.order[n]])
})
// insert
o.order = append(o.order, key)
copy(o.order[loc+1:], o.order[loc:])
o.order[loc] = key
} else {
if !ok {
o.order = append(o.order, key)
copy(o.order[loc+1:], o.order[loc:])
o.order[loc] = key
} else {
if !ok {
o.order = append(o.order, key)
}
}
o.items[key] = val
changed = true
}
}
}
o.items[key] = val
o.Unlock()

return
}

// Set sets the given key to the given value.
// If the key already exists, the range order will not change.
func (o *SafeSliceMap) Set(key string, val interface{}) {
o.SetChanged(key, val)
}

// SetAt sets the given key to the given value, but also inserts it at the index specified. If the index is bigger than
// the length, it puts it at the end. Negative indexes are backwards from the end.
func (o *SafeSliceMap) SetAt(index int, key string, val interface{}) {
Expand Down Expand Up @@ -272,6 +262,8 @@ func (o *SafeSliceMap) Has(key string) (ok bool) {
return
}



// GetAt returns the value based on its position. If the position is out of bounds, an empty value is returned.
func (o *SafeSliceMap) GetAt(position int) (val interface{}) {
if o == nil {
Expand Down
19 changes: 1 addition & 18 deletions pkg/maps/safeslicemap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@ func TestSafeSliceMap(t *testing.T) {
t.Error("MapI interface test failed.")
}

if changed := m.SetChanged("F", 9); !changed {
t.Error("Add non-string value failed.")
}
m.Set("F", 9)
if m.Get("F") != 9 {
t.Error("Add non-string value failed.")
}
Expand All @@ -73,21 +71,6 @@ func TestSafeSliceMap(t *testing.T) {

}

func TestSafeSliceMapChange(t *testing.T) {
m := new (SafeSliceMap)

m.Set("B", "This")
m.Set("A", "That")
m.Set("C", "Other")

if changed := m.SetChanged("D", "And another"); !changed {
t.Error("Set did not produce a change flag")
}

if changed := m.SetChanged("D", "And another"); changed {
t.Error("Set again erroneously produced a change flag")
}
}

func ExampleSafeSliceMap_Range() {
m := new (SafeSliceMap)
Expand Down
19 changes: 19 additions & 0 deletions pkg/maps/safestrmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func (o *SafeStringMap) Clear() {
o.Unlock()
}


// SetChanged sets the key to the value and returns a boolean indicating whether doing this caused
// the map to change. It will return true if the key did not first exist, or if the value associated
// with the key was different than the new value.
Expand All @@ -75,6 +76,7 @@ func (o *SafeStringMap) SetChanged(key string, val string) (changed bool) {
return
}


// Set sets the key to the given value
func (o *SafeStringMap) Set(key string, val string) {
if o == nil {
Expand Down Expand Up @@ -138,6 +140,23 @@ func (o *SafeStringMap) Has(key string) (exists bool) {
return
}


// Is returns true if the given key exists in the map and has the given value.
func (o *SafeStringMap) Is(key string, val string) (is bool) {
if o == nil {
return
}

var v string
o.RLock()
if o.items != nil {
v, is = o.items[key]
}
o.RUnlock()
return is && v == val
}


// Values returns a slice of the values. It will return a nil slice if the map is empty.
// Multiple calls to Values will result in the same list of values, but may be in a different order.
func (o *SafeStringMap) Values() (vals []string) {
Expand Down
58 changes: 57 additions & 1 deletion pkg/maps/safestrslicemap.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ func valueSortSafeStringSliceMap(key1, key2 string, val1, val2 string) bool {
}



// SetChanged sets the value.
// It returns true if something in the map changed. If the key
// was already in the map, and you have not provided a sort function,
Expand Down Expand Up @@ -140,10 +141,48 @@ func (o *SafeStringSliceMap) SetChanged(key string, val string) (changed bool) {
return
}


// Set sets the given key to the given value.
// If the key already exists, the range order will not change.
func (o *SafeStringSliceMap) Set(key string, val string) {
o.SetChanged(key, val)
var ok bool
var oldVal string

if o == nil {
panic("You must initialize the map before using it.")
}
o.Lock()

if o.items == nil {
o.items = make(map[string]string)
}

_, ok = o.items[key]
if o.lessF != nil {
if ok {
// delete old key location
loc := sort.Search (len(o.items), func(n int) bool {
return !o.lessF(o.order[n], key, o.items[o.order[n]], oldVal)
})
o.order = append(o.order[:loc], o.order[loc+1:]...)
}

loc := sort.Search (len(o.order), func(n int) bool {
return o.lessF(key, o.order[n], val, o.items[o.order[n]])
})
// insert
o.order = append(o.order, key)
copy(o.order[loc+1:], o.order[loc:])
o.order[loc] = key
} else {
if !ok {
o.order = append(o.order, key)
}
}
o.items[key] = val
o.Unlock()

return
}

// SetAt sets the given key to the given value, but also inserts it at the index specified. If the index is bigger than
Expand Down Expand Up @@ -245,6 +284,23 @@ func (o *SafeStringSliceMap) Has(key string) (ok bool) {
return
}


// Is returns true if the given key exists in the map and has the given value.
func (o *SafeStringSliceMap) Is(key string, val string) (is bool) {
if o == nil {
return
}

var v string
o.RLock()
if o.items != nil {
v, is = o.items[key]
}
o.RUnlock()
return is && v == val
}


// GetAt returns the value based on its position. If the position is out of bounds, an empty value is returned.
func (o *SafeStringSliceMap) GetAt(position int) (val string) {
if o == nil {
Expand Down
Loading

0 comments on commit 8d2c703

Please sign in to comment.