X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=store%2Fstore.go;h=2595f88213f479a80873d63fa3c5957f74826d33;hb=c89b19c863fc41c0312358a866aebd425f498c76;hp=48614f2b8fe6906294d2eba6069aa824df3a7142;hpb=20fddcfb4f87e47d9e49eef6ed32cd3c181d6d2b;p=epoint diff --git a/store/store.go b/store/store.go index 48614f2..2595f88 100644 --- a/store/store.go +++ b/store/store.go @@ -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 }