@@ -2,7 +2,6 @@ package cache
2
2
3
3
import (
4
4
"context"
5
- "runtime"
6
5
"sync"
7
6
"time"
8
7
@@ -16,9 +15,13 @@ import (
16
15
17
16
// Interface is a common-cache interface.
18
17
type Interface [K comparable , V any ] interface {
18
+ // Get looks up a key's value from the cache.
19
19
Get (key K ) (value V , ok bool )
20
+ // Set sets a value to the cache with key. replacing any existing value.
20
21
Set (key K , val V )
22
+ // Keys returns the keys of the cache. The order is relied on algorithms.
21
23
Keys () []K
24
+ // Delete deletes the item with provided key from the cache.
22
25
Delete (key K )
23
26
}
24
27
@@ -147,38 +150,30 @@ func WithJanitorInterval[K comparable, V any](d time.Duration) Option[K, V] {
147
150
}
148
151
149
152
// New creates a new thread safe Cache.
150
- // This function will be stopped an internal janitor when the cache is
151
- // no longer referenced anywhere.
153
+ // The janitor will not be stopped which is created by this function. If you
154
+ // want to stop the janitor gracefully, You should use the `NewContext` function
155
+ // instead of this.
152
156
//
153
157
// There are several Cache replacement policies available with you specified any options.
154
158
func New [K comparable , V any ](opts ... Option [K , V ]) * Cache [K , V ] {
155
- o := newOptions [K , V ]()
156
- for _ , optFunc := range opts {
157
- optFunc (o )
158
- }
159
- ctx , cancel := context .WithCancel (context .Background ())
160
- cache := & Cache [K , V ]{
161
- cache : o .cache ,
162
- janitor : newJanitor (ctx , o .janitorInterval ),
163
- }
164
- runtime .SetFinalizer (cache , func (self * Cache [K , V ]) {
165
- cancel ()
166
- })
167
- return cache
159
+ return NewContext (context .Background (), opts ... )
168
160
}
169
161
170
162
// NewContext creates a new thread safe Cache with context.
163
+ // This function will be stopped an internal janitor when the context is cancelled.
171
164
//
172
165
// There are several Cache replacement policies available with you specified any options.
173
166
func NewContext [K comparable , V any ](ctx context.Context , opts ... Option [K , V ]) * Cache [K , V ] {
174
167
o := newOptions [K , V ]()
175
168
for _ , optFunc := range opts {
176
169
optFunc (o )
177
170
}
178
- return & Cache [K , V ]{
171
+ cache := & Cache [K , V ]{
179
172
cache : o .cache ,
180
173
janitor : newJanitor (ctx , o .janitorInterval ),
181
174
}
175
+ cache .janitor .run (cache .DeleteExpired )
176
+ return cache
182
177
}
183
178
184
179
// Get looks up a key's value from the cache.
@@ -202,12 +197,18 @@ func (c *Cache[K, V]) Get(key K) (value V, ok bool) {
202
197
203
198
// DeleteExpired all expired items from the cache.
204
199
func (c * Cache [K , V ]) DeleteExpired () {
205
- for _ , key := range c .cache .Keys () {
200
+ c .mu .Lock ()
201
+ keys := c .cache .Keys ()
202
+ c .mu .Unlock ()
203
+
204
+ for _ , key := range keys {
205
+ c .mu .Lock ()
206
206
// if is expired, delete it and return nil instead
207
207
item , ok := c .cache .Get (key )
208
208
if ok && item .Expired () {
209
209
c .cache .Delete (key )
210
210
}
211
+ c .mu .Unlock ()
211
212
}
212
213
}
213
214
0 commit comments