commit 20ca21a3f7122cf7caa91cb0e9b9c69be9279950 Author: Xiang Li Date: Thu Jun 6 17:43:32 2013 -0700 store module and unit test for store diff --git a/store.go b/store.go new file mode 100644 index 000000000..bc0d721df --- /dev/null +++ b/store.go @@ -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 +} \ No newline at end of file diff --git a/store_test.go b/store_test.go new file mode 100644 index 000000000..9d3cc2bac --- /dev/null +++ b/store_test.go @@ -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") + } + +} diff --git a/tree_store.bak b/tree_store.bak new file mode 100644 index 000000000..60616b3f5 --- /dev/null +++ b/tree_store.bak @@ -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 +}