-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfileCache.go
155 lines (131 loc) · 3.18 KB
/
fileCache.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package simplegocache
import (
"errors"
"fmt"
"io/ioutil"
"log"
"os"
"time"
)
// FileCache - Contains references to cached objects
type FileCache struct {
CacheFolder string
TTL int64
Prefix string
Files map[string]File
}
// File - Contains info on a particular cached file
type File struct {
Path string
TTL int64
Created int64
}
// NewFileCache - Initiates a new file based cache
func NewFileCache(folder string, ttl int64, prefix string) (*FileCache, error) {
var tmpFolder string
tmpFolder, err := ioutil.TempDir(folder, prefix)
if err != nil {
log.Println("Unable to create temp folder for cache: " + err.Error())
}
return &FileCache{CacheFolder: tmpFolder, TTL: ttl, Prefix: prefix, Files: make(map[string]File)}, nil
}
// Close - Remove cached files
func (c *FileCache) Close() {
err := os.RemoveAll(c.CacheFolder)
if err != nil {
log.Println("Unable to remove tmp cache folder: " + err.Error())
}
for k := range c.Files {
delete(c.Files, k)
}
}
// AddToCache - Add []byte to cache with key
func (c *FileCache) AddToCache(content []byte, key string) error {
// check that file does not exist
if c.InCache(key) {
return errors.New("Key" + key + " already exists in map!")
}
tmpfile, err := ioutil.TempFile(c.CacheFolder, c.Prefix)
if err != nil {
fmt.Println("Encountered error while writing file: " + err.Error())
return err
}
c.Files[key] = File{
Path: tmpfile.Name(),
TTL: c.TTL,
Created: time.Now().Unix(),
}
_, err = tmpfile.Write(content)
if err != nil {
return err
}
return nil
}
// ReadFromCache - Read the value of a given key from cache
func (c *FileCache) ReadFromCache(key string) ([]byte, error) {
if c.InCache(key) {
content, err := ioutil.ReadFile(c.Files[key].Path)
if err != nil {
return []byte{}, err
}
return content, nil
}
return []byte{}, errors.New("Cannot find key: " + key + " in cache!")
}
// InCache - Check if a key is registered in cache
func (c *FileCache) InCache(key string) bool {
if _, ok := c.Files[key]; ok {
if c.expired(key) {
err := c.DeleteFromCache(key)
if err != nil {
log.Println("Unable to remove element from cache")
}
return false
}
return true
}
return false
}
// DeleteFromCache - Delete an object from cache
func (c *FileCache) DeleteFromCache(key string) error {
if _, ok := c.Files[key]; ok {
err := os.Remove(c.Files[key].Path)
if err != nil {
return err
}
delete(c.Files, key)
return nil
}
return errors.New("key doesn't exist in cache")
}
// UpdateCache - Update the contents of a key already in cache
func (c *FileCache) UpdateCache(content []byte, key string) error {
err := c.DeleteFromCache(key)
if err != nil {
return err
}
err = c.AddToCache(content, key)
if err != nil {
return err
}
return nil
}
// expired - checks if a cache entry has expired
func (c *FileCache) expired(key string) bool {
if (time.Now().Unix() - c.Files[key].Created) > c.Files[key].TTL {
return true
}
return false
}
// Prune - prunes items that have expired
func (c *FileCache) Prune() error {
for k := range c.Files {
if c.expired(k) {
err := c.DeleteFromCache(k)
if err != nil {
return err
}
}
}
return nil
}