Added function GetNotExpiredItems to get all not expired items in a threadsafe manner
This commit is contained in:
parent
1881a9bccb
commit
c193f8a44d
16
cache.go
16
cache.go
|
@ -1009,6 +1009,22 @@ func (c *cache) Items() map[string]Item {
|
|||
return c.items
|
||||
}
|
||||
|
||||
// Returns all not expired items in the cache. This method is save to use with
|
||||
// an active janitor since it copies the underlying map. Therefore method is
|
||||
// costly in terms of time and memory. You can read while using this method but
|
||||
// not write. Use with caution.
|
||||
func (c *cache) GetNotExpiredItems() map[string]Item {
|
||||
retMap := make(map[string]Item, c.ItemCount())
|
||||
c.mu.RLock()
|
||||
for key, item := range c.items{
|
||||
if !item.Expired() {
|
||||
retMap[key] = item
|
||||
}
|
||||
}
|
||||
c.mu.RUnlock()
|
||||
return retMap
|
||||
}
|
||||
|
||||
// Returns the number of items in the cache. This may include items that have
|
||||
// expired, but have not yet been cleaned up. Equivalent to len(c.Items()).
|
||||
func (c *cache) ItemCount() int {
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type TestStruct struct {
|
||||
|
@ -1247,6 +1248,29 @@ func TestOnEvicted(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCacheGetAllNotExpiredItems(t *testing.T) {
|
||||
tc := New(time.Minute*1, 0)
|
||||
tc.Set("a", "a", DefaultExpiration)
|
||||
tc.Set("b", "b", DefaultExpiration)
|
||||
tc.Set("c", "c", time.Millisecond*1)
|
||||
time.Sleep(time.Millisecond*2)
|
||||
allNotExpiredItems := tc.GetNotExpiredItems()
|
||||
if len(allNotExpiredItems) != 2 {
|
||||
t.Error("There are more or less items in the result than the two unexpired.")
|
||||
}
|
||||
for _, key := range []string{"a", "b"} {
|
||||
if _, ok := tc.Get(key); !ok{
|
||||
t.Error("Could not find unexpired item %s", key)
|
||||
}
|
||||
}
|
||||
if _, ok := tc.Get("c"); ok {
|
||||
t.Error("Found expired item c.")
|
||||
}
|
||||
if &allNotExpiredItems == &tc.cache.items {
|
||||
t.Error("Returned map is equal to internal map.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCacheSerialization(t *testing.T) {
|
||||
tc := New(DefaultExpiration, 0)
|
||||
testFillAndSerialize(t, tc)
|
||||
|
@ -1676,3 +1700,18 @@ func BenchmarkDeleteExpiredLoop(b *testing.B) {
|
|||
tc.DeleteExpired()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetAllNotExpiredItems(b *testing.B) {
|
||||
for i:= 0; i < 20; i++ {
|
||||
b.Run(fmt.Sprintf("BenchmarkGetAllNotExpiredItemsWith %d000 Items", i), func(b *testing.B){
|
||||
tc := New(20*time.Minute, 0)
|
||||
for j:= 0; j < i*1000; j++{
|
||||
tc.Set(strconv.Itoa(i), "bar", DefaultExpiration)
|
||||
}
|
||||
b.ResetTimer()
|
||||
for j:= 0; j < b.N; j++{
|
||||
tc.GetNotExpiredItems()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue