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{}{}} 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 type StringItem string
func (item StringItem) Key() string { func (item StringItem) Key() string {

View File

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

View File

@ -21,10 +21,16 @@ func TestSetExpiring(t *testing.T) {
t.Error("not len 1 after set") 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() { if !item.Expired() {
t.Errorf("ExpiringItem a nanosec ago is not expiring") 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)} item = &ExpiringItem{nil, time.Now().Add(time.Minute * 5)}
if item.Expired() { if item.Expired() {