-
Notifications
You must be signed in to change notification settings - Fork 15
/
cache.go
54 lines (49 loc) · 986 Bytes
/
cache.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package main
import (
"errors"
"image"
"sync"
)
type RGBACache struct {
mu *sync.RWMutex
cache []*image.RGBA
size int
curr int
keymap map[string]int
}
func NewRGBACache(size int) *RGBACache {
return &RGBACache{
cache: make([]*image.RGBA, size),
size: size,
keymap: make(map[string]int),
mu: &sync.RWMutex{},
}
}
func (c *RGBACache) Get(key string) (im *image.RGBA, exists bool) {
c.mu.RLock()
defer c.mu.RUnlock()
v, exists := c.keymap[key]
return c.cache[v], exists
}
func (c *RGBACache) Put(key string, im *image.RGBA) error {
c.mu.Lock()
defer c.mu.Unlock()
if _, exists := c.keymap[key]; exists {
return errors.New("key already exists")
}
if len(c.keymap) >= c.size {
rmidx := (c.curr + c.size - 1) % c.size
rmkey := ""
for k, idx := range c.keymap {
if idx == rmidx {
rmkey = k
break
}
}
delete(c.keymap, rmkey)
}
c.curr = (c.curr + 1) % c.size
c.cache[c.curr] = im
c.keymap[key] = c.curr
return nil
}