@@ -141,10 +141,10 @@ func (c *Cache) Set(key, value interface{}, ttl time.Duration) {
141
141
for {
142
142
old , loaded := c .records .LoadOrStore (key , r )
143
143
if ! loaded {
144
- r .init (value , ttl )
145
144
if ttl > 0 {
146
145
c .runLoop ()
147
146
}
147
+ r .init (value , ttl )
148
148
if front := c .list .PushBack (key , r .ring ); front != nil {
149
149
c .Evict (front )
150
150
}
@@ -154,7 +154,7 @@ func (c *Cache) Set(key, value interface{}, ttl time.Duration) {
154
154
c .mu .Lock ()
155
155
defer c .mu .Unlock ()
156
156
if c .deleteIfEqualsLocked (key , old .(* record )) {
157
- c .finalizeAsync (key , old .(* record ))
157
+ c .finalizeSync (key , old .(* record ))
158
158
}
159
159
}()
160
160
}
@@ -180,10 +180,10 @@ func (c *Cache) Fetch(key interface{}, ttl time.Duration, f FetchCallback) (valu
180
180
c .deleteIfEqualsLocked (key , r )
181
181
return nil , false
182
182
}
183
- r .init (value , ttl )
184
183
if ttl > 0 {
185
184
c .runLoop ()
186
185
}
186
+ r .init (value , ttl )
187
187
r .wg .Add (1 )
188
188
if front := c .list .PushBack (key , r .ring ); front != nil {
189
189
c .Evict (front )
@@ -331,49 +331,43 @@ func (c *Cache) deleteIfEqualsLocked(key interface{}, r *record) bool {
331
331
return true
332
332
}
333
333
334
- func (c * Cache ) finalizeSync (key interface {}, r * record ) (interface {}, bool ) {
334
+ func (c * Cache ) remove (key interface {}, r * record ) (interface {}, bool ) {
335
335
value , ok := r .LoadAndReset ()
336
336
if ! ok {
337
+ // An inactive record which had a concurrent Fetch and failed.
337
338
return nil , false
338
339
}
339
340
if k := c .list .Remove (r .ring ); k != nil && k != key {
340
341
panic ("evcache: invalid ring" )
341
342
}
342
- if readers := atomic .LoadUint32 (& r .readers ); readers == 0 {
343
+ return value , true
344
+ }
345
+
346
+ func (c * Cache ) finalizeSync (key interface {}, r * record ) (interface {}, bool ) {
347
+ value , ok := c .remove (key , r )
348
+ if ! ok {
349
+ return nil , false
350
+ }
351
+ c .wg .Add (1 )
352
+ go func () {
353
+ defer c .wg .Done ()
354
+ r .wg .Wait ()
343
355
c .pool .Put (r )
344
356
if c .afterEvict != nil {
345
- c .wg .Add (1 )
346
- go func () {
347
- defer c .wg .Done ()
348
- c .afterEvict (key , value )
349
- }()
357
+ c .afterEvict (key , value )
350
358
}
351
- } else if readers > 0 {
352
- c .wg .Add (1 )
353
- go func () {
354
- defer c .wg .Done ()
355
- r .wg .Wait ()
356
- c .pool .Put (r )
357
- if c .afterEvict != nil {
358
- c .afterEvict (key , value )
359
- }
360
- }()
361
- }
359
+ }()
362
360
return value , true
363
361
}
364
362
365
363
func (c * Cache ) finalizeAsync (key interface {}, r * record ) {
366
364
c .wg .Add (1 )
367
365
go func () {
368
366
defer c .wg .Done ()
369
- value , ok := r . LoadAndReset ( )
367
+ value , ok := c . remove ( key , r )
370
368
if ! ok {
371
- // An inactive record which had a concurrent Fetch and failed.
372
369
return
373
370
}
374
- if k := c .list .Remove (r .ring ); k != nil && k != key {
375
- panic ("evcache: invalid ring" )
376
- }
377
371
r .wg .Wait ()
378
372
c .pool .Put (r )
379
373
if c .afterEvict != nil {
@@ -411,7 +405,7 @@ func (c *Cache) processRecords(now int64) {
411
405
c .mu .Lock ()
412
406
defer c .mu .Unlock ()
413
407
if c .deleteIfEqualsLocked (key , r ) {
414
- c .finalizeAsync (key , r )
408
+ c .finalizeSync (key , r )
415
409
}
416
410
return true
417
411
}
0 commit comments