Skip to content

Commit ccf9cd9

Browse files
authored
Merge pull request #31 from Code-Hex/fix/issue-29
fixed clock policy algorithm around delete
2 parents 5301ac8 + 55774a8 commit ccf9cd9

File tree

2 files changed

+31
-14
lines changed

2 files changed

+31
-14
lines changed

policy/clock/clock.go

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,21 +86,20 @@ func (c *Cache[K, V]) Get(key K) (zero V, _ bool) {
8686
return
8787
}
8888
entry := e.Value.(*entry[K, V])
89-
entry.referenceCount = 1
89+
entry.referenceCount++
9090
return entry.val, true
9191
}
9292

9393
func (c *Cache[K, V]) evict() {
94-
if c.hand.Value == nil {
95-
return
96-
}
97-
for c.hand.Value.(*entry[K, V]).referenceCount > 0 {
94+
for c.hand.Value != nil && c.hand.Value.(*entry[K, V]).referenceCount > 0 {
9895
c.hand.Value.(*entry[K, V]).referenceCount--
9996
c.hand = c.hand.Next()
10097
}
101-
entry := c.hand.Value.(*entry[K, V])
102-
delete(c.items, entry.key)
103-
c.hand.Value = nil
98+
if c.hand.Value != nil {
99+
entry := c.hand.Value.(*entry[K, V])
100+
delete(c.items, entry.key)
101+
c.hand.Value = nil
102+
}
104103
}
105104

106105
// Keys returns the keys of the cache. the order as same as current ring order.
@@ -116,12 +115,10 @@ func (c *Cache[K, V]) Keys() []K {
116115
// iterating
117116
for p := c.head.Next(); p != r; p = p.Next() {
118117
if p.Value == nil {
119-
break
118+
continue
120119
}
121120
e := p.Value.(*entry[K, V])
122-
if e.referenceCount > 0 {
123-
keys = append(keys, e.key)
124-
}
121+
keys = append(keys, e.key)
125122
}
126123
return keys
127124
}
@@ -130,7 +127,7 @@ func (c *Cache[K, V]) Keys() []K {
130127
func (c *Cache[K, V]) Delete(key K) {
131128
if e, ok := c.items[key]; ok {
132129
delete(c.items, key)
133-
e.Value.(*entry[K, V]).referenceCount = 0
130+
e.Value = nil
134131
}
135132
}
136133

policy/clock/clock_test.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package clock_test
22

33
import (
4+
"strconv"
45
"strings"
56
"testing"
67

@@ -123,10 +124,29 @@ func TestKeys(t *testing.T) {
123124
"hoge",
124125
}, ",")
125126
if got2 != want2 {
126-
t.Errorf("want2 %q, but got2 %q", want, got)
127+
t.Errorf("want2 %q, but got2 %q", want2, got2)
127128
}
128129
if len(cache.Keys()) != cache.Len() {
129130
t.Errorf("want2 number of keys %d, but got2 %d", len(cache.Keys()), cache.Len())
130131
}
131132
})
132133
}
134+
135+
func TestIssue29(t *testing.T) {
136+
cap := 3
137+
cache := clock.NewCache[string, int](clock.WithCapacity(cap))
138+
for i := 0; i < cap; i++ {
139+
cache.Set(strconv.Itoa(i), i)
140+
}
141+
cache.Set(strconv.Itoa(cap), cap)
142+
143+
keys := cache.Keys()
144+
if got := len(keys); cap != got {
145+
t.Errorf("want number of keys %d, but got %d", cap, got)
146+
}
147+
wantKeys := "3,1,2"
148+
gotKeys := strings.Join(keys, ",")
149+
if wantKeys != gotKeys {
150+
t.Errorf("want keys %q, but got keys %q", wantKeys, gotKeys)
151+
}
152+
}

0 commit comments

Comments
 (0)