diff --git a/cache.go b/cache.go index becf4c6..09ababd 100644 --- a/cache.go +++ b/cache.go @@ -116,6 +116,13 @@ func (c *Cache) Get(key string) *Item { return item } +// Same as Get but does not promote the value. This essentially circumvents the +// "least recently used" aspect of this cache. To some degree, it's akin to a +// "peak" +func (c *Cache) GetWithoutPromote(key string) *Item { + return c.bucket(key).get(key) +} + // Used when the cache was created with the Track() configuration option. // Avoid otherwise func (c *Cache) TrackingGet(key string) TrackedItem { diff --git a/cache_test.go b/cache_test.go index c59153f..c8cd027 100644 --- a/cache_test.go +++ b/cache_test.go @@ -144,6 +144,20 @@ func (_ CacheTests) PromotedItemsDontGetPruned() { Expect(cache.Get("11").Value()).To.Equal(11) } +func (_ CacheTests) GetWithoutPromoteDoesNotPromote() { + cache := New(Configure().ItemsToPrune(10).GetsPerPromote(1)) + for i := 0; i < 500; i++ { + cache.Set(strconv.Itoa(i), i, time.Minute) + } + cache.SyncUpdates() + cache.GetWithoutPromote("9") + cache.SyncUpdates() + cache.GC() + Expect(cache.Get("9")).To.Equal(nil) + Expect(cache.Get("10").Value()).To.Equal(10) + Expect(cache.Get("11").Value()).To.Equal(11) +} + func (_ CacheTests) TrackerDoesNotCleanupHeldInstance() { cache := New(Configure().ItemsToPrune(11).Track()) item0 := cache.TrackingSet("0", 0, time.Minute) diff --git a/layeredcache.go b/layeredcache.go index 51b1f21..bd23d20 100644 --- a/layeredcache.go +++ b/layeredcache.go @@ -76,6 +76,13 @@ func (c *LayeredCache) Get(primary, secondary string) *Item { return item } +// Same as Get but does not promote the value. This essentially circumvents the +// "least recently used" aspect of this cache. To some degree, it's akin to a +// "peak" +func (c *LayeredCache) GetWithoutPromote(primary, secondary string) *Item { + return c.bucket(primary).get(primary, secondary) +} + func (c *LayeredCache) ForEachFunc(primary string, matches func(key string, item *Item) bool) { c.bucket(primary).forEachFunc(primary, matches) } diff --git a/layeredcache_test.go b/layeredcache_test.go index 2fa12fa..081d64b 100644 --- a/layeredcache_test.go +++ b/layeredcache_test.go @@ -194,6 +194,20 @@ func (_ LayeredCacheTests) PromotedItemsDontGetPruned() { Expect(cache.Get("11", "a").Value()).To.Equal(11) } +func (_ LayeredCacheTests) GetWithoutPromoteDoesNotPromote() { + cache := Layered(Configure().ItemsToPrune(10).GetsPerPromote(1)) + for i := 0; i < 500; i++ { + cache.Set(strconv.Itoa(i), "a", i, time.Minute) + } + cache.SyncUpdates() + cache.GetWithoutPromote("9", "a") + cache.SyncUpdates() + cache.GC() + Expect(cache.Get("9", "a")).To.Equal(nil) + Expect(cache.Get("10", "a").Value()).To.Equal(10) + Expect(cache.Get("11", "a").Value()).To.Equal(11) +} + func (_ LayeredCacheTests) TrackerDoesNotCleanupHeldInstance() { cache := Layered(Configure().ItemsToPrune(10).Track()) item0 := cache.TrackingSet("0", "a", 0, time.Minute) diff --git a/readme.md b/readme.md index b45a487..9fe41ef 100644 --- a/readme.md +++ b/readme.md @@ -69,6 +69,9 @@ The returned `*Item` exposes a number of methods: By returning expired items, CCache lets you decide if you want to serve stale content or not. For example, you might decide to serve up slightly stale content (< 30 seconds old) while re-fetching newer data in the background. You might also decide to serve up infinitely stale content if you're unable to get new data from your source. +### GetWithoutPromote +Same as `Get` but does not "promote" the value, which is to say it circumvents the "lru" aspect of this cache. Should only be used in limited cases, such as peaking at the value. + ### Set `Set` expects the key, value and ttl: