@@ -2,7 +2,6 @@ package cache
22
33import (
44 "context"
5- "runtime"
65 "sync"
76 "time"
87
@@ -16,9 +15,13 @@ import (
1615
1716// Interface is a common-cache interface.
1817type Interface [K comparable , V any ] interface {
18+ // Get looks up a key's value from the cache.
1919 Get (key K ) (value V , ok bool )
20+ // Set sets a value to the cache with key. replacing any existing value.
2021 Set (key K , val V )
22+ // Keys returns the keys of the cache. The order is relied on algorithms.
2123 Keys () []K
24+ // Delete deletes the item with provided key from the cache.
2225 Delete (key K )
2326}
2427
@@ -147,38 +150,30 @@ func WithJanitorInterval[K comparable, V any](d time.Duration) Option[K, V] {
147150}
148151
149152// 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.
152156//
153157// There are several Cache replacement policies available with you specified any options.
154158func 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 ... )
168160}
169161
170162// NewContext creates a new thread safe Cache with context.
163+ // This function will be stopped an internal janitor when the context is cancelled.
171164//
172165// There are several Cache replacement policies available with you specified any options.
173166func NewContext [K comparable , V any ](ctx context.Context , opts ... Option [K , V ]) * Cache [K , V ] {
174167 o := newOptions [K , V ]()
175168 for _ , optFunc := range opts {
176169 optFunc (o )
177170 }
178- return & Cache [K , V ]{
171+ cache := & Cache [K , V ]{
179172 cache : o .cache ,
180173 janitor : newJanitor (ctx , o .janitorInterval ),
181174 }
175+ cache .janitor .run (cache .DeleteExpired )
176+ return cache
182177}
183178
184179// 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) {
202197
203198// DeleteExpired all expired items from the cache.
204199func (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 ()
206206 // if is expired, delete it and return nil instead
207207 item , ok := c .cache .Get (key )
208208 if ok && item .Expired () {
209209 c .cache .Delete (key )
210210 }
211+ c .mu .Unlock ()
211212 }
212213}
213214
0 commit comments