rely more on generic inference
This commit is contained in:
@@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func Test_CacheDeletesAValue(t *testing.T) {
|
func Test_CacheDeletesAValue(t *testing.T) {
|
||||||
cache := New[string](Configure[string]())
|
cache := New(Configure[string]())
|
||||||
defer cache.Stop()
|
defer cache.Stop()
|
||||||
assert.Equal(t, cache.ItemCount(), 0)
|
assert.Equal(t, cache.ItemCount(), 0)
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ func Test_CacheDeletesAValue(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_CacheDeletesAPrefix(t *testing.T) {
|
func Test_CacheDeletesAPrefix(t *testing.T) {
|
||||||
cache := New[string](Configure[string]())
|
cache := New(Configure[string]())
|
||||||
defer cache.Stop()
|
defer cache.Stop()
|
||||||
assert.Equal(t, cache.ItemCount(), 0)
|
assert.Equal(t, cache.ItemCount(), 0)
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ func Test_CacheDeletesAPrefix(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_CacheDeletesAFunc(t *testing.T) {
|
func Test_CacheDeletesAFunc(t *testing.T) {
|
||||||
cache := New[int](Configure[int]())
|
cache := New(Configure[int]())
|
||||||
defer cache.Stop()
|
defer cache.Stop()
|
||||||
assert.Equal(t, cache.ItemCount(), 0)
|
assert.Equal(t, cache.ItemCount(), 0)
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ func Test_CacheOnDeleteCallbackCalled(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cache := New[string](Configure[string]().OnDelete(onDeleteFn))
|
cache := New(Configure[string]().OnDelete(onDeleteFn))
|
||||||
cache.Set("spice", "flow", time.Minute)
|
cache.Set("spice", "flow", time.Minute)
|
||||||
cache.Set("worm", "sand", time.Minute)
|
cache.Set("worm", "sand", time.Minute)
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ func Test_CacheOnDeleteCallbackCalled(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_CacheFetchesExpiredItems(t *testing.T) {
|
func Test_CacheFetchesExpiredItems(t *testing.T) {
|
||||||
cache := New[string](Configure[string]())
|
cache := New(Configure[string]())
|
||||||
fn := func() (string, error) { return "moo-moo", nil }
|
fn := func() (string, error) { return "moo-moo", nil }
|
||||||
|
|
||||||
cache.Set("beef", "moo", time.Second*-1)
|
cache.Set("beef", "moo", time.Second*-1)
|
||||||
@@ -113,7 +113,7 @@ func Test_CacheFetchesExpiredItems(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_CacheGCsTheOldestItems(t *testing.T) {
|
func Test_CacheGCsTheOldestItems(t *testing.T) {
|
||||||
cache := New[int](Configure[int]().ItemsToPrune(10))
|
cache := New(Configure[int]().ItemsToPrune(10))
|
||||||
for i := 0; i < 500; i++ {
|
for i := 0; i < 500; i++ {
|
||||||
cache.Set(strconv.Itoa(i), i, time.Minute)
|
cache.Set(strconv.Itoa(i), i, time.Minute)
|
||||||
}
|
}
|
||||||
@@ -125,7 +125,7 @@ func Test_CacheGCsTheOldestItems(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_CachePromotedItemsDontGetPruned(t *testing.T) {
|
func Test_CachePromotedItemsDontGetPruned(t *testing.T) {
|
||||||
cache := New[int](Configure[int]().ItemsToPrune(10).GetsPerPromote(1))
|
cache := New(Configure[int]().ItemsToPrune(10).GetsPerPromote(1))
|
||||||
for i := 0; i < 500; i++ {
|
for i := 0; i < 500; i++ {
|
||||||
cache.Set(strconv.Itoa(i), i, time.Minute)
|
cache.Set(strconv.Itoa(i), i, time.Minute)
|
||||||
}
|
}
|
||||||
@@ -139,7 +139,7 @@ func Test_CachePromotedItemsDontGetPruned(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_CacheTrackerDoesNotCleanupHeldInstance(t *testing.T) {
|
func Test_CacheTrackerDoesNotCleanupHeldInstance(t *testing.T) {
|
||||||
cache := New[int](Configure[int]().ItemsToPrune(11).Track())
|
cache := New(Configure[int]().ItemsToPrune(11).Track())
|
||||||
item0 := cache.TrackingSet("0", 0, time.Minute)
|
item0 := cache.TrackingSet("0", 0, time.Minute)
|
||||||
for i := 1; i < 11; i++ {
|
for i := 1; i < 11; i++ {
|
||||||
cache.Set(strconv.Itoa(i), i, time.Minute)
|
cache.Set(strconv.Itoa(i), i, time.Minute)
|
||||||
@@ -164,7 +164,7 @@ func Test_CacheRemovesOldestItemWhenFull(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cache := New[int](Configure[int]().MaxSize(5).ItemsToPrune(1).OnDelete(onDeleteFn))
|
cache := New(Configure[int]().MaxSize(5).ItemsToPrune(1).OnDelete(onDeleteFn))
|
||||||
for i := 0; i < 7; i++ {
|
for i := 0; i < 7; i++ {
|
||||||
cache.Set(strconv.Itoa(i), i, time.Minute)
|
cache.Set(strconv.Itoa(i), i, time.Minute)
|
||||||
}
|
}
|
||||||
@@ -177,7 +177,7 @@ func Test_CacheRemovesOldestItemWhenFull(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_CacheRemovesOldestItemWhenFullBySizer(t *testing.T) {
|
func Test_CacheRemovesOldestItemWhenFullBySizer(t *testing.T) {
|
||||||
cache := New[*SizedItem](Configure[*SizedItem]().MaxSize(9).ItemsToPrune(2))
|
cache := New(Configure[*SizedItem]().MaxSize(9).ItemsToPrune(2))
|
||||||
for i := 0; i < 7; i++ {
|
for i := 0; i < 7; i++ {
|
||||||
cache.Set(strconv.Itoa(i), &SizedItem{i, 2}, time.Minute)
|
cache.Set(strconv.Itoa(i), &SizedItem{i, 2}, time.Minute)
|
||||||
}
|
}
|
||||||
@@ -192,7 +192,7 @@ func Test_CacheRemovesOldestItemWhenFullBySizer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_CacheSetUpdatesSizeOnDelta(t *testing.T) {
|
func Test_CacheSetUpdatesSizeOnDelta(t *testing.T) {
|
||||||
cache := New[*SizedItem](Configure[*SizedItem]())
|
cache := New(Configure[*SizedItem]())
|
||||||
cache.Set("a", &SizedItem{0, 2}, time.Minute)
|
cache.Set("a", &SizedItem{0, 2}, time.Minute)
|
||||||
cache.Set("b", &SizedItem{0, 3}, time.Minute)
|
cache.Set("b", &SizedItem{0, 3}, time.Minute)
|
||||||
cache.SyncUpdates()
|
cache.SyncUpdates()
|
||||||
@@ -212,7 +212,7 @@ func Test_CacheSetUpdatesSizeOnDelta(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_CacheReplaceDoesNotchangeSizeIfNotSet(t *testing.T) {
|
func Test_CacheReplaceDoesNotchangeSizeIfNotSet(t *testing.T) {
|
||||||
cache := New[*SizedItem](Configure[*SizedItem]())
|
cache := New(Configure[*SizedItem]())
|
||||||
cache.Set("1", &SizedItem{1, 2}, time.Minute)
|
cache.Set("1", &SizedItem{1, 2}, time.Minute)
|
||||||
cache.Set("2", &SizedItem{1, 2}, time.Minute)
|
cache.Set("2", &SizedItem{1, 2}, time.Minute)
|
||||||
cache.Set("3", &SizedItem{1, 2}, time.Minute)
|
cache.Set("3", &SizedItem{1, 2}, time.Minute)
|
||||||
@@ -222,7 +222,7 @@ func Test_CacheReplaceDoesNotchangeSizeIfNotSet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_CacheReplaceChangesSize(t *testing.T) {
|
func Test_CacheReplaceChangesSize(t *testing.T) {
|
||||||
cache := New[*SizedItem](Configure[*SizedItem]())
|
cache := New(Configure[*SizedItem]())
|
||||||
cache.Set("1", &SizedItem{1, 2}, time.Minute)
|
cache.Set("1", &SizedItem{1, 2}, time.Minute)
|
||||||
cache.Set("2", &SizedItem{1, 2}, time.Minute)
|
cache.Set("2", &SizedItem{1, 2}, time.Minute)
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ func Test_CacheReplaceChangesSize(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_CacheResizeOnTheFly(t *testing.T) {
|
func Test_CacheResizeOnTheFly(t *testing.T) {
|
||||||
cache := New[int](Configure[int]().MaxSize(9).ItemsToPrune(1))
|
cache := New(Configure[int]().MaxSize(9).ItemsToPrune(1))
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
cache.Set(strconv.Itoa(i), i, time.Minute)
|
cache.Set(strconv.Itoa(i), i, time.Minute)
|
||||||
}
|
}
|
||||||
@@ -272,7 +272,7 @@ func Test_CacheResizeOnTheFly(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_CacheForEachFunc(t *testing.T) {
|
func Test_CacheForEachFunc(t *testing.T) {
|
||||||
cache := New[int](Configure[int]().MaxSize(3).ItemsToPrune(1))
|
cache := New(Configure[int]().MaxSize(3).ItemsToPrune(1))
|
||||||
assert.List(t, forEachKeys[int](cache), []string{})
|
assert.List(t, forEachKeys[int](cache), []string{})
|
||||||
|
|
||||||
cache.Set("1", 1, time.Minute)
|
cache.Set("1", 1, time.Minute)
|
||||||
|
@@ -158,7 +158,7 @@ func Test_LayedCache_DeletesALayer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_LayeredCache_GCsTheOldestItems(t *testing.T) {
|
func Test_LayeredCache_GCsTheOldestItems(t *testing.T) {
|
||||||
cache := Layered[int](Configure[int]().ItemsToPrune(10))
|
cache := Layered(Configure[int]().ItemsToPrune(10))
|
||||||
cache.Set("xx", "a", 23, time.Minute)
|
cache.Set("xx", "a", 23, time.Minute)
|
||||||
for i := 0; i < 500; i++ {
|
for i := 0; i < 500; i++ {
|
||||||
cache.Set(strconv.Itoa(i), "a", i, time.Minute)
|
cache.Set(strconv.Itoa(i), "a", i, time.Minute)
|
||||||
@@ -175,7 +175,7 @@ func Test_LayeredCache_GCsTheOldestItems(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_LayeredCache_PromotedItemsDontGetPruned(t *testing.T) {
|
func Test_LayeredCache_PromotedItemsDontGetPruned(t *testing.T) {
|
||||||
cache := Layered[int](Configure[int]().ItemsToPrune(10).GetsPerPromote(1))
|
cache := Layered(Configure[int]().ItemsToPrune(10).GetsPerPromote(1))
|
||||||
for i := 0; i < 500; i++ {
|
for i := 0; i < 500; i++ {
|
||||||
cache.Set(strconv.Itoa(i), "a", i, time.Minute)
|
cache.Set(strconv.Itoa(i), "a", i, time.Minute)
|
||||||
}
|
}
|
||||||
@@ -189,7 +189,7 @@ func Test_LayeredCache_PromotedItemsDontGetPruned(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_LayeredCache_TrackerDoesNotCleanupHeldInstance(t *testing.T) {
|
func Test_LayeredCache_TrackerDoesNotCleanupHeldInstance(t *testing.T) {
|
||||||
cache := Layered[int](Configure[int]().ItemsToPrune(10).Track())
|
cache := Layered(Configure[int]().ItemsToPrune(10).Track())
|
||||||
item0 := cache.TrackingSet("0", "a", 0, time.Minute)
|
item0 := cache.TrackingSet("0", "a", 0, time.Minute)
|
||||||
for i := 1; i < 11; i++ {
|
for i := 1; i < 11; i++ {
|
||||||
cache.Set(strconv.Itoa(i), "a", i, time.Minute)
|
cache.Set(strconv.Itoa(i), "a", i, time.Minute)
|
||||||
@@ -207,7 +207,7 @@ func Test_LayeredCache_TrackerDoesNotCleanupHeldInstance(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_LayeredCache_RemovesOldestItemWhenFull(t *testing.T) {
|
func Test_LayeredCache_RemovesOldestItemWhenFull(t *testing.T) {
|
||||||
cache := Layered[int](Configure[int]().MaxSize(5).ItemsToPrune(1))
|
cache := Layered(Configure[int]().MaxSize(5).ItemsToPrune(1))
|
||||||
cache.Set("xx", "a", 23, time.Minute)
|
cache.Set("xx", "a", 23, time.Minute)
|
||||||
for i := 0; i < 7; i++ {
|
for i := 0; i < 7; i++ {
|
||||||
cache.Set(strconv.Itoa(i), "a", i, time.Minute)
|
cache.Set(strconv.Itoa(i), "a", i, time.Minute)
|
||||||
@@ -225,7 +225,7 @@ func Test_LayeredCache_RemovesOldestItemWhenFull(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_LayeredCache_ResizeOnTheFly(t *testing.T) {
|
func Test_LayeredCache_ResizeOnTheFly(t *testing.T) {
|
||||||
cache := Layered[int](Configure[int]().MaxSize(9).ItemsToPrune(1))
|
cache := Layered(Configure[int]().MaxSize(9).ItemsToPrune(1))
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
cache.Set(strconv.Itoa(i), "a", i, time.Minute)
|
cache.Set(strconv.Itoa(i), "a", i, time.Minute)
|
||||||
}
|
}
|
||||||
@@ -259,7 +259,7 @@ func Test_LayeredCache_ResizeOnTheFly(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_LayeredCache_RemovesOldestItemWhenFullBySizer(t *testing.T) {
|
func Test_LayeredCache_RemovesOldestItemWhenFullBySizer(t *testing.T) {
|
||||||
cache := Layered[*SizedItem](Configure[*SizedItem]().MaxSize(9).ItemsToPrune(2))
|
cache := Layered(Configure[*SizedItem]().MaxSize(9).ItemsToPrune(2))
|
||||||
for i := 0; i < 7; i++ {
|
for i := 0; i < 7; i++ {
|
||||||
cache.Set("pri", strconv.Itoa(i), &SizedItem{i, 2}, time.Minute)
|
cache.Set("pri", strconv.Itoa(i), &SizedItem{i, 2}, time.Minute)
|
||||||
}
|
}
|
||||||
@@ -272,7 +272,7 @@ func Test_LayeredCache_RemovesOldestItemWhenFullBySizer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_LayeredCache_SetUpdatesSizeOnDelta(t *testing.T) {
|
func Test_LayeredCache_SetUpdatesSizeOnDelta(t *testing.T) {
|
||||||
cache := Layered[*SizedItem](Configure[*SizedItem]())
|
cache := Layered(Configure[*SizedItem]())
|
||||||
cache.Set("pri", "a", &SizedItem{0, 2}, time.Minute)
|
cache.Set("pri", "a", &SizedItem{0, 2}, time.Minute)
|
||||||
cache.Set("pri", "b", &SizedItem{0, 3}, time.Minute)
|
cache.Set("pri", "b", &SizedItem{0, 3}, time.Minute)
|
||||||
cache.SyncUpdates()
|
cache.SyncUpdates()
|
||||||
@@ -293,7 +293,7 @@ func Test_LayeredCache_SetUpdatesSizeOnDelta(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_LayeredCache_ReplaceDoesNotchangeSizeIfNotSet(t *testing.T) {
|
func Test_LayeredCache_ReplaceDoesNotchangeSizeIfNotSet(t *testing.T) {
|
||||||
cache := Layered[*SizedItem](Configure[*SizedItem]())
|
cache := Layered(Configure[*SizedItem]())
|
||||||
cache.Set("pri", "1", &SizedItem{1, 2}, time.Minute)
|
cache.Set("pri", "1", &SizedItem{1, 2}, time.Minute)
|
||||||
cache.Set("pri", "2", &SizedItem{1, 2}, time.Minute)
|
cache.Set("pri", "2", &SizedItem{1, 2}, time.Minute)
|
||||||
cache.Set("pri", "3", &SizedItem{1, 2}, time.Minute)
|
cache.Set("pri", "3", &SizedItem{1, 2}, time.Minute)
|
||||||
@@ -303,7 +303,7 @@ func Test_LayeredCache_ReplaceDoesNotchangeSizeIfNotSet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_LayeredCache_ReplaceChangesSize(t *testing.T) {
|
func Test_LayeredCache_ReplaceChangesSize(t *testing.T) {
|
||||||
cache := Layered[*SizedItem](Configure[*SizedItem]())
|
cache := Layered(Configure[*SizedItem]())
|
||||||
cache.Set("pri", "1", &SizedItem{1, 2}, time.Minute)
|
cache.Set("pri", "1", &SizedItem{1, 2}, time.Minute)
|
||||||
cache.Set("pri", "2", &SizedItem{1, 2}, time.Minute)
|
cache.Set("pri", "2", &SizedItem{1, 2}, time.Minute)
|
||||||
|
|
||||||
@@ -321,7 +321,7 @@ func Test_LayeredCache_ReplaceChangesSize(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_LayeredCache_EachFunc(t *testing.T) {
|
func Test_LayeredCache_EachFunc(t *testing.T) {
|
||||||
cache := Layered[int](Configure[int]().MaxSize(3).ItemsToPrune(1))
|
cache := Layered(Configure[int]().MaxSize(3).ItemsToPrune(1))
|
||||||
assert.List(t, forEachKeysLayered[int](cache, "1"), []string{})
|
assert.List(t, forEachKeysLayered[int](cache, "1"), []string{})
|
||||||
|
|
||||||
cache.Set("1", "a", 1, time.Minute)
|
cache.Set("1", "a", 1, time.Minute)
|
||||||
|
12
readme.md
12
readme.md
@@ -22,13 +22,15 @@ import (
|
|||||||
"github.com/karlseguin/ccache/v3"
|
"github.com/karlseguin/ccache/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cache = ccache.New[string](ccache.Configure[string]())
|
// create a cache with string values
|
||||||
|
var cache = ccache.New(ccache.Configure[string]())
|
||||||
```
|
```
|
||||||
|
|
||||||
`Configure` exposes a chainable API:
|
`Configure` exposes a chainable API:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
var cache = ccache.New[int](ccache.Configure[int]().MaxSize(1000).ItemsToPrune(100))
|
// creates a cache with int values
|
||||||
|
var cache = ccache.New(ccache.Configure[int]().MaxSize(1000).ItemsToPrune(100))
|
||||||
```
|
```
|
||||||
|
|
||||||
The most likely configuration options to tweak are:
|
The most likely configuration options to tweak are:
|
||||||
@@ -133,7 +135,7 @@ CCache supports a special tracking mode which is meant to be used in conjunction
|
|||||||
When you configure your cache with `Track()`:
|
When you configure your cache with `Track()`:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
cache = ccache.New(ccache.Configure().Track())
|
cache = ccache.New(ccache.Configure[int]().Track())
|
||||||
```
|
```
|
||||||
|
|
||||||
The items retrieved via `TrackingGet` will not be eligible for purge until `Release` is called on them:
|
The items retrieved via `TrackingGet` will not be eligible for purge until `Release` is called on them:
|
||||||
@@ -159,7 +161,7 @@ CCache's `LayeredCache` stores and retrieves values by both a primary and second
|
|||||||
`LayeredCache` takes the same configuration object as the main cache, exposes the same optional tracking capabilities, but exposes a slightly different API:
|
`LayeredCache` takes the same configuration object as the main cache, exposes the same optional tracking capabilities, but exposes a slightly different API:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
cache := ccache.Layered[string](ccache.Configure[string]())
|
cache := ccache.Layered(ccache.Configure[string]())
|
||||||
|
|
||||||
cache.Set("/users/goku", "type:json", "{value_to_cache}", time.Minute * 5)
|
cache.Set("/users/goku", "type:json", "{value_to_cache}", time.Minute * 5)
|
||||||
cache.Set("/users/goku", "type:xml", "<value_to_cache>", time.Minute * 5)
|
cache.Set("/users/goku", "type:xml", "<value_to_cache>", time.Minute * 5)
|
||||||
@@ -178,7 +180,7 @@ cache.DeleteAll("/users/goku")
|
|||||||
In some cases, when using a `LayeredCache`, it may be desirable to always be acting on the secondary portion of the cache entry. This could be the case where the primary key is used as a key elsewhere in your code. The `SecondaryCache` is retrieved with:
|
In some cases, when using a `LayeredCache`, it may be desirable to always be acting on the secondary portion of the cache entry. This could be the case where the primary key is used as a key elsewhere in your code. The `SecondaryCache` is retrieved with:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
cache := ccache.Layered[string](ccache.Configure[string]())
|
cache := ccache.Layered(ccache.Configure[string]())
|
||||||
sCache := cache.GetOrCreateSecondaryCache("/users/goku")
|
sCache := cache.GetOrCreateSecondaryCache("/users/goku")
|
||||||
sCache.Set("type:json", "{value_to_cache}", time.Minute * 5)
|
sCache.Set("type:json", "{value_to_cache}", time.Minute * 5)
|
||||||
```
|
```
|
||||||
|
@@ -84,7 +84,7 @@ func Test_SecondaryCache_FetchReturnsANewValue(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_SecondaryCache_TrackerDoesNotCleanupHeldInstance(t *testing.T) {
|
func Test_SecondaryCache_TrackerDoesNotCleanupHeldInstance(t *testing.T) {
|
||||||
cache := Layered[int](Configure[int]().ItemsToPrune(10).Track())
|
cache := Layered(Configure[int]().ItemsToPrune(10).Track())
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
cache.Set(strconv.Itoa(i), "a", i, time.Minute)
|
cache.Set(strconv.Itoa(i), "a", i, time.Minute)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user