keystore - filememstore.go
1 package keystore
2
3 import (
4 "io"
5
6 "vimagination.zapto.org/memio"
7 )
8
9 // FileBackedMemStore combines both a FileStore and a MemStore
10 type FileBackedMemStore struct {
11 FileStore
12 memStore MemStore
13 }
14
15 // NewFileBackedMemStore create a new Store which uses the filesystem for
16 // permanent storage, but uses memory for caching
17 func NewFileBackedMemStore(baseDir, tmpDir string, mangler Mangler) (*FileBackedMemStore, error) {
18 fs := new(FileBackedMemStore)
19 if err := fs.init(baseDir, tmpDir, mangler); err != nil {
20 return nil, err
21 }
22 fs.memStore.init()
23 return fs, nil
24 }
25
26 // NewFileBackedMemStoreFromFileStore uses an existing FileStore to create a
27 // new File Backed Memory Store
28 func NewFileBackedMemStoreFromFileStore(filestore *FileStore) *FileBackedMemStore {
29 fs := &FileBackedMemStore{
30 FileStore: *filestore,
31 }
32 fs.memStore.init()
33 return fs
34 }
35
36 // Get retrieves a key from the Store, first looking in the memcache and then
37 // going to the filesystem
38 func (fs *FileBackedMemStore) Get(key string, r io.ReaderFrom) error {
39 err := fs.memStore.Get(key, r)
40 if err == ErrUnknownKey {
41 var buf memio.Buffer
42 err = fs.FileStore.Get(key, &buf)
43 if err == nil {
44 fs.memStore.set(key, buf)
45 _, err = r.ReadFrom(&buf)
46 }
47 }
48 return err
49 }
50
51 // Set stores the key in both the memcache and the filesystem
52 func (fs *FileBackedMemStore) Set(key string, w io.WriterTo) error {
53 var buf memio.Buffer
54 _, err := w.WriteTo(&buf)
55 if err != nil && err != io.EOF {
56 return err
57 }
58 fbuf := buf
59 if err = fs.FileStore.Set(key, &fbuf); err != nil {
60 return err
61 }
62 fs.memStore.set(key, buf)
63 return nil
64 }
65
66 // Remove deletes a key from both the memcache and the filesystem
67 func (fs *FileBackedMemStore) Remove(key string) error {
68 if err := fs.FileStore.Remove(key); err != nil {
69 return err
70 }
71 return fs.memStore.Remove(key)
72 }
73
74 // Clear removes keys from the memory cache. Specifying no keys removes all
75 // data
76 func (fs *FileBackedMemStore) Clear(keys ...string) {
77 fs.memStore.mu.Lock()
78 if len(keys) == 0 {
79 for key := range fs.memStore.data {
80 delete(fs.memStore.data, key)
81 }
82 } else {
83 for _, key := range keys {
84 delete(fs.memStore.data, key)
85 }
86 }
87 fs.memStore.mu.Unlock()
88 }
89
90 // Rename moves data from an existing key to a new, unused key
91 func (fs *FileBackedMemStore) Rename(oldkey, newkey string) error {
92 fs.memStore.mu.Lock()
93 if err := fs.FileStore.Rename(oldkey, newkey); err != nil {
94 fs.memStore.mu.Unlock()
95 return err
96 }
97 delete(fs.memStore.data, oldkey)
98 fs.memStore.mu.Unlock()
99 return nil
100 }