-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcache.go
More file actions
93 lines (76 loc) · 1.89 KB
/
cache.go
File metadata and controls
93 lines (76 loc) · 1.89 KB
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package cache
import (
"container/list"
"time"
)
// Cache is a LRU replacement cache
type Cache struct {
store Store
ll *list.List
size int
}
// New returns an initialized LRU Cache
func New(size int, store Store) *Cache {
ll := list.New()
return &Cache{store: store, ll: ll, size: size}
}
// Node maps key to value
type node struct {
key string
value string
expiresAt int
}
// Set inserts the value for the given key in the cache. It overrides old value
// if this keys already exists in the cache
func (c *Cache) Set(key, value string, expiresAt int) {
current, exists := c.store.Get(key)
if exists {
// override existing values
current.Value.(*node).value = value
current.Value.(*node).expiresAt = expiresAt
c.ll.MoveToFront(current)
return
}
// If cache is full remove LRU node(key, value)
if c.size != 0 && (c.ll.Len() == c.size) {
lastElement := c.ll.Back()
c.ll.Remove(lastElement)
c.store.Delete(lastElement.Value.(*node).key)
}
n := &node{key, value, expiresAt}
e := c.ll.PushFront(n)
c.store.Set(key, e)
}
// Get returns the value for the given key. It returns the value and true if found
// but false if otherwise
func (c *Cache) Get(key string) (string, bool) {
element, exists := c.store.Get(key)
if !exists {
return "", false
}
expire := element.Value.(*node).expiresAt
if expire == 0 || expire < int(time.Now().Unix()) {
return "", false
}
c.ll.MoveToFront(element)
return element.Value.(*node).value, true
}
// Delete removes the key-value from the cache.
// It is a noop if no match is found.
func (c *Cache) Delete(key string) {
element, exists := c.store.Get(key)
if !exists {
return
}
c.ll.Remove(element)
c.store.Delete(key)
}
// Size returns the size of the cache
func (c *Cache) Size() int {
return c.size
}
// Has checks if key exists in cache
func (c *Cache) Has(key string) bool {
_, exist := c.store.Get(key)
return exist
}