Passed
Pull Request — main (#71)
by Yume
01:16
created

pkg/cache/cache.go   A

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 25
eloc 99
dl 0
loc 155
rs 10
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A cache.*Cache.DeleteItem 0 15 3
A cache.*Cache.Size 0 2 1
A cache.*Cache.AppendSlice 0 11 3
A cache.*cacheItem.Size 0 2 1
A cache.runCron 0 5 2
A cache.NewCache 0 9 1
A cache.*Cache.Replace 0 9 2
A cache.*Cache.Get 0 8 2
A cache.*Cache.Items 0 13 3
A cache.*Cache.Set 0 5 1
A cache.*Cache.SetSlice 0 8 2
A cache.*Cache.Flush 0 4 1
A cache.*Cache.Exists 0 5 1
A cache.*Cache.Delete 0 9 2
1
package cache
2
3
import (
4
	"fmt"
5
	"github.com/memnix/memnixrest/pkg/models"
6
	"github.com/robfig/cron/v3"
7
	"sync"
8
)
9
10
type Cache struct {
11
	// Cache map
12
	c    map[uint]cacheItem
13
	mu   sync.RWMutex
14
	cron *cron.Cron
15
}
16
17
type cacheItem struct {
18
	Object map[uint]models.MemDate
19
}
20
21
func (c *Cache) Flush() {
22
	c.mu.Lock()
23
	defer c.mu.Unlock()
24
	c.c = make(map[uint]cacheItem)
25
}
26
27
func (c *Cache) Set(key uint, value map[uint]models.MemDate) {
28
	c.mu.Lock()
29
	defer c.mu.Unlock()
30
	c.c[key] = cacheItem{
31
		Object: value,
32
	}
33
}
34
35
func (c *Cache) SetSlice(key uint, value []models.MemDate) {
36
	c.mu.Lock()
37
	defer c.mu.Unlock()
38
	c.c[key] = cacheItem{
39
		Object: make(map[uint]models.MemDate, len(value)),
40
	}
41
	for _, v := range value {
42
		c.c[key].Object[v.ID] = v
43
	}
44
}
45
46
func (c *Cache) AppendSlice(key uint, value []models.MemDate) {
47
	c.mu.Lock()
48
	defer c.mu.Unlock()
49
	_, found := c.c[key]
50
	if !found {
51
		c.c[key] = cacheItem{
52
			Object: make(map[uint]models.MemDate, len(value)),
53
		}
54
	}
55
	for _, v := range value {
56
		c.c[key].Object[v.ID] = v
57
	}
58
}
59
60
// Items in cache
61
func (c *Cache) Items(key uint) []models.MemDate {
62
	c.mu.RLock()
63
	defer c.mu.RUnlock()
64
	item, found := c.c[key]
65
	if !found {
66
		return nil
67
	}
68
	memDates := make([]models.MemDate, 0, item.Size())
69
70
	for _, v := range item.Object {
71
		memDates = append(memDates, v)
72
	}
73
	return memDates
74
}
75
76
func (c *Cache) Replace(key uint, item models.MemDate) {
77
	c.mu.Lock()
78
	defer c.mu.Unlock()
79
	_, found := c.c[key]
80
	if !found {
81
		return
82
	}
83
84
	c.c[key].Object[item.ID] = item
85
}
86
87
func (c *Cache) Exists(key uint) bool {
88
	c.mu.RLock()
89
	defer c.mu.RUnlock()
90
	_, found := c.c[key]
91
	return found
92
}
93
94
func (c *Cache) Get(key uint) (map[uint]models.MemDate, error) {
95
	c.mu.RLock()
96
	defer c.mu.RUnlock()
97
	item, found := c.c[key]
98
	if !found {
99
		return nil, fmt.Errorf("key not found")
100
	}
101
	return item.Object, nil
102
}
103
104
func (c *Cache) Delete(key uint) error {
105
	c.mu.Lock()
106
	defer c.mu.Unlock()
107
	_, found := c.c[key]
108
	if !found {
109
		return fmt.Errorf("key not found")
110
	}
111
	delete(c.c, key)
112
	return nil
113
}
114
115
func (c *Cache) Size() int {
116
	return len(c.c)
117
}
118
119
func (cacheItem *cacheItem) Size() int {
120
	return len(cacheItem.Object)
121
}
122
123
func (c *Cache) DeleteItem(key uint, item uint) error {
124
	c.mu.Lock()
125
	defer c.mu.Unlock()
126
	_, found := c.c[key]
127
	if !found {
128
		return fmt.Errorf("key not found")
129
	}
130
131
	_, found = c.c[key].Object[item]
132
	if !found {
133
		return fmt.Errorf("item not found")
134
	}
135
136
	delete(c.c[key].Object, item)
137
	return nil
138
}
139
140
func runCron(c *Cache) {
141
	_, _ = c.cron.AddFunc("@daily", func() {
142
		c.Flush()
143
	})
144
	c.cron.Start()
145
}
146
147
func NewCache() *Cache {
148
	cache := &Cache{
149
		c:    make(map[uint]cacheItem),
150
		cron: cron.New(),
151
	}
152
153
	runCron(cache)
154
155
	return cache
156
}
157