store module and unit test for store

release-0.4 0
Xiang Li 2013-06-06 17:43:32 -07:00
commit 20ca21a3f7
3 changed files with 205 additions and 0 deletions

74
store.go Normal file
View File

@ -0,0 +1,74 @@
package raftd
import (
"path"
"errors"
"encoding/json"
)
type Store struct {
Nodes map[string]string `json:"nodes"`
}
func createStore() *Store{
s := new(Store)
s.Nodes = make(map[string]string)
return s
}
// set the key to value, return the old value if the key exists
func (s *Store) Set(key string, value string) (string, bool) {
key = path.Clean(key)
oldValue, ok := s.Nodes[key]
if ok {
s.Nodes[key] = value
return oldValue, true
} else {
s.Nodes[key] = value
return "", false
}
}
// get the node of the key
func (s *Store) Get(key string) (string, error) {
key = path.Clean(key)
value, ok := s.Nodes[key]
if ok {
return value, nil
} else {
return "", errors.New("Key does not exist")
}
}
// delete the key, return the old value if the key exists
func (s *Store) Delete(key string) (string, error) {
key = path.Clean(key)
oldValue, ok := s.Nodes[key]
if ok {
delete(s.Nodes, key)
return oldValue, nil
} else {
return "", errors.New("Key does not exist")
}
}
func (s *Store) Save() ([]byte, error) {
b, err := json.Marshal(s)
if err != nil {
return nil, err
}
return b, nil
}
func (s *Store) Recovery(state []byte) error {
err := json.Unmarshal(state, s)
return err
}

46
store_test.go Normal file
View File

@ -0,0 +1,46 @@
package raftd
import (
"testing"
)
func TestStoreGet(t *testing.T) {
store := createStore()
store.Set("foo", "bar")
value, err := store.Get("foo")
if err!= nil || value != "bar" {
t.Fatalf("Cannot get stored value")
}
store.Delete("foo")
value, err = store.Get("foo")
if err == nil{
t.Fatalf("Got deleted value")
}
}
func TestSaveAndRecovery(t *testing.T) {
store := createStore()
store.Set("foo", "bar")
state, err := store.Save()
if err != nil {
t.Fatalf("Cannot Save")
}
newStore := createStore()
newStore.Recovery(state)
value, err := newStore.Get("foo")
if err!= nil || value != "bar" {
t.Fatalf("Cannot recovery")
}
}

85
tree_store.bak Normal file
View File

@ -0,0 +1,85 @@
package main
import (
"path"
"strings"
)
type store struct {
nodes map[string]node
}
type node struct {
value string
dir bool // just for clearity
nodes map[string]node
}
// set the key to value, return the old value if the key exists
func (s *store) set(key string, value string) string, error {
key = path.Clean(key)
nodeNames := strings.Split(key, "/")
levelNodes := s.nodes
for i = 0; i < len(nodes) - 1; ++i {
node, ok := levelNodes[nodeNames[i]]
// add new dir
if !ok {
node := Node{nodeNames[i], true, make(map[string]node)}
levelNodes[nodeNames[i]] := node
} else if ok && !node.dir {
return nil, errors.New("The key is a directory")
}
else {
levelNodes = levelNodes.nodes
}
}
// add the last node and value
node, ok := levelNodes[nodeNames[i]]
if !ok {
node := Node{nodeNames[i], false, nil}
levelNodes[nodeNames] = node
return nil, nil
} else {
oldValue := node.value
node.value = value
return oldValue ,nil
}
}
// get the node of the key
func (s *store) get(key string) node {
key = path.Clean(key)
nodeNames := strings.Split(key, "/")
levelNodes := s.nodes
for i = 0; i < len(nodes) - 1; ++i {
node, ok := levelNodes[nodeNames[i]]
if !ok || !node.dir {
return nil
}
levelNodes = levelNodes.nodes
}
node, ok := levelNodes[nodeNames[i]]
if ok {
return node
}
return nil
}
// delete the key, return the old value if the key exists
func (s *store) delete(key string) string {
return nil
}
func (n *node) Value() string{
return n.value
}