Skip to content

Commit

Permalink
Fix bug that caused no replacement in LRU Cache. (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
marstr authored Sep 16, 2020
1 parent 3c6aaaf commit cdc8d77
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 8 deletions.
16 changes: 8 additions & 8 deletions lru_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import "sync"
// is evicted from the cache.
type LRUCache struct {
capacity uint
entries map[interface{}]lruEntry
entries map[interface{}]*lruEntry
touched *LinkedList
key sync.RWMutex
}
Expand All @@ -21,7 +21,7 @@ type lruEntry struct {
func NewLRUCache(capacity uint) *LRUCache {
return &LRUCache{
capacity: capacity,
entries: make(map[interface{}]lruEntry, capacity + 1),
entries: make(map[interface{}]*lruEntry, capacity + 1),
touched: NewLinkedList(),
}
}
Expand All @@ -35,21 +35,21 @@ func (lru *LRUCache) Put(key interface{}, value interface{}) {
if ok {
lru.touched.removeNode(entry.Node)
} else {
entry = lruEntry{
entry = &lruEntry{
Node: &llNode{},
Key: key,
Value: value,
}
}

entry.Node.payload = entry
entry.Value = value
lru.touched.addNodeFront(entry.Node)
lru.entries[key] = entry

if lru.touched.Length() > lru.capacity {
removed, ok := lru.touched.RemoveBack()
if ok {
delete(lru.entries, removed.(lruEntry).Key)
delete(lru.entries, removed.(*lruEntry).Key)
}
}
}
Expand All @@ -66,7 +66,7 @@ func (lru *LRUCache) Get(key interface{}) (interface{}, bool) {

lru.touched.removeNode(entry.Node)
lru.touched.addNodeFront(entry.Node)
return entry.Node.payload.(lruEntry).Value, true
return entry.Node.payload.(*lruEntry).Value, true
}

// Remove explicitly takes an item out of the cache.
Expand Down Expand Up @@ -97,7 +97,7 @@ func (lru *LRUCache) Enumerate(cancel <-chan struct{}) Enumerator {

for entry := range nested {
select {
case retval <- entry.(lruEntry).Value:
case retval <- entry.(*lruEntry).Value:
break
case <-cancel:
return
Expand All @@ -121,7 +121,7 @@ func (lru *LRUCache) EnumerateKeys(cancel <-chan struct{}) Enumerator {

for entry := range nested {
select {
case retval <- entry.(lruEntry).Key:
case retval <- entry.(*lruEntry).Key:
break
case <-cancel:
return
Expand Down
22 changes: 22 additions & 0 deletions lru_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,28 @@ package collection

import "testing"

func TestLRUCache_Put_replace(t *testing.T) {
const key = 1
const firstPut = "first"
const secondPut = "second"

subject := NewLRUCache(10)
subject.Put(key, firstPut)
subject.Put(key, secondPut)

want := secondPut
got, ok := subject.Get(key)
if !ok {
t.Logf("key should have been present")
t.Fail()
}

if got != want {
t.Logf("Unexpected result\n\tgot: %s\n\twant: %s", got, want)
t.Fail()
}
}

func TestLRUCache_Remove_empty(t *testing.T) {
subject := NewLRUCache(10)
got := subject.Remove(7)
Expand Down

0 comments on commit cdc8d77

Please sign in to comment.