1
0
Fork 0

Add file cache implementation

This commit is contained in:
Gregory Eremin 2018-06-17 13:34:01 +02:00
parent 611b508425
commit df01f2eed7
No known key found for this signature in database
GPG Key ID: 8CB79D42167BEB7F
2 changed files with 75 additions and 0 deletions

30
filecache/filecache.go Normal file
View File

@ -0,0 +1,30 @@
package filecache
import (
"encoding/json"
"io/ioutil"
"os"
"reflect"
)
// Load will look for a given file. If it exists, it would unmarshal its
// contents into the given value. If the file does not exist, a supplied
// function would be called and its output would be written to a file.
func Load(val interface{}, filename string, fn func() interface{}) error {
_, err := os.Stat(filename)
if os.IsNotExist(err) {
out := fn()
reflect.ValueOf(val).Elem().Set(reflect.ValueOf(out))
body, err := json.Marshal(val)
if err != nil {
return err
}
return ioutil.WriteFile(filename, body, 0766)
}
body, err := ioutil.ReadFile(filename)
if err != nil {
return err
}
return json.Unmarshal(body, val)
}

View File

@ -0,0 +1,45 @@
package filecache
import (
"io/ioutil"
"os"
"testing"
)
func TestFileCache(t *testing.T) {
filename := getTempFileName(t)
const exp = 100
var res int
var nCalled int
for i := 0; i < 10; i++ {
err := Load(&res, filename, func() interface{} {
nCalled++
return exp
})
if err != nil {
t.Fatalf("Error occurred while loading cache: %v", err)
}
if res != exp {
t.Errorf("Expected %d, got %d", exp, res)
}
}
if nCalled != 1 {
t.Errorf("Epected a function to be called once, was called %d times", nCalled)
}
}
func getTempFileName(t *testing.T) string {
t.Helper()
fd, err := ioutil.TempFile("", "filecache")
if err != nil {
t.Fatalf("Failed to create a temporary file: %v", err)
}
if err := fd.Close(); err != nil {
t.Fatalf("Failed to close temporary file: %v", err)
}
if err := os.Remove(fd.Name()); err != nil {
t.Fatalf("Failed to delete temporary file: %v", err)
}
return fd.Name()
}