set: AddNew vs Add, added Rename

This commit is contained in:
Andrey Petrov 2016-09-07 15:33:24 -04:00
parent 91718a511b
commit 810ef13bea
3 changed files with 53 additions and 18 deletions

View File

@ -29,6 +29,20 @@ func Keyize(key string) Item {
return &item{key, struct{}{}}
}
type renamedItem struct {
Item
key string
}
func (item *renamedItem) Key() string {
return item.key
}
// Rename item to a new key, same underlying value.
func Rename(item Item, key string) Item {
return &renamedItem{Item: item, key: key}
}
type StringItem string
func (item StringItem) Key() string {

View File

@ -55,6 +55,7 @@ func (s *Set) In(key string) bool {
s.RUnlock()
if ok && item.Value() == nil {
s.cleanup(key)
ok = false
}
return ok
}
@ -66,12 +67,13 @@ func (s *Set) Get(key string) (Item, error) {
item, ok := s.lookup[key]
s.RUnlock()
if ok && item.Value() == nil {
s.cleanup(key)
ok = false
}
if !ok {
return nil, ErrMissing
}
if item.Value() == nil {
s.cleanup(key)
}
return item, nil
}
@ -87,10 +89,7 @@ func (s *Set) cleanup(key string) {
}
// Add item to this set if it does not exist already.
func (s *Set) Add(item Item) error {
if item.Value() == nil {
return ErrNil
}
func (s *Set) AddNew(item Item) error {
key := s.normalize(item.Key())
s.Lock()
@ -101,7 +100,26 @@ func (s *Set) Add(item Item) error {
return ErrCollision
}
s.lookup[key] = item
if item.Value() == nil {
delete(s.lookup, key)
} else {
s.lookup[key] = item
}
return nil
}
// Add to set, replacing if item already exists.
func (s *Set) Add(item Item) error {
key := s.normalize(item.Key())
s.Lock()
defer s.Unlock()
if item.Value() == nil {
delete(s.lookup, key)
} else {
s.lookup[key] = item
}
return nil
}
@ -123,9 +141,6 @@ func (s *Set) Remove(key string) error {
// Replace oldKey with a new item, which might be a new key.
// Can be used to rename items.
func (s *Set) Replace(oldKey string, item Item) error {
if item.Value() == nil {
return ErrNil
}
newKey := s.normalize(item.Key())
oldKey = s.normalize(oldKey)
@ -140,15 +155,15 @@ func (s *Set) Replace(oldKey string, item Item) error {
}
// Remove oldKey
_, found = s.lookup[oldKey]
if !found {
return ErrMissing
}
delete(s.lookup, oldKey)
}
// Add new item
s.lookup[newKey] = item
if item.Value() == nil {
delete(s.lookup, newKey)
} else {
// Add new item
s.lookup[newKey] = item
}
return nil
}

View File

@ -21,10 +21,16 @@ func TestSetExpiring(t *testing.T) {
t.Error("not len 1 after set")
}
item := &ExpiringItem{nil, time.Now().Add(-time.Nanosecond * 1)}
item := &ExpiringItem{StringItem("expired"), time.Now().Add(-time.Nanosecond * 1)}
if !item.Expired() {
t.Errorf("ExpiringItem a nanosec ago is not expiring")
}
if err := s.Add(item); err != nil {
t.Fatalf("failed to add item: %s", err)
}
if s.In("expired") {
t.Errorf("expired item is present")
}
item = &ExpiringItem{nil, time.Now().Add(time.Minute * 5)}
if item.Expired() {