From eb164d15369bd8582b79491c72122269911ba14a Mon Sep 17 00:00:00 2001 From: dudaodong Date: Thu, 29 Dec 2022 11:43:04 +0800 Subject: [PATCH] test: add examples for lrucache function --- algorithm/lru_cache.go | 102 ------------------------------------ algorithm/lru_cache_test.go | 36 ------------- 2 files changed, 138 deletions(-) delete mode 100644 algorithm/lru_cache.go delete mode 100644 algorithm/lru_cache_test.go diff --git a/algorithm/lru_cache.go b/algorithm/lru_cache.go deleted file mode 100644 index bc519cd..0000000 --- a/algorithm/lru_cache.go +++ /dev/null @@ -1,102 +0,0 @@ -package algorithm - -type lruNode[K comparable, V any] struct { - key K - value V - pre *lruNode[K, V] - next *lruNode[K, V] -} - -// newLruNode return a lruNode pointer -func newLruNode[K comparable, V any](key K, value V) *lruNode[K, V] { - return &lruNode[K, V]{ - key: key, - value: value, - pre: nil, - next: nil, - } -} - -// LRUCache lru cache (thread unsafe) -type LRUCache[K comparable, V any] struct { - cache map[K]*lruNode[K, V] - head *lruNode[K, V] - tail *lruNode[K, V] - capacity int - length int -} - -// NewLRUCache return a LRUCache pointer -func NewLRUCache[K comparable, V any](capacity int) *LRUCache[K, V] { - return &LRUCache[K, V]{ - cache: make(map[K]*lruNode[K, V], capacity), - head: nil, - tail: nil, - capacity: capacity, - length: 0, - } -} - -// Get value of key from lru cache -func (l *LRUCache[K, V]) Get(key K) (V, bool) { - var value V - - node, ok := l.cache[key] - if ok { - l.moveToHead(node) - return node.value, true - } - - return value, false -} - -// Put value of key into lru cache -func (l *LRUCache[K, V]) Put(key K, value V) { - node, ok := l.cache[key] - if !ok { - newNode := newLruNode(key, value) - l.cache[key] = newNode - l.addNode(newNode) - - if len(l.cache) > l.capacity { - oldKey := l.deleteNode(l.head) - delete(l.cache, oldKey) - } - } else { - node.value = value - l.moveToHead(node) - } - l.length = len(l.cache) -} - -func (l *LRUCache[K, V]) addNode(node *lruNode[K, V]) { - if l.tail != nil { - l.tail.next = node - node.pre = l.tail - node.next = nil - } - l.tail = node - if l.head == nil { - l.head = node - } -} - -func (l *LRUCache[K, V]) deleteNode(node *lruNode[K, V]) K { - if node == l.tail { - l.tail = l.tail.pre - } else if node == l.head { - l.head = l.head.next - } else { - node.pre.next = node.next - node.next.pre = node.pre - } - return node.key -} - -func (l *LRUCache[K, V]) moveToHead(node *lruNode[K, V]) { - if l.tail == node { - return - } - l.deleteNode(node) - l.addNode(node) -} diff --git a/algorithm/lru_cache_test.go b/algorithm/lru_cache_test.go deleted file mode 100644 index fba5426..0000000 --- a/algorithm/lru_cache_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package algorithm - -import ( - "testing" - - "github.com/duke-git/lancet/v2/internal" -) - -func TestLRUCache(t *testing.T) { - asssert := internal.NewAssert(t, "TestLRUCache") - - cache := NewLRUCache[int, int](2) - - cache.Put(1, 1) - cache.Put(2, 2) - - _, ok := cache.Get(0) - asssert.Equal(false, ok) - - v, ok := cache.Get(1) - asssert.Equal(true, ok) - asssert.Equal(1, v) - - v, ok = cache.Get(2) - asssert.Equal(true, ok) - asssert.Equal(2, v) - - cache.Put(3, 3) - v, ok = cache.Get(1) - asssert.Equal(false, ok) - asssert.NotEqual(1, v) - - v, ok = cache.Get(3) - asssert.Equal(true, ok) - asssert.Equal(3, v) -}