Skip to content

Commit 4dabb9b

Browse files
committed
freelru: Fix GetAndRefreshOrAdd
1 parent be9840c commit 4dabb9b

File tree

5 files changed

+23
-17
lines changed

5 files changed

+23
-17
lines changed

common/udpnat2/service.go

+3-5
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func New(handler N.UDPConnectionHandlerEx, prepare PrepareFunc, timeout time.Dur
5151
}
5252

5353
func (s *Service) NewPacket(bufferSlices [][]byte, source M.Socksaddr, destination M.Socksaddr, userData any) {
54-
conn, loaded := s.cache.GetAndRefreshOrAdd(source.AddrPort(), func() (*natConn, bool) {
54+
conn, _, ok := s.cache.GetAndRefreshOrAdd(source.AddrPort(), func() (*natConn, bool) {
5555
ok, ctx, writer, onClose := s.prepare(source, destination, userData)
5656
if !ok {
5757
return nil, false
@@ -67,10 +67,8 @@ func (s *Service) NewPacket(bufferSlices [][]byte, source M.Socksaddr, destinati
6767
go s.handler.NewPacketConnectionEx(ctx, newConn, source, destination, onClose)
6868
return newConn, true
6969
})
70-
if !loaded {
71-
if conn == nil {
72-
return
73-
}
70+
if !ok {
71+
return
7472
}
7573
buffer := conn.readWaitOptions.NewPacketBuffer()
7674
for _, bufferSlice := range bufferSlices {

contrab/freelru/cache.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ type Cache[K comparable, V comparable] interface {
5454
// The lifetime of the found cache item is refreshed, even if it was already expired.
5555
GetAndRefresh(key K) (V, bool)
5656

57-
GetAndRefreshOrAdd(key K, constructor func() (V, bool)) (V, bool)
57+
GetAndRefreshOrAdd(key K, constructor func() (V, bool)) (V, bool, bool)
5858

5959
// Peek looks up a key's value from the cache, without changing its recent-ness.
6060
// If the found entry is already expired, the evict function is called.

contrab/freelru/lru.go

+9-7
Original file line numberDiff line numberDiff line change
@@ -522,29 +522,31 @@ func (lru *LRU[K, V]) getAndRefresh(hash uint32, key K) (value V, ok bool) {
522522
return
523523
}
524524

525-
func (lru *LRU[K, V]) GetAndRefreshOrAdd(key K, constructor func() (V, bool)) (V, bool) {
526-
return lru.getAndRefreshOrAdd(lru.hash(key), key, constructor)
525+
func (lru *LRU[K, V]) GetAndRefreshOrAdd(key K, constructor func() (V, bool)) (V, bool, bool) {
526+
value, updated, ok := lru.getAndRefreshOrAdd(lru.hash(key), key, constructor)
527+
if !updated && ok {
528+
lru.PurgeExpired()
529+
}
530+
return value, updated, ok
527531
}
528532

529-
func (lru *LRU[K, V]) getAndRefreshOrAdd(hash uint32, key K, constructor func() (V, bool)) (value V, ok bool) {
533+
func (lru *LRU[K, V]) getAndRefreshOrAdd(hash uint32, key K, constructor func() (V, bool)) (value V, updated bool, ok bool) {
530534
if pos, ok := lru.findKeyNoExpire(hash, key); ok {
531535
if pos != lru.head {
532536
lru.unlinkElement(pos)
533537
lru.setHead(pos)
534538
}
535539
lru.metrics.Hits++
536540
lru.elements[pos].expire = expire(lru.lifetime)
537-
return lru.elements[pos].value, ok
541+
return lru.elements[pos].value, true, true
538542
}
539-
540543
lru.metrics.Misses++
541544
value, ok = constructor()
542545
if !ok {
543546
return
544547
}
545548
lru.addWithLifetime(hash, key, value, lru.lifetime)
546-
lru.PurgeExpired()
547-
return value, false
549+
return value, false, true
548550
}
549551

550552
// Peek looks up a key's value from the cache, without changing its recent-ness.

contrab/freelru/shardedlru.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -201,14 +201,17 @@ func (lru *ShardedLRU[K, V]) GetAndRefresh(key K) (value V, ok bool) {
201201
return
202202
}
203203

204-
func (lru *ShardedLRU[K, V]) GetAndRefreshOrAdd(key K, constructor func() (V, bool)) (value V, updated bool) {
204+
func (lru *ShardedLRU[K, V]) GetAndRefreshOrAdd(key K, constructor func() (V, bool)) (value V, updated bool, ok bool) {
205205
hash := lru.hash(key)
206206
shard := (hash >> 16) & lru.mask
207207

208208
lru.mus[shard].Lock()
209-
value, updated = lru.lrus[shard].getAndRefreshOrAdd(hash, key, constructor)
209+
value, updated, ok = lru.lrus[shard].getAndRefreshOrAdd(hash, key, constructor)
210210
lru.mus[shard].Unlock()
211211

212+
if !updated && ok {
213+
lru.PurgeExpired()
214+
}
212215
return
213216
}
214217

contrab/freelru/syncedlru.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,14 @@ func (lru *SyncedLRU[K, V]) GetAndRefresh(key K) (value V, ok bool) {
121121
return
122122
}
123123

124-
func (lru *SyncedLRU[K, V]) GetAndRefreshOrAdd(key K, constructor func() (V, bool)) (value V, updated bool) {
124+
func (lru *SyncedLRU[K, V]) GetAndRefreshOrAdd(key K, constructor func() (V, bool)) (value V, updated bool, ok bool) {
125125
hash := lru.lru.hash(key)
126126

127127
lru.mu.Lock()
128-
value, updated = lru.lru.getAndRefreshOrAdd(hash, key, constructor)
128+
value, updated, ok = lru.lru.getAndRefreshOrAdd(hash, key, constructor)
129+
if !updated && ok {
130+
lru.lru.PurgeExpired()
131+
}
129132
lru.mu.Unlock()
130133

131134
return

0 commit comments

Comments
 (0)