store simplification (use name,key->value so we can manage many k-v stores)
[epoint] / store / store.go
index 48614f2..2595f88 100644 (file)
@@ -1,29 +1,26 @@
 package store
 
 // persistent key-value store
-// TODO: thread safety, persistence, efficient update and query, incremental backup
+// multiple key-value store can be managed by a single db connection
+// each store has a name, before usage the name of the store must be
+// ensured to exist
+//
+// TODO: this is a toy implementation
 
 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) {
+func Open(root string) (c *Conn, err error) {
        c = new(Conn)
-       c.memstore = make(map[string][]byte)
-       c.name = name
-       c.path, err = filepath.Abs(name)
+       c.path, err = filepath.Abs(root)
        if err != nil {
                return
        }
@@ -31,49 +28,30 @@ func Open(name string) (c *Conn, err error) {
        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) Get(name, k string) (v []byte, err error) {
+       return ioutil.ReadFile(filepath.Join(c.path, name, k))
+}
+
+func (c *Conn) Ensure(name string) (err error) {
+       return os.MkdirAll(filepath.Join(c.path, name), 0755)
 }
 
-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))
+func (c *Conn) Set(name, k string, v []byte) (err error) {
+       fn := filepath.Join(c.path, name, k)
+       // os.O_SYNC
+       f, err := os.Create(fn+".tmp")
        if err != nil {
                return
        }
+       defer f.Close()
        _, err = f.Write(v)
        if err != nil {
                return
        }
-       c.memstore[k] = v
+       err = os.Rename(fn+".tmp", fn)
        return
 }