mirror of https://github.com/mpolden/echoip
cache: Reduce memory usage
This commit is contained in:
parent
bd8b1c7b97
commit
df49848167
|
@ -10,19 +10,18 @@ import (
|
||||||
type Cache struct {
|
type Cache struct {
|
||||||
capacity int
|
capacity int
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
entries map[uint64]Response
|
entries map[uint64]*list.Element
|
||||||
keys *list.List
|
values *list.List
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCache(capacity int) *Cache {
|
func NewCache(capacity int) *Cache {
|
||||||
if capacity < 0 {
|
if capacity < 0 {
|
||||||
capacity = 0
|
capacity = 0
|
||||||
}
|
}
|
||||||
keys := list.New()
|
|
||||||
return &Cache{
|
return &Cache{
|
||||||
capacity: capacity,
|
capacity: capacity,
|
||||||
entries: make(map[uint64]Response),
|
entries: make(map[uint64]*list.Element),
|
||||||
keys: keys,
|
values: list.New(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,12 +40,17 @@ func (c *Cache) Set(ip net.IP, resp Response) {
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
if len(c.entries) == c.capacity {
|
if len(c.entries) == c.capacity {
|
||||||
// At capacity. Remove the oldest entry
|
// At capacity. Remove the oldest entry
|
||||||
oldest := c.keys.Front()
|
oldest := c.values.Front()
|
||||||
delete(c.entries, oldest.Value.(uint64))
|
oldestValue := oldest.Value.(Response)
|
||||||
c.keys.Remove(oldest)
|
oldestKey := key(oldestValue.IP)
|
||||||
|
delete(c.entries, oldestKey)
|
||||||
|
c.values.Remove(oldest)
|
||||||
}
|
}
|
||||||
c.entries[k] = resp
|
current, ok := c.entries[k]
|
||||||
c.keys.PushBack(k)
|
if ok {
|
||||||
|
c.values.Remove(current)
|
||||||
|
}
|
||||||
|
c.entries[k] = c.values.PushBack(resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cache) Get(ip net.IP) (Response, bool) {
|
func (c *Cache) Get(ip net.IP) (Response, bool) {
|
||||||
|
@ -54,5 +58,8 @@ func (c *Cache) Get(ip net.IP) (Response, bool) {
|
||||||
c.mu.RLock()
|
c.mu.RLock()
|
||||||
defer c.mu.RUnlock()
|
defer c.mu.RUnlock()
|
||||||
r, ok := c.entries[k]
|
r, ok := c.entries[k]
|
||||||
return r, ok
|
if !ok {
|
||||||
|
return Response{}, false
|
||||||
|
}
|
||||||
|
return r.Value.(Response), true
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,3 +39,18 @@ func TestCacheCapacity(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCacheDuplicate(t *testing.T) {
|
||||||
|
c := NewCache(10)
|
||||||
|
ip := net.ParseIP("192.0.2.1")
|
||||||
|
response := Response{IP: ip}
|
||||||
|
c.Set(ip, response)
|
||||||
|
c.Set(ip, response)
|
||||||
|
want := 1
|
||||||
|
if got := len(c.entries); got != want {
|
||||||
|
t.Errorf("want %d entries, got %d", want, got)
|
||||||
|
}
|
||||||
|
if got := c.values.Len(); got != want {
|
||||||
|
t.Errorf("want %d values, got %d", want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue