Add cache.ItemCount() intt64 API

This commit is contained in:
Karl Seguin 2019-01-26 12:33:50 +07:00
parent 692cd618b2
commit 3385784411
6 changed files with 44 additions and 1 deletions

View file

@ -10,6 +10,12 @@ type bucket struct {
lookup map[string]*Item lookup map[string]*Item
} }
func (b *bucket) itemCount() int {
b.RLock()
defer b.RUnlock()
return len(b.lookup)
}
func (b *bucket) get(key string) *Item { func (b *bucket) get(key string) *Item {
b.RLock() b.RLock()
defer b.RUnlock() defer b.RUnlock()

View file

@ -37,6 +37,14 @@ func New(config *Configuration) *Cache {
return c return c
} }
func (c *Cache) ItemCount() int {
count := 0
for _, b := range c.buckets {
count += b.itemCount()
}
return count
}
// Get an item from the cache. Returns nil if the item wasn't found. // Get an item from the cache. Returns nil if the item wasn't found.
// This can return an expired item. Use item.Expired() to see if the item // This can return an expired item. Use item.Expired() to see if the item
// is expired and item.TTL() to see how long until the item expires (which // is expired and item.TTL() to see how long until the item expires (which

View file

@ -16,15 +16,19 @@ func Test_Cache(t *testing.T) {
func (_ CacheTests) DeletesAValue() { func (_ CacheTests) DeletesAValue() {
cache := New(Configure()) cache := New(Configure())
Expect(cache.ItemCount()).To.Equal(0)
cache.Set("spice", "flow", time.Minute) cache.Set("spice", "flow", time.Minute)
cache.Set("worm", "sand", time.Minute) cache.Set("worm", "sand", time.Minute)
Expect(cache.ItemCount()).To.Equal(2)
cache.Delete("spice") cache.Delete("spice")
Expect(cache.Get("spice")).To.Equal(nil) Expect(cache.Get("spice")).To.Equal(nil)
Expect(cache.Get("worm").Value()).To.Equal("sand") Expect(cache.Get("worm").Value()).To.Equal("sand")
Expect(cache.ItemCount()).To.Equal(1)
} }
func (_ CacheTests) OnDeleteCallbackCalled() { func (_ CacheTests) OnDeleteCallbackCalled() {
onDeleteFnCalled := false onDeleteFnCalled := false
onDeleteFn := func(item *Item) { onDeleteFn := func(item *Item) {
if item.key == "spice" { if item.key == "spice" {
@ -66,6 +70,7 @@ func (_ CacheTests) GCsTheOldestItems() {
gcCache(cache) gcCache(cache)
Expect(cache.Get("9")).To.Equal(nil) Expect(cache.Get("9")).To.Equal(nil)
Expect(cache.Get("10").Value()).To.Equal(10) Expect(cache.Get("10").Value()).To.Equal(10)
Expect(cache.ItemCount()).To.Equal(490)
} }
func (_ CacheTests) PromotedItemsDontGetPruned() { func (_ CacheTests) PromotedItemsDontGetPruned() {
@ -114,6 +119,7 @@ func (_ CacheTests) RemovesOldestItemWhenFull() {
Expect(cache.Get("1")).To.Equal(nil) Expect(cache.Get("1")).To.Equal(nil)
Expect(cache.Get("2").Value()).To.Equal(2) Expect(cache.Get("2").Value()).To.Equal(2)
Expect(onDeleteFnCalled).To.Equal(true) Expect(onDeleteFnCalled).To.Equal(true)
Expect(cache.ItemCount()).To.Equal(5)
} }
func (_ CacheTests) RemovesOldestItemWhenFullBySizer() { func (_ CacheTests) RemovesOldestItemWhenFullBySizer() {

View file

@ -10,6 +10,16 @@ type layeredBucket struct {
buckets map[string]*bucket buckets map[string]*bucket
} }
func (b *layeredBucket) itemCount() int {
count := 0
b.RLock()
defer b.RUnlock()
for _, b := range b.buckets {
count += b.itemCount()
}
return count
}
func (b *layeredBucket) get(primary, secondary string) *Item { func (b *layeredBucket) get(primary, secondary string) *Item {
bucket := b.getSecondaryBucket(primary) bucket := b.getSecondaryBucket(primary)
if bucket == nil { if bucket == nil {

View file

@ -49,6 +49,14 @@ func Layered(config *Configuration) *LayeredCache {
return c return c
} }
func (c *LayeredCache) ItemCount() int {
count := 0
for _, b := range c.buckets {
count += b.itemCount()
}
return count
}
// Get an item from the cache. Returns nil if the item wasn't found. // Get an item from the cache. Returns nil if the item wasn't found.
// This can return an expired item. Use item.Expired() to see if the item // This can return an expired item. Use item.Expired() to see if the item
// is expired and item.TTL() to see how long until the item expires (which // is expired and item.TTL() to see how long until the item expires (which

View file

@ -17,6 +17,7 @@ func Test_LayeredCache(t *testing.T) {
func (_ *LayeredCacheTests) GetsANonExistantValue() { func (_ *LayeredCacheTests) GetsANonExistantValue() {
cache := newLayered() cache := newLayered()
Expect(cache.Get("spice", "flow")).To.Equal(nil) Expect(cache.Get("spice", "flow")).To.Equal(nil)
Expect(cache.ItemCount()).To.Equal(0)
} }
func (_ *LayeredCacheTests) SetANewValue() { func (_ *LayeredCacheTests) SetANewValue() {
@ -24,6 +25,7 @@ func (_ *LayeredCacheTests) SetANewValue() {
cache.Set("spice", "flow", "a value", time.Minute) cache.Set("spice", "flow", "a value", time.Minute)
Expect(cache.Get("spice", "flow").Value()).To.Equal("a value") Expect(cache.Get("spice", "flow").Value()).To.Equal("a value")
Expect(cache.Get("spice", "stop")).To.Equal(nil) Expect(cache.Get("spice", "stop")).To.Equal(nil)
Expect(cache.ItemCount()).To.Equal(1)
} }
func (_ *LayeredCacheTests) SetsMultipleValueWithinTheSameLayer() { func (_ *LayeredCacheTests) SetsMultipleValueWithinTheSameLayer() {
@ -38,6 +40,7 @@ func (_ *LayeredCacheTests) SetsMultipleValueWithinTheSameLayer() {
Expect(cache.Get("leto", "sister").Value()).To.Equal("ghanima") Expect(cache.Get("leto", "sister").Value()).To.Equal("ghanima")
Expect(cache.Get("leto", "brother")).To.Equal(nil) Expect(cache.Get("leto", "brother")).To.Equal(nil)
Expect(cache.Get("baron", "friend")).To.Equal(nil) Expect(cache.Get("baron", "friend")).To.Equal(nil)
Expect(cache.ItemCount()).To.Equal(3)
} }
func (_ *LayeredCacheTests) ReplaceDoesNothingIfKeyDoesNotExist() { func (_ *LayeredCacheTests) ReplaceDoesNothingIfKeyDoesNotExist() {
@ -51,6 +54,7 @@ func (_ *LayeredCacheTests) ReplaceUpdatesTheValue() {
cache.Set("spice", "flow", "value-a", time.Minute) cache.Set("spice", "flow", "value-a", time.Minute)
Expect(cache.Replace("spice", "flow", "value-b")).To.Equal(true) Expect(cache.Replace("spice", "flow", "value-b")).To.Equal(true)
Expect(cache.Get("spice", "flow").Value().(string)).To.Equal("value-b") Expect(cache.Get("spice", "flow").Value().(string)).To.Equal("value-b")
Expect(cache.ItemCount()).To.Equal(1)
//not sure how to test that the TTL hasn't changed sort of a sleep.. //not sure how to test that the TTL hasn't changed sort of a sleep..
} }
@ -64,6 +68,7 @@ func (_ *LayeredCacheTests) DeletesAValue() {
Expect(cache.Get("spice", "must").Value()).To.Equal("value-b") Expect(cache.Get("spice", "must").Value()).To.Equal("value-b")
Expect(cache.Get("spice", "worm")).To.Equal(nil) Expect(cache.Get("spice", "worm")).To.Equal(nil)
Expect(cache.Get("leto", "sister").Value()).To.Equal("ghanima") Expect(cache.Get("leto", "sister").Value()).To.Equal("ghanima")
Expect(cache.ItemCount()).To.Equal(2)
} }
func (_ *LayeredCacheTests) OnDeleteCallbackCalled() { func (_ *LayeredCacheTests) OnDeleteCallbackCalled() {