simple store implementation
[epoint] / store / store.go
1 package store
2
3 // persistent key-value store
4 // TODO: thread safety, persistence, efficient update and query, incremental backup
5
6 import (
7         "fmt"
8         "os"
9         "path/filepath"
10         "io/ioutil"
11         "sync"
12 )
13
14
15 type Conn struct {
16         name string
17         path string
18         mutex sync.RWMutex
19         memstore map[string][]byte
20 }
21
22 func Open(name string) (c *Conn, err error) {
23         c = new(Conn)
24         c.memstore = make(map[string][]byte)
25         c.name = name
26         c.path, err = filepath.Abs(name)
27         if err != nil {
28                 return
29         }
30         err = os.MkdirAll(c.path, 0755)
31         if err != nil {
32                 return
33         }
34         err = filepath.Walk(c.path, func(path string, info *os.FileInfo, err error) error {
35                 if info.IsDirectory() {
36                         if info.Name == c.name {
37                                 return nil
38                         }
39                         return filepath.SkipDir
40                 }
41                 if err != nil {
42                         return err
43                 }
44                 k := info.Name
45                 v, err := ioutil.ReadFile(filepath.Join(c.path, k))
46                 if err != nil {
47                         return err
48                 }
49                 c.memstore[k] = v
50                 return nil
51         })
52         return
53 }
54
55 func (c *Conn) Get(k string) (v []byte, err error) {
56         c.mutex.RLock()
57         defer c.mutex.RUnlock()
58         v, ok := c.memstore[k]
59         if !ok {
60                 err = fmt.Errorf("key not found")
61         }
62         return
63 }
64
65 func (c *Conn) Set(k string, v []byte) (err error) {
66         c.mutex.Lock()
67         defer c.mutex.Unlock()
68         f, err := os.Create(filepath.Join(c.path, k))
69         if err != nil {
70                 return
71         }
72         _, err = f.Write(v)
73         if err != nil {
74                 return
75         }
76         c.memstore[k] = v
77         return
78 }
79
80 func (c *Conn) Close() (err error) {
81         return
82 }