diff --git a/cache.go b/cache.go index 9082808..ec83a76 100644 --- a/cache.go +++ b/cache.go @@ -17,6 +17,10 @@ type setMaxSize struct { size int64 } +type clear struct { + done chan struct{} +} + type Cache struct { *Configuration list *list.List @@ -146,13 +150,11 @@ func (c *Cache) Delete(key string) bool { return false } -//this isn't thread safe. It's meant to be called from non-concurrent tests +// Clears the cache func (c *Cache) Clear() { - for _, bucket := range c.buckets { - bucket.clear() - } - c.size = 0 - c.list = list.New() + done := make(chan struct{}) + c.control <- clear{done: done} + <-done } // Stops the background worker. Operations performed on the cache after Stop @@ -231,6 +233,13 @@ func (c *Cache) worker() { if c.size > c.maxSize { dropped += c.gc() } + case clear: + for _, bucket := range c.buckets { + bucket.clear() + } + c.size = 0 + c.list = list.New() + msg.done <- struct{}{} } } } diff --git a/layeredcache.go b/layeredcache.go index 2a846df..40f7123 100644 --- a/layeredcache.go +++ b/layeredcache.go @@ -164,13 +164,11 @@ func (c *LayeredCache) DeleteFunc(primary string, matches func(key string, item return c.bucket(primary).deleteFunc(primary, matches, c.deletables) } -//this isn't thread safe. It's meant to be called from non-concurrent tests +// Clears the cache func (c *LayeredCache) Clear() { - for _, bucket := range c.buckets { - bucket.clear() - } - c.size = 0 - c.list = list.New() + done := make(chan struct{}) + c.control <- clear{done: done} + <-done } func (c *LayeredCache) Stop() { @@ -249,6 +247,13 @@ func (c *LayeredCache) worker() { if c.size > c.maxSize { dropped += c.gc() } + case clear: + for _, bucket := range c.buckets { + bucket.clear() + } + c.size = 0 + c.list = list.New() + msg.done <- struct{}{} } } } diff --git a/readme.md b/readme.md index 8efbe45..47a8bc2 100644 --- a/readme.md +++ b/readme.md @@ -100,7 +100,7 @@ cache.Delete("user:4") `DeleteFunc` deletes all items that the provded matches func evaluates to true. Returns the number of keys removed. ### Clear -`Clear` clears the cache. This method is **not** thread safe. It is meant to be used from tests. +`Clear` clears the cache. If the cache's gc is running, `Clear` waits for it to finish. ### Extend The life of an item can be changed via the `Extend` method. This will change the expiry of the item by the specified duration relative to the current time.