diff --git a/cache_test.go b/cache_test.go index 8d0893f..9b486fe 100644 --- a/cache_test.go +++ b/cache_test.go @@ -210,6 +210,33 @@ func TestFlush(t *testing.T) { } } +func TestDeleteAll(t *testing.T) { + table := Cache("testDeleteAll") + called := false + + table.SetAboutToDeleteItemCallback(func(item *CacheItem) { + called = true + }) + + table.Add(k, 10*time.Second, v) + // flush the entire table + table.DeleteAll() + + if !called { + t.Fail() + } + + // try to retrieve the item + p, err := table.Value(k) + if err == nil || p != nil { + t.Error("Error flushing table") + } + // make sure there's really nothing else left in the cache + if table.Count() != 0 { + t.Error("Error verifying count of flushed table") + } +} + func TestCount(t *testing.T) { // add a huge amount of items to the cache table := Cache("testCount") @@ -233,6 +260,8 @@ func TestCount(t *testing.T) { } func TestDataLoader(t *testing.T) { + called := 0 + // setup a cache with a configured data-loader table := Cache("testDataLoader") table.SetDataLoader(func(key interface{}, args ...interface{}) *CacheItem { @@ -240,6 +269,9 @@ func TestDataLoader(t *testing.T) { if key.(string) != "nil" { val := k + key.(string) i := NewCacheItem(key, 500*time.Millisecond, val) + i.SetAboutToExpireCallback(func(key interface{}) { + called++ + }) item = i } @@ -260,6 +292,12 @@ func TestDataLoader(t *testing.T) { if err != nil || p == nil || p.Data().(string) != vp { t.Error("Error validating data loader") } + + table.Delete(key) + } + + if called != 10 { + t.Fail() } } diff --git a/cachetable.go b/cachetable.go index 3952bbe..593b885 100644 --- a/cachetable.go +++ b/cachetable.go @@ -172,6 +172,13 @@ func (table *CacheTable) Add(key interface{}, lifeSpan time.Duration, data inter return item } +func (table *CacheTable) addItem(item *CacheItem) *CacheItem { + table.Lock() + table.addInternal(item) + + return item +} + func (table *CacheTable) deleteInternal(key interface{}) (*CacheItem, error) { r, ok := table.items[key] if !ok { @@ -253,7 +260,7 @@ func (table *CacheTable) Value(key interface{}, args ...interface{}) (*CacheItem if loadData != nil { item := loadData(key, args...) if item != nil { - table.Add(key, item.lifeSpan, item.data) + table.addItem(item) return item, nil } @@ -277,6 +284,26 @@ func (table *CacheTable) Flush() { } } +// DeleteAll deletes all items from this cache table and call aboutToDeleteItem,aboutToExpire +func (table *CacheTable) DeleteAll() { + table.Foreach(func(key interface{}, item *CacheItem) { + // Trigger callbacks before deleting an item from cache. + if table.aboutToDeleteItem != nil { + table.aboutToDeleteItem(item) + } + + item.RLock() + defer item.RUnlock() + if item.aboutToExpire != nil { + item.aboutToExpire(key) + } + }) + + table.log("Remove all table", table.name) + + table.Flush() +} + // CacheItemPair maps key to access counter type CacheItemPair struct { Key interface{} @@ -327,5 +354,5 @@ func (table *CacheTable) log(v ...interface{}) { return } - table.logger.Println(v) + table.logger.Println(v...) }