added atomic list-append operation

This commit is contained in:
Stefan Geisbacher 2018-12-09 16:47:30 +01:00
parent 5633e08626
commit dfba5f289e
2 changed files with 68 additions and 0 deletions

View File

@ -81,6 +81,27 @@ func (c *cache) set(k string, x interface{}, d time.Duration) {
}
}
func (c *cache) Append(k string, x string) error {
c.mu.Lock()
v, found := c.items[k]
if !found || v.Expired() {
c.mu.Unlock()
return fmt.Errorf("Item %q not found", k)
}
rv, ok := v.Object.([]string)
if !ok {
c.mu.Unlock()
return fmt.Errorf("The value for %s is not an []string", k)
}
nv := append(rv, x)
v.Object = nv
c.items[k] = v
// TODO: Calls to mu.Unlock are currently not deferred because defer
// adds ~200 ns (as of go1.)
c.mu.Unlock()
return nil
}
// Add an item to the cache, replacing any existing item, using the default
// expiration.
func (c *cache) SetDefault(k string, x interface{}) {

View File

@ -68,6 +68,53 @@ func TestCache(t *testing.T) {
}
}
func TestAppend(t *testing.T) {
tc := New(NoExpiration, 0)
tc.Set("label1", []string{}, NoExpiration)
tc.Set("label2", []string{}, NoExpiration)
tc.Set("label3", []string{}, NoExpiration)
tc.Append("label1", "article1")
tc.Append("label1", "article2")
tc.Append("label2", "article1")
tc.Append("label2", "article3")
tc.Append("label2", "article4")
tc.Append("label3", "article2")
label1Articles, found := tc.Get("label1")
if !found {
t.Error("could not find key 'label1' after appending")
}
label2Articles, found := tc.Get("label2")
if !found {
t.Error("could not find key 'label2' after appending")
}
label3Articles, found := tc.Get("label3")
if !found {
t.Error("could not find key 'label3' after appending")
}
if l := len(label1Articles.([]string)); l != 2 {
t.Errorf("'label1' should have 2 articles but has: %d", l)
}
if l := len(label2Articles.([]string)); l != 3 {
t.Errorf("'label2' should have 3 articles but has: %d", l)
}
if l := len(label3Articles.([]string)); l != 1 {
t.Errorf("'label3' should have 1 articles but has: %d", l)
}
if v := label2Articles.([]string)[0]; v != "article1" {
t.Errorf("first article of label2 should be article1, but is: %s", v)
}
if v := label2Articles.([]string)[1]; v != "article3" {
t.Errorf("second article of label2 should be article3, but is: %s", v)
}
if v := label2Articles.([]string)[2]; v != "article4" {
t.Errorf("third article of label2 should be article4, but is: %s", v)
}
}
func TestCacheTimes(t *testing.T) {
var found bool