-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathcache.go
98 lines (78 loc) · 2.16 KB
/
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
91
92
93
94
95
96
97
98
package main
import (
"bytes"
"encoding/gob"
"strings"
"github.com/coocood/freecache"
)
const (
defaultCacheSize = 1000 << 20 // 1000 MB cache
defaultExpiry = 120 * 3600 // 120 hours cache expiry
stringSeparator = "<>" // Assuming the separator wont be used in any case.
)
// Cache objects.
type Cache struct {
fc *freecache.Cache
}
type GeneralCacheItem struct {
Value interface{}
}
// NewCache will create a new freecache
func NewCache() Cache {
return Cache{fc: freecache.NewCache(defaultCacheSize)}
}
// Set a string value to cache.
func (c *Cache) SetString(key string, val ...string) error {
var value = strings.Join(val, stringSeparator)
return c.setWithExpiry(key, []byte(value), int(defaultExpiry))
}
func (c *Cache) setWithExpiry(key string, val []byte, expiry int) error {
return c.fc.Set([]byte(key), val, expiry)
}
// Get a string value from cache.
func (c *Cache) GetString(key string) ([]string, error) {
val, err := c.fc.Get([]byte(key))
if err != nil {
return nil, err
}
return strings.Split(string(val), stringSeparator), nil
}
// Set a generic cache value.
// These are about 100 micro-seconds (3 times) slower
// than the string cache above. It's slower because of
// encoding and decoding
func (c *Cache) Set(key string, value interface{}) error {
var valueBytesBuffer bytes.Buffer
// gob can only encode struct items.
// It can't encode arrays properly
cacheItem := GeneralCacheItem{value}
enc := gob.NewEncoder(&valueBytesBuffer)
err := enc.Encode(cacheItem)
if err != nil {
return err
}
return c.fc.Set([]byte(key), valueBytesBuffer.Bytes(), int(defaultExpiry))
}
// Get a value from cache.
func (c *Cache) Get(key string) (interface{}, error) {
valueBytes, err := c.fc.Get([]byte(key))
if err != nil {
return nil, err
}
var cacheItem GeneralCacheItem
dec := gob.NewDecoder(bytes.NewReader(valueBytes))
err = dec.Decode(&cacheItem)
if err != nil {
return nil, err
}
return cacheItem.Value, nil
}
// Delete a value from cache.
func (c *Cache) Delete(key string) (bool, error) {
affected := c.fc.Del([]byte(key))
return affected, nil
}
// Clear everything in the cache.
func (c *Cache) Clear() {
c.fc.Clear()
}