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
|
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()
|
b.Lock()
|
||||||
bkt, exists := b.buckets[primary]
|
bkt, exists := b.buckets[primary]
|
||||||
if exists == false {
|
if exists == false {
|
||||||
|
@ -46,7 +46,7 @@ func (b *layeredBucket) set(primary, secondary string, value interface{}, durati
|
||||||
b.buckets[primary] = bkt
|
b.buckets[primary] = bkt
|
||||||
}
|
}
|
||||||
b.Unlock()
|
b.Unlock()
|
||||||
item, existing := bkt.set(secondary, value, duration, false)
|
item, existing := bkt.set(secondary, value, duration, track)
|
||||||
item.group = primary
|
item.group = primary
|
||||||
return item, existing
|
return item, existing
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,9 +102,14 @@ func (c *LayeredCache) TrackingGet(primary, secondary string) TrackedItem {
|
||||||
return item
|
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
|
// Set the value in the cache for the specified duration
|
||||||
func (c *LayeredCache) Set(primary, secondary string, value interface{}, duration time.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.
|
// 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 {
|
if err != nil {
|
||||||
return nil, err
|
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.
|
// 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()
|
go c.worker()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *LayeredCache) set(primary, secondary string, value interface{}, duration time.Duration) *Item {
|
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)
|
item, existing := c.bucket(primary).set(primary, secondary, value, duration, track)
|
||||||
if existing != nil {
|
if existing != nil {
|
||||||
c.deletables <- existing
|
c.deletables <- existing
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,17 +196,20 @@ func (_ LayeredCacheTests) PromotedItemsDontGetPruned() {
|
||||||
|
|
||||||
func (_ LayeredCacheTests) TrackerDoesNotCleanupHeldInstance() {
|
func (_ LayeredCacheTests) TrackerDoesNotCleanupHeldInstance() {
|
||||||
cache := Layered(Configure().ItemsToPrune(10).Track())
|
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)
|
cache.Set(strconv.Itoa(i), "a", i, time.Minute)
|
||||||
}
|
}
|
||||||
item := cache.TrackingGet("0", "a")
|
item1 := cache.TrackingGet("1", "a")
|
||||||
time.Sleep(time.Millisecond * 10)
|
time.Sleep(time.Millisecond * 10)
|
||||||
gcLayeredCache(cache)
|
gcLayeredCache(cache)
|
||||||
Expect(cache.Get("0", "a").Value()).To.Equal(0)
|
Expect(cache.Get("0", "a").Value()).To.Equal(0)
|
||||||
Expect(cache.Get("1", "a")).To.Equal(nil)
|
Expect(cache.Get("1", "a").Value()).To.Equal(1)
|
||||||
item.Release()
|
item0.Release()
|
||||||
|
item1.Release()
|
||||||
gcLayeredCache(cache)
|
gcLayeredCache(cache)
|
||||||
Expect(cache.Get("0", "a")).To.Equal(nil)
|
Expect(cache.Get("0", "a")).To.Equal(nil)
|
||||||
|
Expect(cache.Get("1", "a")).To.Equal(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ LayeredCacheTests) RemovesOldestItemWhenFull() {
|
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
|
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.
|
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