Browse Source

add sorting and its test case

evan-gu 12 years ago
parent
commit
1a7b3e8e08
4 changed files with 61 additions and 14 deletions
  1. 13 0
      file_system/event.go
  2. 5 1
      file_system/file_system.go
  3. 42 12
      file_system/file_system_test.go
  4. 1 1
      store/test.go

+ 13 - 0
file_system/event.go

@@ -36,6 +36,19 @@ type KeyValuePair struct {
 	KVPairs []KeyValuePair `json:"kvs,omitempty"`
 }
 
+// interfaces for sort
+func (e Event) Len() int {
+	return len(e.KVPairs)
+}
+
+func (e Event) Less(i, j int) bool {
+	return e.KVPairs[i].Key < e.KVPairs[j].Key
+}
+
+func (e Event) Swap(i, j int) {
+	e.KVPairs[i], e.KVPairs[j] = e.KVPairs[j], e.KVPairs[i]
+}
+
 func newEvent(action string, key string, index uint64, term uint64) *Event {
 	return &Event{
 		Action: action,

+ 5 - 1
file_system/file_system.go

@@ -3,6 +3,7 @@ package fileSystem
 import (
 	"fmt"
 	"path"
+	"sort"
 	"strings"
 	"time"
 
@@ -25,7 +26,7 @@ func New() *FileSystem {
 
 }
 
-func (fs *FileSystem) Get(nodePath string, recusive bool, index uint64, term uint64) (*Event, error) {
+func (fs *FileSystem) Get(nodePath string, recusive, sorting bool, index uint64, term uint64) (*Event, error) {
 	n, err := fs.InternalGet(nodePath, index, term)
 
 	if err != nil {
@@ -57,6 +58,9 @@ func (fs *FileSystem) Get(nodePath string, recusive bool, index uint64, term uin
 
 		// eliminate hidden nodes
 		e.KVPairs = e.KVPairs[:i]
+		if sorting {
+			sort.Sort(e)
+		}
 	} else { // node is file
 		e.Value = n.Value
 	}

+ 42 - 12
file_system/file_system_test.go

@@ -1,6 +1,7 @@
 package fileSystem
 
 import (
+	"store"
 	"testing"
 	"time"
 )
@@ -34,7 +35,7 @@ func TestCreateAndGet(t *testing.T) {
 		t.Fatal("Cannot create /fooDir")
 	}
 
-	e, err := fs.Get("/fooDir", false, 3, 1)
+	e, err := fs.Get("/fooDir", false, false, 3, 1)
 
 	if err != nil || e.Dir != true {
 		t.Fatal("Cannot create /fooDir ")
@@ -64,7 +65,7 @@ func TestUpdateFile(t *testing.T) {
 		t.Fatalf("cannot update %s=barbar [%s]", "/foo/bar", err.Error())
 	}
 
-	e, err := fs.Get("/foo/bar", false, 2, 1)
+	e, err := fs.Get("/foo/bar", false, false, 2, 1)
 
 	if err != nil {
 		t.Fatalf("cannot get %s [%s]", "/foo/bar", err.Error())
@@ -106,7 +107,7 @@ func TestUpdateFile(t *testing.T) {
 
 	// sleep 50ms, it should still reach the node
 	time.Sleep(time.Microsecond * 50)
-	e, err = fs.Get("/foo/foo", true, 7, 1)
+	e, err = fs.Get("/foo/foo", true, false, 7, 1)
 
 	if err != nil || e.Key != "/foo/foo" {
 		t.Fatalf("cannot get dir before expiration [%s]", err.Error())
@@ -126,23 +127,23 @@ func TestUpdateFile(t *testing.T) {
 
 	// wait for expiration
 	time.Sleep(time.Second * 3)
-	e, err = fs.Get("/foo/foo", true, 7, 1)
+	e, err = fs.Get("/foo/foo", true, false, 7, 1)
 
 	if err == nil {
 		t.Fatal("still can get dir after expiration [%s]")
 	}
 
-	_, err = fs.Get("/foo/foo/foo1", true, 7, 1)
+	_, err = fs.Get("/foo/foo/foo1", true, false, 7, 1)
 	if err == nil {
 		t.Fatal("still can get sub node after expiration [%s]")
 	}
 
-	_, err = fs.Get("/foo/foo/foo2", true, 7, 1)
+	_, err = fs.Get("/foo/foo/foo2", true, false, 7, 1)
 	if err == nil {
 		t.Fatal("still can get sub dir after expiration [%s]")
 	}
 
-	_, err = fs.Get("/foo/foo/foo2/boo", true, 7, 1)
+	_, err = fs.Get("/foo/foo/foo2/boo", true, false, 7, 1)
 	if err == nil {
 		t.Fatalf("still can get sub node of sub dir after expiration [%s]", err.Error())
 	}
@@ -160,7 +161,7 @@ func TestListDirectory(t *testing.T) {
 	// set key-value /foo/fooDir/foo=bar
 	fs.Create("/foo/fooDir/foo", "bar", Permanent, 2, 1)
 
-	e, err := fs.Get("/foo", true, 2, 1)
+	e, err := fs.Get("/foo", true, false, 2, 1)
 
 	if err != nil {
 		t.Fatalf("%v", err)
@@ -187,7 +188,7 @@ func TestListDirectory(t *testing.T) {
 	// set key-value /foo/_hidden/foo -> bar
 	fs.Create("/foo/_hidden/foo", "bar", Permanent, 3, 1)
 
-	e, _ = fs.Get("/foo", false, 2, 1)
+	e, _ = fs.Get("/foo", false, false, 2, 1)
 
 	if len(e.KVPairs) != 2 {
 		t.Fatalf("hidden node is not hidden! %s", e.KVPairs[2].Key)
@@ -204,7 +205,7 @@ func TestRemove(t *testing.T) {
 		t.Fatalf("cannot delete %s [%s]", "/foo", err.Error())
 	}
 
-	_, err = fs.Get("/foo", false, 1, 1)
+	_, err = fs.Get("/foo", false, false, 1, 1)
 
 	if err == nil || err.Error() != "Key Not Found" {
 		t.Fatalf("can get the node after deletion")
@@ -226,7 +227,7 @@ func TestRemove(t *testing.T) {
 		t.Fatalf("cannot delete %s [%s]", "/foo", err.Error())
 	}
 
-	_, err = fs.Get("/foo", false, 1, 1)
+	_, err = fs.Get("/foo", false, false, 1, 1)
 
 	if err == nil || err.Error() != "Key Not Found" {
 		t.Fatalf("can get the node after deletion ")
@@ -382,7 +383,7 @@ func createAndGet(fs *FileSystem, path string, t *testing.T) {
 		t.Fatalf("cannot create %s=bar [%s]", path, err.Error())
 	}
 
-	e, err := fs.Get(path, false, 1, 1)
+	e, err := fs.Get(path, false, false, 1, 1)
 
 	if err != nil {
 		t.Fatalf("cannot get %s [%s]", path, err.Error())
@@ -402,3 +403,32 @@ func nonblockingRetrive(c <-chan *Event) *Event {
 		return nil
 	}
 }
+
+func TestSort(t *testing.T) {
+	fs := New()
+
+	// simulating random creation
+	keys := store.GenKeys(100, 5)
+
+	//t.Log(keys)
+	i := uint64(1)
+	for _, k := range keys {
+		_, err := fs.Create(k, "bar", Permanent, i, 1)
+		if err != nil {
+			t.Fatalf("create node[%s] failed", k, err.Error())
+		}
+		i++
+	}
+
+	e, err := fs.Get("/foo", true, true, i, 1)
+	if err != nil {
+		t.Fatalf("get dir nodes failed [%s]", err.Error())
+	}
+
+	for i, k := range e.KVPairs[:len(e.KVPairs)-1] {
+		//t.Log(k)
+		if k.Key >= e.KVPairs[i+1].Key {
+			t.Fatalf("sort failed, [%s] should be placed after [%s]", k.Key, e.KVPairs[i+1].Key)
+		}
+	}
+}

+ 1 - 1
store/test.go

@@ -10,7 +10,7 @@ func GenKeys(num int, depth int) []string {
 	keys := make([]string, num)
 	for i := 0; i < num; i++ {
 
-		keys[i] = "/foo/"
+		keys[i] = "/foo"
 		depth := rand.Intn(depth) + 1
 
 		for j := 0; j < depth; j++ {