Skip to content

Commit 9c36caf

Browse files
committed
added tests for WithReferenceCount
1 parent 63e7f6b commit 9c36caf

File tree

6 files changed

+71
-5
lines changed

6 files changed

+71
-5
lines changed

cache.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ func WithExpiration(exp time.Duration) ItemOption {
7979
// WithReferenceCount is an option to set reference count for any items.
8080
// This option is only applicable to cache policies that have a reference count (e.g., Clock, LFU).
8181
// referenceCount specifies the reference count value to set for the cache item.
82+
//
83+
// the default is 1.
8284
func WithReferenceCount(referenceCount int) ItemOption {
8385
return func(o *itemOptions) {
8486
o.referenceCount = referenceCount
@@ -102,7 +104,6 @@ func newItem[K comparable, V any](key K, val V, opts ...ItemOption) *Item[K, V]
102104
// Cache is a thread safe cache.
103105
type Cache[K comparable, V any] struct {
104106
cache Interface[K, *Item[K, V]]
105-
//expirations map[K]chan struct{}
106107
// mu is used to do lock in some method process.
107108
mu sync.Mutex
108109
janitor *janitor

example_test.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"time"
77

88
cache "github.com/Code-Hex/go-generics-cache"
9+
"github.com/Code-Hex/go-generics-cache/policy/lfu"
910
)
1011

1112
func ExampleCache() {
@@ -77,21 +78,29 @@ func ExampleWithExpiration() {
7778
}
7879

7980
func ExampleWithReferenceCount() {
80-
c := cache.New(cache.AsLFU[string, int]())
81-
c.Set("a", 1, cache.WithReferenceCount(2))
81+
c := cache.New(cache.AsLFU[string, int](lfu.WithCapacity(2)))
82+
83+
// set item with reference count
84+
c.Set("a", 1, cache.WithReferenceCount(5))
8285

8386
// check item is set.
8487
gota, aok := c.Get("a")
8588
fmt.Println(gota, aok)
8689

87-
c.Set("b", 2, cache.WithReferenceCount(3))
90+
c.Set("b", 2)
91+
c.Set("c", 3)
8892

93+
// evicted becauce the lowest reference count.
8994
gotb, bok := c.Get("b")
9095
fmt.Println(gotb, bok)
9196

97+
gotc, cok := c.Get("c")
98+
fmt.Println(gotc, cok)
99+
92100
// Output:
93101
// 1 true
94-
// 2 true
102+
// 0 false
103+
// 3 true
95104
}
96105

97106
func ExampleCache_Delete() {

policy/clock/clock.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ func NewCache[K comparable, V any](opts ...Option) *Cache[K, V] {
6464
}
6565

6666
// Set sets any item to the cache. replacing any existing item.
67+
//
68+
// If value satisfies "interface{ GetReferenceCount() int }", the value of
69+
// the GetReferenceCount() method is used to set the initial value of reference count.
6770
func (c *Cache[K, V]) Set(key K, val V) {
6871
if e, ok := c.items[key]; ok {
6972
entry := e.Value.(*entry[K, V])

policy/clock/clock_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ import (
88
"github.com/Code-Hex/go-generics-cache/policy/clock"
99
)
1010

11+
type tmp struct {
12+
i int
13+
}
14+
15+
func (t *tmp) GetReferenceCount() int { return t.i }
16+
1117
func TestSet(t *testing.T) {
1218
// set capacity is 1
1319
cache := clock.NewCache[string, int](clock.WithCapacity(1))
@@ -43,6 +49,25 @@ func TestSet(t *testing.T) {
4349
if bar != 100 || !ok {
4450
t.Fatalf("invalid replacing value bar %d, cachehit %v", bar, ok)
4551
}
52+
53+
t.Run("with initilal reference count", func(t *testing.T) {
54+
cache := clock.NewCache[string, *tmp](clock.WithCapacity(2))
55+
cache.Set("foo", &tmp{i: 10}) // the highest reference count
56+
cache.Set("foo2", &tmp{i: 2}) // expected eviction
57+
if got := cache.Len(); got != 2 {
58+
t.Fatalf("invalid length: %d", got)
59+
}
60+
61+
cache.Set("foo3", &tmp{i: 3})
62+
63+
// checks deleted the lowest reference count
64+
if _, ok := cache.Get("foo2"); ok {
65+
t.Fatalf("invalid delete oldest value foo2 %v", ok)
66+
}
67+
if _, ok := cache.Get("foo"); !ok {
68+
t.Fatalf("invalid value foo is not found")
69+
}
70+
})
4671
}
4772

4873
func TestDelete(t *testing.T) {

policy/lfu/lfu.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ func (c *Cache[K, V]) Get(key K) (zero V, _ bool) {
6161
}
6262

6363
// Set sets a value to the cache with key. replacing any existing value.
64+
//
65+
// If value satisfies "interface{ GetReferenceCount() int }", the value of
66+
// the GetReferenceCount() method is used to set the initial value of reference count.
6467
func (c *Cache[K, V]) Set(key K, val V) {
6568
if e, ok := c.items[key]; ok {
6669
c.queue.update(e, val)

policy/lfu/lfu_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ import (
66
"github.com/Code-Hex/go-generics-cache/policy/lfu"
77
)
88

9+
type tmp struct {
10+
i int
11+
}
12+
13+
func (t *tmp) GetReferenceCount() int { return t.i }
14+
915
func TestSet(t *testing.T) {
1016
// set capacity is 1
1117
cache := lfu.NewCache[string, int](lfu.WithCapacity(1))
@@ -41,6 +47,25 @@ func TestSet(t *testing.T) {
4147
if bar != 100 || !ok {
4248
t.Fatalf("invalid replacing value bar %d, cachehit %v", bar, ok)
4349
}
50+
51+
t.Run("with initilal reference count", func(t *testing.T) {
52+
cache := lfu.NewCache[string, *tmp](lfu.WithCapacity(2))
53+
cache.Set("foo", &tmp{i: 10}) // the highest reference count
54+
cache.Set("foo2", &tmp{i: 2}) // expected eviction
55+
if got := cache.Len(); got != 2 {
56+
t.Fatalf("invalid length: %d", got)
57+
}
58+
59+
cache.Set("foo3", &tmp{i: 3})
60+
61+
// checks deleted the lowest reference count
62+
if _, ok := cache.Get("foo2"); ok {
63+
t.Fatalf("invalid delete oldest value foo2 %v", ok)
64+
}
65+
if _, ok := cache.Get("foo"); !ok {
66+
t.Fatalf("invalid value foo is not found")
67+
}
68+
})
4469
}
4570

4671
func TestDelete(t *testing.T) {

0 commit comments

Comments
 (0)