HW4 is completed

This commit is contained in:
Andrey Ivanov 2020-06-23 14:45:11 +03:00
parent 89a2446cef
commit 11d4b35774
2 changed files with 22 additions and 11 deletions

View File

@ -1,4 +1,5 @@
package hw04_lru_cache //nolint:golint,stylecheck package hw04_lru_cache //nolint:golint,stylecheck
import "sync"
type Key string type Key string
@ -12,6 +13,7 @@ type lruCache struct {
capacity int capacity int
queue *List queue *List
items map[Key]*ListItem items map[Key]*ListItem
mx sync.RWMutex
} }
type Item struct { type Item struct {
@ -23,25 +25,33 @@ func NewCache(capacity int) Cache {
return &lruCache{ return &lruCache{
capacity: capacity, capacity: capacity,
queue: NewList(), queue: NewList(),
items: map[Key]*ListItem{}, items: make(map[Key]*ListItem),
} }
} }
func (l *lruCache) Set(key Key, value interface{}) bool { func (l *lruCache) Set(key Key, value interface{}) bool {
if _, exists := l.Get(key); exists { if _, exists := l.items[key]; exists {
l.items[key].Value = value l.mx.RLock()
l.items[key].Value = Item{Value: value, Key: key}
l.queue.MoveToFront(l.items[key])
l.mx.RUnlock()
return exists return exists
} }
if l.queue.Len() >= l.capacity { if l.queue.Len() == l.capacity {
// TODO: нужно как-то удалить элемент из мапа l.mx.RLock()
//delete(l.items,l.queue.Back().(*Item).Key) delete(l.items, l.queue.Back().Value.(Item).Key)
l.queue.Remove(l.queue.Back()) 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 return false
} }
func (l *lruCache) Get(key Key) (interface{}, bool) { func (l *lruCache) Get(key Key) (interface{}, bool) {
l.mx.Lock()
defer l.mx.Unlock()
if l.items[key] == nil { if l.items[key] == nil {
return nil, false return nil, false
} }
@ -50,7 +60,9 @@ func (l *lruCache) Get(key Key) (interface{}, bool) {
} }
func (l *lruCache) Clear() { func (l *lruCache) Clear() {
l.mx.Lock()
l.items = nil l.items = nil
l.queue.len = 0 l.queue.len = 0
l.queue.Info = ListItem{} l.queue.Info = ListItem{}
l.mx.Unlock()
} }

View File

@ -31,18 +31,18 @@ func TestCache(t *testing.T) {
val, ok := c.Get("aaa") val, ok := c.Get("aaa")
require.True(t, ok) require.True(t, ok)
require.Equal(t, 100, val) require.Equal(t, 100, val.(Item).Value)
val, ok = c.Get("bbb") val, ok = c.Get("bbb")
require.True(t, ok) require.True(t, ok)
require.Equal(t, 200, val) require.Equal(t, 200, val.(Item).Value)
wasInCache = c.Set("aaa", 300) wasInCache = c.Set("aaa", 300)
require.True(t, wasInCache) require.True(t, wasInCache)
val, ok = c.Get("aaa") val, ok = c.Get("aaa")
require.True(t, ok) require.True(t, ok)
require.Equal(t, 300, val) require.Equal(t, 300, val.(Item).Value)
val, ok = c.Get("ccc") val, ok = c.Get("ccc")
require.False(t, ok) require.False(t, ok)
@ -79,7 +79,6 @@ func TestCache(t *testing.T) {
} }
func TestCacheMultithreading(t *testing.T) { func TestCacheMultithreading(t *testing.T) {
t.Skip() // Remove if task with asterisk completed
c := NewCache(10) c := NewCache(10)
wg := &sync.WaitGroup{} wg := &sync.WaitGroup{}