simple store implementation
authornsz <nsz@port70.net>
Wed, 16 Nov 2011 11:14:13 +0000 (12:14 +0100)
committernsz <nsz@port70.net>
Wed, 16 Nov 2011 11:14:13 +0000 (12:14 +0100)
store/store.go [new file with mode: 0644]

diff --git a/store/store.go b/store/store.go
new file mode 100644 (file)
index 0000000..48614f2
--- /dev/null
@@ -0,0 +1,82 @@
+package store
+
+// persistent key-value store
+// TODO: thread safety, persistence, efficient update and query, incremental backup
+
+import (
+       "fmt"
+       "os"
+       "path/filepath"
+       "io/ioutil"
+       "sync"
+)
+
+
+type Conn struct {
+       name string
+       path string
+       mutex sync.RWMutex
+       memstore map[string][]byte
+}
+
+func Open(name string) (c *Conn, err error) {
+       c = new(Conn)
+       c.memstore = make(map[string][]byte)
+       c.name = name
+       c.path, err = filepath.Abs(name)
+       if err != nil {
+               return
+       }
+       err = os.MkdirAll(c.path, 0755)
+       if err != nil {
+               return
+       }
+       err = filepath.Walk(c.path, func(path string, info *os.FileInfo, err error) error {
+               if info.IsDirectory() {
+                       if info.Name == c.name {
+                               return nil
+                       }
+                       return filepath.SkipDir
+               }
+               if err != nil {
+                       return err
+               }
+               k := info.Name
+               v, err := ioutil.ReadFile(filepath.Join(c.path, k))
+               if err != nil {
+                       return err
+               }
+               c.memstore[k] = v
+               return nil
+       })
+       return
+}
+
+func (c *Conn) Get(k string) (v []byte, err error) {
+       c.mutex.RLock()
+       defer c.mutex.RUnlock()
+       v, ok := c.memstore[k]
+       if !ok {
+               err = fmt.Errorf("key not found")
+       }
+       return
+}
+
+func (c *Conn) Set(k string, v []byte) (err error) {
+       c.mutex.Lock()
+       defer c.mutex.Unlock()
+       f, err := os.Create(filepath.Join(c.path, k))
+       if err != nil {
+               return
+       }
+       _, err = f.Write(v)
+       if err != nil {
+               return
+       }
+       c.memstore[k] = v
+       return
+}
+
+func (c *Conn) Close() (err error) {
+       return
+}