sm
/
cache
1
0
Fork 0

added delete on bst

This commit is contained in:
Giuseppe 2015-12-01 09:07:03 +01:00
parent c11107bf02
commit 9e28bbffcf
2 changed files with 50 additions and 31 deletions

View File

@ -65,25 +65,25 @@ func (c *cache) Set(k string, x interface{}, d time.Duration) {
c.mu.Unlock() c.mu.Unlock()
} }
func (c *cache) set(k string, x interface{}, d time.Duration) { func (c *cache) set(k string, x interface{}, d time.Duration) {
e := emptyTime item := Item{
Object: x,
Key : k,
}
if d == DefaultExpiration { if d == DefaultExpiration {
d = c.defaultExpiration d = c.defaultExpiration
} }
if d > 0 { if d > 0 {
e = time.Now().Add(d) item.Expiration = time.Now().Add(d)
} //if an item with the same key exists in the cache, remove it from the bst
item := Item{ old, found := c.items[k]
Object: x, if found {
Expiration: e, c.sortedItems.Delete(old)
Key : k, c.sortedItems.InsertNoReplace(item)
} }
//if an item with the same key exists in the cache, remove it from the bst } else {
old, found := c.items[k] item.Expiration = emptyTime
if found { }
c.sortedItems.Delete(old)
c.sortedItems.InsertNoReplace(item)
}
c.items[k] = item c.items[k] = item
} }
@ -144,6 +144,9 @@ func (c *cache) Increment(k string, n int64) error {
c.mu.Unlock() c.mu.Unlock()
return fmt.Errorf("Item %s not found", k) return fmt.Errorf("Item %s not found", k)
} }
if v.Expiration != emptyTime {
c.sortedItems.Delete(v)
}
switch v.Object.(type) { switch v.Object.(type) {
case int: case int:
v.Object = v.Object.(int) + int(n) v.Object = v.Object.(int) + int(n)
@ -176,6 +179,9 @@ func (c *cache) Increment(k string, n int64) error {
return fmt.Errorf("The value for %s is not an integer", k) return fmt.Errorf("The value for %s is not an integer", k)
} }
c.items[k] = v c.items[k] = v
if v.Expiration != emptyTime {
c.sortedItems.InsertNoReplace(v)
}
c.mu.Unlock() c.mu.Unlock()
return nil return nil
} }
@ -875,27 +881,25 @@ func (c *cache) delete(k string) (interface{}, bool) {
return nil, false return nil, false
} }
type keyAndValue struct {
key string
value interface{}
}
// Delete all expired items from the cache. // Delete all expired items from the cache.
func (c *cache) DeleteExpired() { func (c *cache) DeleteExpired() {
var evictedItems []keyAndValue var evictedItems []Item
c.mu.Lock() c.mu.Lock()
for k, v := range c.items { c.sortedItems.DescendLessOrEqual(Item{Expiration: time.Now()}, func(i llrb.Item) bool {
if v.Expired() { v := i.(Item)
ov, evicted := c.delete(k) c.delete(v.Key)
if evicted { evictedItems = append(evictedItems, v)
evictedItems = append(evictedItems, keyAndValue{k, ov}) return true
} })
}
}
c.mu.Unlock()
for _, v := range evictedItems { for _, v := range evictedItems {
c.onEvicted(v.key, v.value) c.sortedItems.Delete(v)
} }
c.mu.Unlock()
for _, v := range evictedItems {
if c.onEvicted != nil {
c.onEvicted(v.Key, v.Object)
}
}
} }
// Sets an (optional) function that is called with the key and value when an // Sets an (optional) function that is called with the key and value when an

View File

@ -1615,3 +1615,18 @@ func BenchmarkDeleteExpired(b *testing.B) {
tc.DeleteExpired() tc.DeleteExpired()
} }
} }
func BenchmarkLargeCache(b *testing.B) {
b.StopTimer()
tc := New(200 * time.Millisecond, 50 * time.Millisecond)
//tc.mu.Lock()
for i := 0; i < 100000; i++ {
tc.set(strconv.Itoa(i), "bar", DefaultExpiration)
}
//tc.mu.Unlock()
tc.DeleteExpired()
b.StartTimer()
for i := 100000; i <100000 + b.N; i++ {
tc.set(strconv.Itoa(i), "bar", DefaultExpiration)
}
}