Skip to content

Commit

Permalink
freelru: fix PurgeExpired
Browse files Browse the repository at this point in the history
  • Loading branch information
nekohasekai committed Dec 4, 2024
1 parent 9f69e7f commit 809d8ec
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 17 deletions.
15 changes: 7 additions & 8 deletions contrab/freelru/lru.go
Original file line number Diff line number Diff line change
Expand Up @@ -687,20 +687,19 @@ func (lru *LRU[K, V]) Purge() {
// PurgeExpired purges all expired items from the LRU.
// The evict function is called for each expired item.
func (lru *LRU[K, V]) PurgeExpired() {
n := now()
loop:
l := lru.len
if l == 0 {
return
}
n := now()
pos := lru.head
pos := lru.elements[lru.head].next
for i := uint32(0); i < l; i++ {
next := lru.elements[pos].next
if lru.elements[pos].expire != 0 {
if lru.elements[pos].expire <= n {
lru.removeAt(pos)
}
if lru.elements[pos].expire != 0 && lru.elements[pos].expire <= n {
lru.removeAt(pos)
goto loop
}
pos = next
pos = lru.elements[pos].next
}
}

Expand Down
28 changes: 19 additions & 9 deletions contrab/freelru/lru_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package freelru_test

import (
"github.com/sagernet/sing/common"
F "github.com/sagernet/sing/common/format"
"math/rand/v2"

Check failure on line 6 in contrab/freelru/lru_test.go

View workflow job for this annotation

GitHub Actions / Linux (Go 1.20)

package math/rand/v2 is not in GOROOT (/opt/hostedtoolcache/go/1.20.14/x64/src/math/rand/v2)

Check failure on line 6 in contrab/freelru/lru_test.go

View workflow job for this annotation

GitHub Actions / Linux (Go 1.21)

package math/rand/v2 is not in std (/opt/hostedtoolcache/go/1.21.13/x64/src/math/rand/v2)
"testing"
"time"

Expand Down Expand Up @@ -75,16 +78,23 @@ func TestUpdateLifetime2(t *testing.T) {
require.False(t, ok)
}

func TestPeekWithLifetime(t *testing.T) {
func TestPurgeExpired(t *testing.T) {
t.Parallel()
lru, err := freelru.New[string, string](1024, maphash.NewHasher[string]().Hash32)
lru, err := freelru.New[string, *string](1024, maphash.NewHasher[string]().Hash32)
require.NoError(t, err)
lru.SetLifetime(time.Second)
lru.AddWithLifetime("hello", "world", 10*time.Second)
lru.Add("hello1", "")
lru.Add("hello2", "")
lru.Add("hello3", "")
time.Sleep(2 * time.Second)
lru.PurgeExpired()
require.Equal(t, 1, lru.Len())
lru.SetOnEvict(func(s string, s2 *string) {
if s2 == nil {
t.Fail()
}
})
for i := 0; i < 100; i++ {
lru.AddWithLifetime("hello_"+F.ToString(i), common.Ptr("world_"+F.ToString(i)), time.Duration(rand.Int32N(3000))*time.Millisecond)
}
for i := 0; i < 5; i++ {
time.Sleep(time.Second)
lru.GetAndRefreshOrAdd("hellox"+F.ToString(i), func() (*string, bool) {
return common.Ptr("worldx"), true
})
}
}

0 comments on commit 809d8ec

Please sign in to comment.