add TrackingSet to LayeredCache
This commit is contained in:
parent
f3b2b9fd88
commit
0dbf3f125f
4 changed files with 19 additions and 11 deletions
|
@ -38,7 +38,7 @@ func (b *layeredBucket) getSecondaryBucket(primary string) *bucket {
|
|||
return bucket
|
||||
}
|
||||
|
||||
func (b *layeredBucket) set(primary, secondary string, value interface{}, duration time.Duration) (*Item, *Item) {
|
||||
func (b *layeredBucket) set(primary, secondary string, value interface{}, duration time.Duration, track bool) (*Item, *Item) {
|
||||
b.Lock()
|
||||
bkt, exists := b.buckets[primary]
|
||||
if exists == false {
|
||||
|
@ -46,7 +46,7 @@ func (b *layeredBucket) set(primary, secondary string, value interface{}, durati
|
|||
b.buckets[primary] = bkt
|
||||
}
|
||||
b.Unlock()
|
||||
item, existing := bkt.set(secondary, value, duration, false)
|
||||
item, existing := bkt.set(secondary, value, duration, track)
|
||||
item.group = primary
|
||||
return item, existing
|
||||
}
|
||||
|
|
|
@ -102,9 +102,14 @@ func (c *LayeredCache) TrackingGet(primary, secondary string) TrackedItem {
|
|||
return item
|
||||
}
|
||||
|
||||
// Set the value in the cache for the specified duration
|
||||
func (c *LayeredCache) TrackingSet(primary, secondary string, value interface{}, duration time.Duration) TrackedItem {
|
||||
return c.set(primary, secondary, value, duration, true)
|
||||
}
|
||||
|
||||
// Set the value in the cache for the specified duration
|
||||
func (c *LayeredCache) Set(primary, secondary string, value interface{}, duration time.Duration) {
|
||||
c.set(primary, secondary, value, duration)
|
||||
c.set(primary, secondary, value, duration, false)
|
||||
}
|
||||
|
||||
// Replace the value if it exists, does not set if it doesn't.
|
||||
|
@ -131,7 +136,7 @@ func (c *LayeredCache) Fetch(primary, secondary string, duration time.Duration,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.set(primary, secondary, value, duration), nil
|
||||
return c.set(primary, secondary, value, duration, false), nil
|
||||
}
|
||||
|
||||
// Remove the item from the cache, return true if the item was present, false otherwise.
|
||||
|
@ -193,8 +198,8 @@ func (c *LayeredCache) restart() {
|
|||
go c.worker()
|
||||
}
|
||||
|
||||
func (c *LayeredCache) set(primary, secondary string, value interface{}, duration time.Duration) *Item {
|
||||
item, existing := c.bucket(primary).set(primary, secondary, value, duration)
|
||||
func (c *LayeredCache) set(primary, secondary string, value interface{}, duration time.Duration, track bool) *Item {
|
||||
item, existing := c.bucket(primary).set(primary, secondary, value, duration, track)
|
||||
if existing != nil {
|
||||
c.deletables <- existing
|
||||
}
|
||||
|
|
|
@ -196,17 +196,20 @@ func (_ LayeredCacheTests) PromotedItemsDontGetPruned() {
|
|||
|
||||
func (_ LayeredCacheTests) TrackerDoesNotCleanupHeldInstance() {
|
||||
cache := Layered(Configure().ItemsToPrune(10).Track())
|
||||
for i := 0; i < 10; i++ {
|
||||
item0 := cache.TrackingSet("0", "a", 0, time.Minute)
|
||||
for i := 1; i < 11; i++ {
|
||||
cache.Set(strconv.Itoa(i), "a", i, time.Minute)
|
||||
}
|
||||
item := cache.TrackingGet("0", "a")
|
||||
item1 := cache.TrackingGet("1", "a")
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
gcLayeredCache(cache)
|
||||
Expect(cache.Get("0", "a").Value()).To.Equal(0)
|
||||
Expect(cache.Get("1", "a")).To.Equal(nil)
|
||||
item.Release()
|
||||
Expect(cache.Get("1", "a").Value()).To.Equal(1)
|
||||
item0.Release()
|
||||
item1.Release()
|
||||
gcLayeredCache(cache)
|
||||
Expect(cache.Get("0", "a")).To.Equal(nil)
|
||||
Expect(cache.Get("1", "a")).To.Equal(nil)
|
||||
}
|
||||
|
||||
func (_ LayeredCacheTests) RemovesOldestItemWhenFull() {
|
||||
|
|
|
@ -143,7 +143,7 @@ user := item.Value() //will be nil if "user:4" didn't exist in the cache
|
|||
item.Release() //can be called even if item.Value() returned nil
|
||||
```
|
||||
|
||||
In practice, `Release` wouldn't be called until later, at some other place in your code.
|
||||
In practice, `Release` wouldn't be called until later, at some other place in your code. `TrackingSet` can be used to set a value to be tracked.
|
||||
|
||||
There's a couple reason to use the tracking mode if other parts of your code also hold references to objects. First, if you're already going to hold a reference to these objects, there's really no reason not to have them in the cache - the memory is used up anyways.
|
||||
|
||||
|
|
Loading…
Reference in a new issue