44 "fmt"
55 "sync"
66
7- "github.com/hashicorp/golang-lru/simplelru"
7+ "github.com/hashicorp/golang-lru/v2/ simplelru"
88)
99
1010const (
@@ -26,25 +26,25 @@ const (
2626// computationally about 2x the cost, and adds some metadata over
2727// head. The ARCCache is similar, but does not require setting any
2828// parameters.
29- type TwoQueueCache struct {
29+ type TwoQueueCache [ K comparable , V any ] struct {
3030 size int
3131 recentSize int
3232
33- recent simplelru.LRUCache
34- frequent simplelru.LRUCache
35- recentEvict simplelru.LRUCache
33+ recent simplelru.LRUCache [ K , V ]
34+ frequent simplelru.LRUCache [ K , V ]
35+ recentEvict simplelru.LRUCache [ K , V ]
3636 lock sync.RWMutex
3737}
3838
3939// New2Q creates a new TwoQueueCache using the default
4040// values for the parameters.
41- func New2Q (size int ) (* TwoQueueCache , error ) {
42- return New2QParams (size , Default2QRecentRatio , Default2QGhostEntries )
41+ func New2Q [ K comparable , V any ] (size int ) (* TwoQueueCache [ K , V ] , error ) {
42+ return New2QParams [ K , V ] (size , Default2QRecentRatio , Default2QGhostEntries )
4343}
4444
4545// New2QParams creates a new TwoQueueCache using the provided
4646// parameter values.
47- func New2QParams (size int , recentRatio , ghostRatio float64 ) (* TwoQueueCache , error ) {
47+ func New2QParams [ K comparable , V any ] (size int , recentRatio , ghostRatio float64 ) (* TwoQueueCache [ K , V ] , error ) {
4848 if size <= 0 {
4949 return nil , fmt .Errorf ("invalid size" )
5050 }
@@ -60,21 +60,21 @@ func New2QParams(size int, recentRatio, ghostRatio float64) (*TwoQueueCache, err
6060 evictSize := int (float64 (size ) * ghostRatio )
6161
6262 // Allocate the LRUs
63- recent , err := simplelru .NewLRU (size , nil )
63+ recent , err := simplelru .NewLRU [ K , V ] (size , nil )
6464 if err != nil {
6565 return nil , err
6666 }
67- frequent , err := simplelru .NewLRU (size , nil )
67+ frequent , err := simplelru .NewLRU [ K , V ] (size , nil )
6868 if err != nil {
6969 return nil , err
7070 }
71- recentEvict , err := simplelru .NewLRU (evictSize , nil )
71+ recentEvict , err := simplelru .NewLRU [ K , V ] (evictSize , nil )
7272 if err != nil {
7373 return nil , err
7474 }
7575
7676 // Initialize the cache
77- c := & TwoQueueCache {
77+ c := & TwoQueueCache [ K , V ] {
7878 size : size ,
7979 recentSize : recentSize ,
8080 recent : recent ,
@@ -85,7 +85,7 @@ func New2QParams(size int, recentRatio, ghostRatio float64) (*TwoQueueCache, err
8585}
8686
8787// Get looks up a key's value from the cache.
88- func (c * TwoQueueCache ) Get (key interface {} ) (value interface {} , ok bool ) {
88+ func (c * TwoQueueCache [ K , V ] ) Get (key K ) (value V , ok bool ) {
8989 c .lock .Lock ()
9090 defer c .lock .Unlock ()
9191
@@ -103,11 +103,11 @@ func (c *TwoQueueCache) Get(key interface{}) (value interface{}, ok bool) {
103103 }
104104
105105 // No hit
106- return nil , false
106+ return
107107}
108108
109109// Add adds a value to the cache.
110- func (c * TwoQueueCache ) Add (key , value interface {} ) {
110+ func (c * TwoQueueCache [ K , V ] ) Add (key K , value V ) {
111111 c .lock .Lock ()
112112 defer c .lock .Unlock ()
113113
@@ -141,7 +141,7 @@ func (c *TwoQueueCache) Add(key, value interface{}) {
141141}
142142
143143// ensureSpace is used to ensure we have space in the cache
144- func (c * TwoQueueCache ) ensureSpace (recentEvict bool ) {
144+ func (c * TwoQueueCache [ K , V ] ) ensureSpace (recentEvict bool ) {
145145 // If we have space, nothing to do
146146 recentLen := c .recent .Len ()
147147 freqLen := c .frequent .Len ()
@@ -153,7 +153,8 @@ func (c *TwoQueueCache) ensureSpace(recentEvict bool) {
153153 // the target, evict from there
154154 if recentLen > 0 && (recentLen > c .recentSize || (recentLen == c .recentSize && ! recentEvict )) {
155155 k , _ , _ := c .recent .RemoveOldest ()
156- c .recentEvict .Add (k , nil )
156+ var empty V
157+ c .recentEvict .Add (k , empty )
157158 return
158159 }
159160
@@ -162,15 +163,15 @@ func (c *TwoQueueCache) ensureSpace(recentEvict bool) {
162163}
163164
164165// Len returns the number of items in the cache.
165- func (c * TwoQueueCache ) Len () int {
166+ func (c * TwoQueueCache [ K , V ] ) Len () int {
166167 c .lock .RLock ()
167168 defer c .lock .RUnlock ()
168169 return c .recent .Len () + c .frequent .Len ()
169170}
170171
171172// Keys returns a slice of the keys in the cache.
172173// The frequently used keys are first in the returned slice.
173- func (c * TwoQueueCache ) Keys () []interface {} {
174+ func (c * TwoQueueCache [ K , V ] ) Keys () []K {
174175 c .lock .RLock ()
175176 defer c .lock .RUnlock ()
176177 k1 := c .frequent .Keys ()
@@ -179,7 +180,7 @@ func (c *TwoQueueCache) Keys() []interface{} {
179180}
180181
181182// Remove removes the provided key from the cache.
182- func (c * TwoQueueCache ) Remove (key interface {} ) {
183+ func (c * TwoQueueCache [ K , V ] ) Remove (key K ) {
183184 c .lock .Lock ()
184185 defer c .lock .Unlock ()
185186 if c .frequent .Remove (key ) {
@@ -194,7 +195,7 @@ func (c *TwoQueueCache) Remove(key interface{}) {
194195}
195196
196197// Purge is used to completely clear the cache.
197- func (c * TwoQueueCache ) Purge () {
198+ func (c * TwoQueueCache [ K , V ] ) Purge () {
198199 c .lock .Lock ()
199200 defer c .lock .Unlock ()
200201 c .recent .Purge ()
@@ -204,15 +205,15 @@ func (c *TwoQueueCache) Purge() {
204205
205206// Contains is used to check if the cache contains a key
206207// without updating recency or frequency.
207- func (c * TwoQueueCache ) Contains (key interface {} ) bool {
208+ func (c * TwoQueueCache [ K , V ] ) Contains (key K ) bool {
208209 c .lock .RLock ()
209210 defer c .lock .RUnlock ()
210211 return c .frequent .Contains (key ) || c .recent .Contains (key )
211212}
212213
213214// Peek is used to inspect the cache value of a key
214215// without updating recency or frequency.
215- func (c * TwoQueueCache ) Peek (key interface {} ) (value interface {} , ok bool ) {
216+ func (c * TwoQueueCache [ K , V ] ) Peek (key K ) (value V , ok bool ) {
216217 c .lock .RLock ()
217218 defer c .lock .RUnlock ()
218219 if val , ok := c .frequent .Peek (key ); ok {
0 commit comments