Skip to content

Commit

Permalink
HW4 is completed
Browse files Browse the repository at this point in the history
Signed-off-by: Pavel Pogodaev <[email protected]>
  • Loading branch information
Pavel Pogodaev committed Jul 5, 2024
1 parent 411b524 commit 1d17c2f
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 6 deletions.
45 changes: 43 additions & 2 deletions hw04_lru_cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,54 @@ type Cache interface {
}

type lruCache struct {
Cache // Remove me after realization.

capacity int
queue List
items map[Key]*ListItem
}

type cacheItem struct {
key Key
value interface{}
}

func (l *lruCache) Set(key Key, value interface{}) bool {
listItem, success := l.items[key]
if success {
listItem.Value = cacheItem{
key: key,
value: value,
}
l.queue.MoveToFront(listItem)
return true
}

l.items[key] = l.queue.PushFront(cacheItem{
key: key,
value: value,
})

if l.queue.Len() > l.capacity {
deleteItem := l.queue.Back()
l.queue.Remove(deleteItem)
delete(l.items, deleteItem.Value.(cacheItem).key)
}
return success
}

func (l *lruCache) Get(key Key) (interface{}, bool) {
listItem, ok := l.items[key]
if ok {
l.queue.MoveToFront(listItem)
return listItem.Value.(cacheItem).value, ok
}
return listItem, ok
}

func (l *lruCache) Clear() {
l.queue = NewList()
l.items = make(map[Key]*ListItem, l.capacity)
}

func NewCache(capacity int) Cache {
return &lruCache{
capacity: capacity,
Expand Down
30 changes: 29 additions & 1 deletion hw04_lru_cache/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,35 @@ func TestCache(t *testing.T) {
})

t.Run("purge logic", func(t *testing.T) {
// Write me
c := NewCache(3)

wasInCache := c.Set("Antony", 1)
require.False(t, wasInCache)

wasInCache = c.Set("Bob", 2)
require.False(t, wasInCache)

wasInCache = c.Set("Ci", 3)
require.False(t, wasInCache)

val, ok := c.Get("Ci")
require.True(t, ok)
require.Equal(t, 3, val)

val, ok = c.Get("Bob")
require.True(t, ok)
require.Equal(t, 2, val)

val, ok = c.Get("Antony")
require.True(t, ok)
require.Equal(t, 1, val)

wasInCache = c.Set("Daddy", 4)
require.False(t, wasInCache)

val, ok = c.Get("ccc")
require.False(t, ok)
require.Nil(t, val)
})
}

Expand Down
2 changes: 1 addition & 1 deletion hw04_lru_cache/go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/fixme_my_friend/hw04_lru_cache
module github.com/pogpp/home_works/hw04_lru_cache

go 1.22

Expand Down
81 changes: 79 additions & 2 deletions hw04_lru_cache/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,85 @@ type ListItem struct {
}

type list struct {
List // Remove me after realization.
// Place your code here.
head *ListItem // Указатель на первый элемент
tail *ListItem // Указатель на последний элемент
size int
}

func (l *list) Len() int {
return l.size
}

func (l *list) Front() *ListItem {
return l.head
}

func (l *list) Back() *ListItem {
return l.tail
}

func (l *list) PushFront(v interface{}) *ListItem {
oldFrontItem := l.Front()
item := &ListItem{v, oldFrontItem, nil}

if oldFrontItem != nil {
oldFrontItem.Prev = item
}

l.head = item
if l.Back() == nil {
l.tail = item
}
l.size++
return item
}

func (l *list) PushBack(v interface{}) *ListItem {
oldTailItem := l.Back()
item := &ListItem{
Value: v,
Next: nil,
Prev: oldTailItem,
}
if oldTailItem != nil {
oldTailItem.Next = item
}

l.tail = item
if l.Front() == nil {
l.head = item
}

l.size++
return item
}

func (l *list) Remove(i *ListItem) {
nextItem := i.Next
prevItem := i.Prev

if prevItem != nil {
prevItem.Next = nextItem
}

if nextItem != nil {
nextItem.Prev = prevItem
}

if l.Front() == i && nextItem != nil {
l.head = nextItem
}

if l.Back() == i && prevItem != nil {
l.tail = prevItem
}

l.size--
}

func (l *list) MoveToFront(i *ListItem) {
l.Remove(i)
l.PushFront(i.Value)
}

func NewList() List {
Expand Down

0 comments on commit 1d17c2f

Please sign in to comment.