From 11d4b357743479e0650a5efbaf5536c62f7b576d Mon Sep 17 00:00:00 2001 From: Andrey Ivanov Date: Tue, 23 Jun 2020 14:45:11 +0300 Subject: [PATCH] HW4 is completed --- hw04_lru_cache/cache.go | 26 +++++++++++++++++++------- hw04_lru_cache/cache_test.go | 7 +++---- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/hw04_lru_cache/cache.go b/hw04_lru_cache/cache.go index dd93cfd..1d8288e 100644 --- a/hw04_lru_cache/cache.go +++ b/hw04_lru_cache/cache.go @@ -1,4 +1,5 @@ package hw04_lru_cache //nolint:golint,stylecheck +import "sync" type Key string @@ -12,6 +13,7 @@ type lruCache struct { capacity int queue *List items map[Key]*ListItem + mx sync.RWMutex } type Item struct { @@ -23,25 +25,33 @@ func NewCache(capacity int) Cache { return &lruCache{ capacity: capacity, queue: NewList(), - items: map[Key]*ListItem{}, + items: make(map[Key]*ListItem), } } func (l *lruCache) Set(key Key, value interface{}) bool { - if _, exists := l.Get(key); exists { - l.items[key].Value = value + if _, exists := l.items[key]; exists { + l.mx.RLock() + l.items[key].Value = Item{Value: value, Key: key} + l.queue.MoveToFront(l.items[key]) + l.mx.RUnlock() return exists } - if l.queue.Len() >= l.capacity { - // TODO: нужно как-то удалить элемент из мапа - //delete(l.items,l.queue.Back().(*Item).Key) + if l.queue.Len() == l.capacity { + l.mx.RLock() + delete(l.items, l.queue.Back().Value.(Item).Key) l.queue.Remove(l.queue.Back()) + l.mx.RUnlock() } - l.items[key] = l.queue.PushFront(value) + l.mx.RLock() + l.items[key] = l.queue.PushFront(Item{Value: value, Key: key}) + l.mx.RUnlock() return false } func (l *lruCache) Get(key Key) (interface{}, bool) { + l.mx.Lock() + defer l.mx.Unlock() if l.items[key] == nil { return nil, false } @@ -50,7 +60,9 @@ func (l *lruCache) Get(key Key) (interface{}, bool) { } func (l *lruCache) Clear() { + l.mx.Lock() l.items = nil l.queue.len = 0 l.queue.Info = ListItem{} + l.mx.Unlock() } diff --git a/hw04_lru_cache/cache_test.go b/hw04_lru_cache/cache_test.go index fd3ea5c..c16cf82 100644 --- a/hw04_lru_cache/cache_test.go +++ b/hw04_lru_cache/cache_test.go @@ -31,18 +31,18 @@ func TestCache(t *testing.T) { val, ok := c.Get("aaa") require.True(t, ok) - require.Equal(t, 100, val) + require.Equal(t, 100, val.(Item).Value) val, ok = c.Get("bbb") require.True(t, ok) - require.Equal(t, 200, val) + require.Equal(t, 200, val.(Item).Value) wasInCache = c.Set("aaa", 300) require.True(t, wasInCache) val, ok = c.Get("aaa") require.True(t, ok) - require.Equal(t, 300, val) + require.Equal(t, 300, val.(Item).Value) val, ok = c.Get("ccc") require.False(t, ok) @@ -79,7 +79,6 @@ func TestCache(t *testing.T) { } func TestCacheMultithreading(t *testing.T) { - t.Skip() // Remove if task with asterisk completed c := NewCache(10) wg := &sync.WaitGroup{}