Skip to content

Commit 438ff11

Browse files
committed
removed expiration code from some algorithm pkgs
1 parent 73addb2 commit 438ff11

File tree

9 files changed

+69
-296
lines changed

9 files changed

+69
-296
lines changed

lfu/lfu.go

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ type Cache[K comparable, V any] struct {
1515
mu sync.RWMutex
1616
}
1717

18-
var _ cache.Cache[interface{}, any] = (*Cache[interface{}, any])(nil)
18+
var _ cache.Interface[interface{}, any] = (*Cache[interface{}, any])(nil)
1919

2020
// NewCache creates a new LFU cache whose capacity is the default size (128).
2121
func NewCache[K comparable, V any]() *Cache[K, V] {
@@ -40,16 +40,13 @@ func (c *Cache[K, V]) Get(key K) (zero V, _ bool) {
4040
if !ok {
4141
return
4242
}
43-
if e.item.HasExpired() {
44-
return
45-
}
46-
e.item.Referenced()
43+
e.referenced()
4744
heap.Fix(c.queue, e.index)
48-
return e.item.Value, true
45+
return e.val, true
4946
}
5047

5148
// Set sets a value to the cache with key. replacing any existing value.
52-
func (c *Cache[K, V]) Set(key K, val V, opts ...cache.ItemOption) {
49+
func (c *Cache[K, V]) Set(key K, val V) {
5350
c.mu.Lock()
5451
defer c.mu.Unlock()
5552

@@ -60,10 +57,10 @@ func (c *Cache[K, V]) Set(key K, val V, opts ...cache.ItemOption) {
6057

6158
if len(c.items) == c.cap {
6259
evictedEntry := heap.Pop(c.queue).(*entry[K, V])
63-
delete(c.items, evictedEntry.item.Key)
60+
delete(c.items, evictedEntry.key)
6461
}
6562

66-
e := newEntry(key, val, opts...)
63+
e := newEntry(key, val)
6764
heap.Push(c.queue, e)
6865
c.items[key] = e
6966
}
@@ -74,7 +71,7 @@ func (c *Cache[K, V]) Keys() []K {
7471
defer c.mu.RUnlock()
7572
keys := make([]K, 0, len(c.items))
7673
for _, entry := range *c.queue {
77-
keys = append(keys, entry.item.Key)
74+
keys = append(keys, entry.key)
7875
}
7976
return keys
8077
}
@@ -89,17 +86,6 @@ func (c *Cache[K, V]) Delete(key K) {
8986
}
9087
}
9188

92-
// Contains reports whether key is within cache.
93-
func (c *Cache[K, V]) Contains(key K) bool {
94-
c.mu.RLock()
95-
defer c.mu.RUnlock()
96-
e, ok := c.items[key]
97-
if !ok {
98-
return false
99-
}
100-
return !e.item.HasExpired()
101-
}
102-
10389
// Len returns the number of items in the cache.
10490
func (c *Cache[K, V]) Len() int {
10591
c.mu.RLock()

lfu/lfu_internal_test.go

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1 @@
11
package lfu
2-
3-
import (
4-
"testing"
5-
"time"
6-
7-
cache "github.com/Code-Hex/go-generics-cache"
8-
)
9-
10-
func TestContains(t *testing.T) {
11-
t.Run("without expiration", func(t *testing.T) {
12-
cache := NewCache[string, int]()
13-
cache.Set("foo", 1)
14-
cache.Set("bar", 2)
15-
cache.Set("baz", 3)
16-
for _, key := range []string{
17-
"foo",
18-
"bar",
19-
"baz",
20-
} {
21-
if !cache.Contains(key) {
22-
t.Errorf("not found: %s", key)
23-
}
24-
}
25-
if cache.Contains("not found") {
26-
t.Errorf("found")
27-
}
28-
})
29-
30-
t.Run("with expiration", func(t *testing.T) {
31-
c := NewCache[string, int]()
32-
key := "foo"
33-
exp := time.Hour
34-
c.Set(key, 1, cache.WithExpiration(exp))
35-
// modify directly
36-
e, ok := c.items[key]
37-
if !ok {
38-
t.Fatal("unexpected not found key")
39-
}
40-
item := e.item
41-
item.CreatedAt = time.Now().Add(-2 * exp)
42-
43-
if c.Contains(key) {
44-
t.Errorf("found")
45-
}
46-
})
47-
}
48-
49-
func TestGet(t *testing.T) {
50-
c := NewCache[string, int]()
51-
key := "foo"
52-
exp := time.Hour
53-
c.Set(key, 1, cache.WithExpiration(exp))
54-
_, ok := c.Get(key)
55-
if !ok {
56-
t.Fatal("unexpected not found")
57-
}
58-
// modify directly
59-
e, ok := c.items[key]
60-
if !ok {
61-
t.Fatal("unexpected not found key")
62-
}
63-
item := e.item
64-
item.CreatedAt = time.Now().Add(-2 * exp)
65-
_, ok2 := c.Get(key)
66-
if ok2 {
67-
t.Fatal("unexpected found (expired)")
68-
}
69-
}

lfu/priority_queue_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ func TestPriorityQueue(t *testing.T) {
2727
if entry.index != idx {
2828
t.Errorf("want index %d, but got %d", entry.index, idx)
2929
}
30-
if entry.item.ReferenceCount != 1 {
30+
if entry.referenceCount != 1 {
3131
t.Errorf("want count 1")
3232
}
33-
if got := entry.item.Value; nums[idx] != got {
33+
if got := entry.val; nums[idx] != got {
3434
t.Errorf("want value %d but got %d", nums[idx], got)
3535
}
3636
}
@@ -53,8 +53,8 @@ func TestPriorityQueue(t *testing.T) {
5353
if got.index != -1 {
5454
t.Errorf("want index -1, but got %d", got.index)
5555
}
56-
if wantValue != got.item.Value {
57-
t.Errorf("want the lowest priority value is %d, but got %d", wantValue, got.item.Value)
56+
if wantValue != got.val {
57+
t.Errorf("want the lowest priority value is %d, but got %d", wantValue, got.val)
5858
}
5959
if want, got := len(nums)-1, queue.Len(); want != got {
6060
t.Errorf("want %d, but got %d", want, got)
@@ -66,8 +66,8 @@ func TestPriorityQueue(t *testing.T) {
6666
if got.index != -1 {
6767
t.Errorf("want index -1, but got %d", got.index)
6868
}
69-
if wantValue2 != got2.item.Value {
70-
t.Errorf("want the lowest priority value is %d, but got %d", wantValue2, got2.item.Value)
69+
if wantValue2 != got2.val {
70+
t.Errorf("want the lowest priority value is %d, but got %d", wantValue2, got2.val)
7171
}
7272
if want, got := len(nums)-2, queue.Len(); want != got {
7373
t.Errorf("want %d, but got %d", want, got)

lfu/priotiry_queue.go

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,34 @@ package lfu
22

33
import (
44
"container/heap"
5+
"time"
56

67
cache "github.com/Code-Hex/go-generics-cache"
78
)
89

910
type entry[K comparable, V any] struct {
10-
index int
11-
item *cache.Item[K, V]
11+
index int
12+
key K
13+
val V
14+
referenceCount int
15+
referencedAt time.Time
1216
}
1317

1418
func newEntry[K comparable, V any](key K, val V, opts ...cache.ItemOption) *entry[K, V] {
1519
return &entry[K, V]{
16-
index: 0,
17-
item: cache.NewItem(key, val, opts...),
20+
index: 0,
21+
key: key,
22+
val: val,
23+
referenceCount: 1,
24+
referencedAt: time.Now(),
1825
}
1926
}
2027

28+
func (e *entry[K, V]) referenced() {
29+
e.referenceCount++
30+
e.referencedAt = time.Now()
31+
}
32+
2133
type priorityQueue[K comparable, V any] []*entry[K, V]
2234

2335
func newPriorityQueue[K comparable, V any](cap int) *priorityQueue[K, V] {
@@ -31,10 +43,10 @@ var _ heap.Interface = (*priorityQueue[interface{}, interface{}])(nil)
3143
func (l priorityQueue[K, V]) Len() int { return len(l) }
3244

3345
func (l priorityQueue[K, V]) Less(i, j int) bool {
34-
if l[i].item.ReferenceCount == l[j].item.ReferenceCount {
35-
return l[i].item.ReferencedAt.Before(l[j].item.ReferencedAt)
46+
if l[i].referenceCount == l[j].referenceCount {
47+
return l[i].referencedAt.Before(l[j].referencedAt)
3648
}
37-
return l[i].item.ReferenceCount < l[j].item.ReferenceCount
49+
return l[i].referenceCount < l[j].referenceCount
3850
}
3951

4052
func (l priorityQueue[K, V]) Swap(i, j int) {
@@ -60,7 +72,7 @@ func (l *priorityQueue[K, V]) Pop() interface{} {
6072
}
6173

6274
func (pq *priorityQueue[K, V]) update(e *entry[K, V], val V) {
63-
e.item.Value = val
64-
e.item.Referenced()
75+
e.val = val
76+
e.referenced()
6577
heap.Fix(pq, e.index)
6678
}

lru/lru.go

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ type Cache[K comparable, V any] struct {
1515
mu sync.RWMutex
1616
}
1717

18-
var _ cache.Cache[interface{}, any] = (*Cache[interface{}, any])(nil)
18+
type entry[K comparable, V any] struct {
19+
key K
20+
val V
21+
}
22+
23+
var _ cache.Interface[interface{}, any] = (*Cache[interface{}, any])(nil)
1924

2025
// NewCache creates a new LRU cache whose capacity is the default size (128).
2126
func NewCache[K comparable, V any]() *Cache[K, V] {
@@ -39,32 +44,29 @@ func (c *Cache[K, V]) Get(key K) (zero V, _ bool) {
3944
if !ok {
4045
return
4146
}
42-
item := e.Value.(*cache.Item[K, V])
43-
if item.HasExpired() {
44-
return
45-
}
46-
item.Referenced()
4747
// updates cache order
4848
c.list.MoveToFront(e)
49-
return item.Value, true
49+
return e.Value.(*entry[K, V]).val, true
5050
}
5151

5252
// Set sets a value to the cache with key. replacing any existing value.
53-
func (c *Cache[K, V]) Set(key K, val V, opts ...cache.ItemOption) {
53+
func (c *Cache[K, V]) Set(key K, val V) {
5454
c.mu.Lock()
5555
defer c.mu.Unlock()
5656

5757
if e, ok := c.items[key]; ok {
5858
// updates cache order
5959
c.list.MoveToFront(e)
60-
item := e.Value.(*cache.Item[K, V])
61-
item.Value = val
62-
item.Referenced()
60+
entry := e.Value.(*entry[K, V])
61+
entry.val = val
6362
return
6463
}
6564

66-
item := cache.NewItem(key, val, opts...)
67-
e := c.list.PushFront(item)
65+
newEntry := &entry[K, V]{
66+
key: key,
67+
val: val,
68+
}
69+
e := c.list.PushFront(newEntry)
6870
c.items[key] = e
6971

7072
if c.list.Len() > c.cap {
@@ -78,8 +80,8 @@ func (c *Cache[K, V]) Keys() []K {
7880
defer c.mu.RUnlock()
7981
keys := make([]K, 0, len(c.items))
8082
for ent := c.list.Back(); ent != nil; ent = ent.Prev() {
81-
item := ent.Value.(*cache.Item[K, V])
82-
keys = append(keys, item.Key)
83+
entry := ent.Value.(*entry[K, V])
84+
keys = append(keys, entry.key)
8385
}
8486
return keys
8587
}
@@ -100,25 +102,13 @@ func (c *Cache[K, V]) Delete(key K) {
100102
}
101103
}
102104

103-
// Contains reports whether key is within cache.
104-
func (c *Cache[K, V]) Contains(key K) bool {
105-
c.mu.RLock()
106-
defer c.mu.RUnlock()
107-
e, ok := c.items[key]
108-
if !ok {
109-
return false
110-
}
111-
item := e.Value.(*cache.Item[K, V])
112-
return !item.HasExpired()
113-
}
114-
115105
func (c *Cache[K, V]) deleteOldest() {
116106
e := c.list.Back()
117107
c.delete(e)
118108
}
119109

120110
func (c *Cache[K, V]) delete(e *list.Element) {
121111
c.list.Remove(e)
122-
item := e.Value.(*cache.Item[K, V])
123-
delete(c.items, item.Key)
112+
entry := e.Value.(*entry[K, V])
113+
delete(c.items, entry.key)
124114
}

0 commit comments

Comments
 (0)