Skip to content

Commit

Permalink
Merge pull request #116 from vaskoz/day52
Browse files Browse the repository at this point in the history
Day52
  • Loading branch information
vaskoz committed Oct 14, 2018
2 parents 81fdcb0 + 66874e3 commit 111726c
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,5 @@ problems from
* [Day 47](https://github.com/vaskoz/dailycodingproblem-go/issues/105)
* [Day 49](https://github.com/vaskoz/dailycodingproblem-go/issues/107)
* [Day 50](https://github.com/vaskoz/dailycodingproblem-go/issues/110)
* [Day 52](https://github.com/vaskoz/dailycodingproblem-go/issues/113)
* [Day 53](https://github.com/vaskoz/dailycodingproblem-go/issues/114)
49 changes: 49 additions & 0 deletions day52/problem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package day52

import (
"container/list"
)

// Cache specifies a generic cache interface of key-value pairs.
type Cache interface {
Set(key, value interface{})
Get(key interface{}) interface{}
}

type kvPair struct {
k, v interface{}
}

type lruCache struct {
data map[interface{}]*list.Element
l *list.List
capacity int
}

func (lc *lruCache) Set(key interface{}, value interface{}) {
if elem, found := lc.data[key]; found {
lc.l.MoveToFront(elem)
elem.Value = kvPair{k: key, v: value}
return
}
if len(lc.data) == lc.capacity { // evict oldest
oldest := lc.l.Back()
delete(lc.data, oldest.Value.(kvPair).k)
lc.l.Remove(oldest)
}
e := lc.l.PushFront(kvPair{k: key, v: value})
lc.data[key] = e
}

func (lc *lruCache) Get(key interface{}) interface{} {
if elem, found := lc.data[key]; found {
lc.l.MoveToFront(elem)
return elem.Value.(kvPair).v
}
return nil
}

// NewLRU returns a Cache implementation that behaves as a LRU.
func NewLRU(capacity int) Cache {
return &lruCache{make(map[interface{}]*list.Element), list.New(), capacity}
}
49 changes: 49 additions & 0 deletions day52/problem_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package day52

import "testing"

func TestLRUCache(t *testing.T) {
lru := NewLRU(3)
for i := 0; i < 6; i++ {
lru.Set(i, i+1)
}
for i := 0; i < 3; i++ {
if v := lru.Get(i); v != nil {
t.Errorf("Expected these to be evicted")
}
}
for i := 3; i < 6; i++ {
if v := lru.Get(i); v != i+1 {
t.Errorf("Expected the values to remain")
}
}
for i := 3; i < 6; i++ {
lru.Set(i, 10*i)
}
for i := 3; i < 6; i++ {
if v := lru.Get(i); v != i*10 {
t.Errorf("Expected the values to modify")
}
}
}

func BenchmarkLRUCache(b *testing.B) {
lru := NewLRU(3)
for bm := 0; bm < b.N; bm++ {
for i := 0; i < 6; i++ {
lru.Set(i, i+1)
}
for i := 0; i < 3; i++ {
lru.Get(i)
}
for i := 3; i < 6; i++ {
lru.Get(i)
}
for i := 3; i < 6; i++ {
lru.Set(i, 10*i)
}
for i := 3; i < 6; i++ {
lru.Get(i)
}
}
}

0 comments on commit 111726c

Please sign in to comment.