-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathin-memory-cache.go
90 lines (77 loc) · 1.68 KB
/
in-memory-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
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
package inmemorycache
import (
"sync"
"time"
)
// item - cache item
type item struct {
data interface{}
expires int64
}
// Cache
type Cache struct {
close chan struct{}
items sync.Map
}
// New - constructor
func New(cleaningInterval time.Duration) *Cache {
cache := Cache{
close: make(chan struct{}),
}
go cache.cleanExpired(cleaningInterval)
return &cache
}
// cleanExpired - removing expired cache cleaning loop
func (c *Cache) cleanExpired(cleaningInterval time.Duration) {
ticker := time.NewTicker(cleaningInterval)
defer ticker.Stop()
for {
select {
case <-ticker.C:
now := time.Now().Unix()
c.items.Range(func(key, value interface{}) bool {
item := value.(item) //nolint
if item.expires != 0 && item.expires < now {
c.items.Delete(key)
}
return true
})
case <-c.close:
return
}
}
}
// Set - add value to cache
func (c *Cache) Set(key string, value interface{}) {
c.items.Store(key, item{
data: value,
})
}
// SetWithExpire - add value to cache with expiting time
func (c *Cache) SetWithExpire(key string, value interface{}, ttl time.Duration) {
c.items.Store(key, item{
data: value,
expires: time.Now().Add(ttl).Unix(),
})
}
// Get - get value from cache
func (c *Cache) Get(key string) interface{} {
value, exists := c.items.Load(key)
if !exists {
return nil
}
item := value.(item) //nolint
if item.expires != 0 && item.expires < time.Now().Unix() {
return nil
}
return item.data
}
// Delete - remove value from cache
func (c *Cache) Delete(key string) {
c.items.Delete(key)
}
// Close - removing expired cache cleaning loop and all cache items
func (c *Cache) Close() {
c.close <- struct{}{}
c.items = sync.Map{}
}