Skip to content

Commit

Permalink
Support Contains
Browse files Browse the repository at this point in the history
jimchen committed Aug 23, 2024
1 parent 0a14ca1 commit 1d8c9ca
Showing 5 changed files with 97 additions and 0 deletions.
6 changes: 6 additions & 0 deletions internal/simplelru/lru.go
Original file line number Diff line number Diff line change
@@ -33,6 +33,12 @@ func (c *LRU[K, V]) Peek(key K) (value V, ok bool) {
return value, ok
}

// Checks if a key exists in cache without updating the recent-ness.
func (c *LRU[K, V]) Contains(key K) (ok bool) {
_, ok = c.items.Get(key)
return ok
}

// Returns the oldest entry without updating the "recently used"-ness of the key.
func (c *LRU[K, V]) PeekOldest() (key K, value V, ok bool) {
if ent := c.evictList.Back(); ent != nil {
3 changes: 3 additions & 0 deletions internal/simplelru/lru_interface.go
Original file line number Diff line number Diff line change
@@ -14,6 +14,9 @@ type LRUCache[K comparable, V any] interface {
// updates the "recently used"-ness of the key. #value, isFound
Get(key K) (value V, ok bool)

// Checks if a key exists in cache without updating the recent-ness.
Contains(key K) (ok bool)

// Returns key's value without updating the "recently used"-ness of the key.
Peek(key K) (value V, ok bool)

40 changes: 40 additions & 0 deletions internal/simplelru/lru_test.go
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ import (
"unsafe"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestLRU(t *testing.T) {
@@ -201,3 +202,42 @@ func TestLRU_Keys_Values(t *testing.T) {
assert.EqualValues(t, []int{1, 2, 3}, l.Keys())
assert.EqualValues(t, []int{10, 20, 30}, l.Values())
}

func TestLRU_Contains(t *testing.T) {
tests := []struct {
name string
initData [][2]string
key string
want bool
}{
{
name: "contains",
initData: [][2]string{
{"foo", "foo"},
{"zoo", "zoo"},
},
key: "foo",
want: true,
},
{
name: "not contains",
initData: [][2]string{
{"foo", "foo"},
{"zoo", "zoo"},
},
key: "bar",
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l, err := NewLRU[string, string](3)
require.NoError(t, err)

for _, data := range tt.initData {
l.Push(data[0], data[1])
}
assert.EqualValues(t, tt.want, l.Contains(tt.key))
})
}
}
8 changes: 8 additions & 0 deletions lru.go
Original file line number Diff line number Diff line change
@@ -55,6 +55,14 @@ func (c *Cache[K, V]) Peek(key K) (value V, ok bool) {
return value, ok
}

// Checks if a key exists in cache without updating the recent-ness.
func (c *Cache[K, V]) Contains(key K) (ok bool) {
c.mux.RLock()
defer c.mux.RUnlock()

return c.lru.Contains(key)
}

// Returns the oldest entry without updating the "recently used"-ness of the key.
func (c *Cache[K, V]) PeekOldest() (key K, value V, ok bool) {
c.mux.RLock()
40 changes: 40 additions & 0 deletions lru_test.go
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func assert_opt_eq[V any](t *testing.T, ok bool, got, v V) {
@@ -218,3 +219,42 @@ func TestCache_Keys_Values(t *testing.T) {
assert.EqualValues(t, []int{1, 2, 3}, l.Keys())
assert.EqualValues(t, []int{10, 20, 30}, l.Values())
}

func TestCache_Contains(t *testing.T) {
tests := []struct {
name string
initData [][2]string
key string
want bool
}{
{
name: "contains",
initData: [][2]string{
{"foo", "foo"},
{"zoo", "zoo"},
},
key: "foo",
want: true,
},
{
name: "not contains",
initData: [][2]string{
{"foo", "foo"},
{"zoo", "zoo"},
},
key: "bar",
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l, err := New[string, string](3)
require.NoError(t, err)

for _, data := range tt.initData {
l.Push(data[0], data[1])
}
assert.EqualValues(t, tt.want, l.Contains(tt.key))
})
}
}

0 comments on commit 1d8c9ca

Please sign in to comment.