HW4 is completed
parent
89a2446cef
commit
11d4b35774
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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{}
|
||||
|
|
Loading…
Reference in New Issue