Browse Source

store module and unit test for store

Xiang Li 12 years ago
commit
20ca21a3f7
3 changed files with 205 additions and 0 deletions
  1. 74 0
      store.go
  2. 46 0
      store_test.go
  3. 85 0
      tree_store.bak

+ 74 - 0
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
+}

+ 46 - 0
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")
+	}
+
+}

+ 85 - 0
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
+}