From d582c453703398d4d70e3fa70d3f812ecc85a1c6 Mon Sep 17 00:00:00 2001 From: zhuliquan Date: Thu, 11 Jan 2024 00:15:48 +0800 Subject: [PATCH] feature: add Cap interface{} (#145) * feature: add Cap interface{} * feature: add Cap for 2q and fix bug on arc.Cap * feature: add Cap for expireable_lru * test: add Cap for expire lru --- 2q.go | 5 +++++ 2q_test.go | 3 +++ arc/arc.go | 5 +++++ arc/arc_test.go | 9 +++++++++ expirable/expirable_lru.go | 5 +++++ expirable/expirable_lru_test.go | 4 ++++ lru.go | 5 +++++ lru_test.go | 3 +++ simplelru/lru.go | 5 +++++ simplelru/lru_interface.go | 3 +++ simplelru/lru_test.go | 3 +++ 11 files changed, 50 insertions(+) diff --git a/2q.go b/2q.go index 8c95252..16c8a66 100644 --- a/2q.go +++ b/2q.go @@ -175,6 +175,11 @@ func (c *TwoQueueCache[K, V]) Len() int { return c.recent.Len() + c.frequent.Len() } +// Cap returns the capacity of the cache +func (c *TwoQueueCache[K, V]) Cap() int { + return c.size +} + // Resize changes the cache size. func (c *TwoQueueCache[K, V]) Resize(size int) (evicted int) { c.lock.Lock() diff --git a/2q_test.go b/2q_test.go index efa6e86..b8b2c94 100644 --- a/2q_test.go +++ b/2q_test.go @@ -299,6 +299,9 @@ func Test2Q(t *testing.T) { if l.Len() != 128 { t.Fatalf("bad len: %v", l.Len()) } + if l.Cap() != 128 { + t.Fatalf("expect %d, but %d", 128, l.Cap()) + } for i, k := range l.Keys() { if v, ok := l.Get(k); !ok || v != k || v != i+128 { diff --git a/arc/arc.go b/arc/arc.go index 724f5fe..116cb70 100644 --- a/arc/arc.go +++ b/arc/arc.go @@ -202,6 +202,11 @@ func (c *ARCCache[K, V]) Len() int { return c.t1.Len() + c.t2.Len() } +// Cap returns the capacity of the cache +func (c *ARCCache[K, V]) Cap() int { + return c.size +} + // Keys returns all the cached keys func (c *ARCCache[K, V]) Keys() []K { c.lock.RLock() diff --git a/arc/arc_test.go b/arc/arc_test.go index 913abca..7c3ded4 100644 --- a/arc/arc_test.go +++ b/arc/arc_test.go @@ -313,6 +313,9 @@ func TestARC(t *testing.T) { if l.Len() != 128 { t.Fatalf("bad len: %v", l.Len()) } + if l.Cap() != 128 { + t.Fatalf("expect %d, but %d", 128, l.Cap()) + } for i, k := range l.Keys() { if v, ok := l.Get(k); !ok || v != k || v != i+128 { @@ -340,6 +343,9 @@ func TestARC(t *testing.T) { t.Fatalf("should be deleted") } } + if l.Cap() != 128 { + t.Fatalf("expect %d, but %d", 128, l.Cap()) + } l.Purge() if l.Len() != 0 { @@ -348,6 +354,9 @@ func TestARC(t *testing.T) { if _, ok := l.Get(200); ok { t.Fatalf("should contain nothing") } + if l.Cap() != 128 { + t.Fatalf("expect %d, but %d", 128, l.Cap()) + } } // Test that Contains doesn't update recent-ness diff --git a/expirable/expirable_lru.go b/expirable/expirable_lru.go index 9f600a4..8e70082 100644 --- a/expirable/expirable_lru.go +++ b/expirable/expirable_lru.go @@ -339,3 +339,8 @@ func (c *LRU[K, V]) addToBucket(e *internal.Entry[K, V]) { func (c *LRU[K, V]) removeFromBucket(e *internal.Entry[K, V]) { delete(c.buckets[e.ExpireBucket].entries, e.Key) } + +// Cap returns the capacity of the cache +func (c *LRU[K, V]) Cap() int { + return c.size +} \ No newline at end of file diff --git a/expirable/expirable_lru_test.go b/expirable/expirable_lru_test.go index fd3b255..e01c68d 100644 --- a/expirable/expirable_lru_test.go +++ b/expirable/expirable_lru_test.go @@ -425,6 +425,10 @@ func TestLoadingExpired(t *testing.T) { func TestLRURemoveOldest(t *testing.T) { lc := NewLRU[string, string](2, nil, 0) + if lc.Cap() != 2 { + t.Fatalf("expect cap is 2") + } + k, v, ok := lc.RemoveOldest() if k != "" { t.Fatalf("should be empty") diff --git a/lru.go b/lru.go index a2655f1..2bb07fd 100644 --- a/lru.go +++ b/lru.go @@ -248,3 +248,8 @@ func (c *Cache[K, V]) Len() int { c.lock.RUnlock() return length } + +// Cap returns the capacity of the cache +func (c *Cache[K, V]) Cap() int { + return c.lru.Cap() +} diff --git a/lru_test.go b/lru_test.go index 36cbfff..7ecc7ae 100644 --- a/lru_test.go +++ b/lru_test.go @@ -86,6 +86,9 @@ func TestLRU(t *testing.T) { if l.Len() != 128 { t.Fatalf("bad len: %v", l.Len()) } + if l.Cap() != 128 { + t.Fatalf("expect %d, but %d", 128, l.Cap()) + } if evictCounter != 128 { t.Fatalf("bad evict count: %v", evictCounter) diff --git a/simplelru/lru.go b/simplelru/lru.go index f697923..8f45d2e 100644 --- a/simplelru/lru.go +++ b/simplelru/lru.go @@ -147,6 +147,11 @@ func (c *LRU[K, V]) Len() int { return c.evictList.Length() } +// Cap returns the capacity of the cache +func (c *LRU[K, V]) Cap() int { + return c.size +} + // Resize changes the cache size. func (c *LRU[K, V]) Resize(size int) (evicted int) { diff := c.Len() - size diff --git a/simplelru/lru_interface.go b/simplelru/lru_interface.go index 043b8bc..495652b 100644 --- a/simplelru/lru_interface.go +++ b/simplelru/lru_interface.go @@ -38,6 +38,9 @@ type LRUCache[K comparable, V any] interface { // Returns the number of items in the cache. Len() int + // Returns the capacity of the cache. + Cap() int + // Clears all cache entries. Purge() diff --git a/simplelru/lru_test.go b/simplelru/lru_test.go index 19a8fac..91a1d1b 100644 --- a/simplelru/lru_test.go +++ b/simplelru/lru_test.go @@ -27,6 +27,9 @@ func TestLRU(t *testing.T) { if l.Len() != 128 { t.Fatalf("bad len: %v", l.Len()) } + if l.Cap() != 128 { + t.Fatalf("expect %d, but %d", 128, l.Cap()) + } if evictCounter != 128 { t.Fatalf("bad evict count: %v", evictCounter)