Browse Source

merge get and list

Xiang Li 12 years ago
parent
commit
4b9b5d8069
5 changed files with 67 additions and 71 deletions
  1. 0 30
      client_handlers.go
  2. 13 13
      command.go
  3. 1 2
      etcd.go
  4. 40 21
      store/store.go
  5. 13 5
      store/tree.go

+ 0 - 30
client_handlers.go

@@ -226,36 +226,6 @@ func GetHttpHandler(w *http.ResponseWriter, req *http.Request) {
 
 }
 
-// List Handler
-func ListHttpHandler(w http.ResponseWriter, req *http.Request) {
-	prefix := req.URL.Path[len("/v1/list/"):]
-
-	debug("[recv] GET http://%v/v1/list/%s", raftServer.Name(), prefix)
-
-	command := &ListCommand{}
-	command.Prefix = prefix
-
-	if body, err := command.Apply(raftServer); err != nil {
-		if _, ok := err.(store.NotFoundError); ok {
-			http.NotFound(w, req)
-			return
-		}
-		w.WriteHeader(http.StatusInternalServerError)
-		return
-	} else {
-		w.WriteHeader(http.StatusOK)
-
-		body, ok := body.([]byte)
-		if !ok {
-			panic("wrong type")
-		}
-
-		w.Write(body)
-		return
-	}
-
-}
-
 // Watch handler
 func WatchHttpHandler(w http.ResponseWriter, req *http.Request) {
 	key := req.URL.Path[len("/v1/watch/"):]

+ 13 - 13
command.go

@@ -65,19 +65,19 @@ func (c *GetCommand) Apply(server *raft.Server) (interface{}, error) {
 }
 
 // List command
-type ListCommand struct {
-	Prefix string `json:"prefix"`
-}
-
-// The name of the list command in the log
-func (c *ListCommand) CommandName() string {
-	return "list"
-}
-
-// List all the keys have the given prefix path
-func (c *ListCommand) Apply(server *raft.Server) (interface{}, error) {
-	return etcdStore.List(c.Prefix)
-}
+// type ListCommand struct {
+// 	Prefix string `json:"prefix"`
+// }
+
+// // The name of the list command in the log
+// func (c *ListCommand) CommandName() string {
+// 	return "list"
+// }
+
+// // List all the keys have the given prefix path
+// func (c *ListCommand) Apply(server *raft.Server) (interface{}, error) {
+// 	return etcdStore.Get(c.Prefix)
+// }
 
 // Delete command
 type DeleteCommand struct {

+ 1 - 2
etcd.go

@@ -358,7 +358,6 @@ func startClientTransport(port int, st int) {
 	// external commands
 	http.HandleFunc("/"+version+"/keys/", Multiplexer)
 	http.HandleFunc("/"+version+"/watch/", WatchHttpHandler)
-	http.HandleFunc("/"+version+"/list/", ListHttpHandler)
 	http.HandleFunc("/"+version+"/testAndSet/", TestAndSetHttpHandler)
 	http.HandleFunc("/leader", LeaderHttpHandler)
 
@@ -571,6 +570,6 @@ func registerCommands() {
 	raft.RegisterCommand(&GetCommand{})
 	raft.RegisterCommand(&DeleteCommand{})
 	raft.RegisterCommand(&WatchCommand{})
-	raft.RegisterCommand(&ListCommand{})
+	//raft.RegisterCommand(&ListCommand{})
 	raft.RegisterCommand(&TestAndSetCommand{})
 }

+ 40 - 21
store/store.go

@@ -64,11 +64,12 @@ type Node struct {
 type Response struct {
 	Action    string `json:"action"`
 	Key       string `json:"key"`
+	Dir       bool   `json:"dir,omitempty"`
 	PrevValue string `json:"prevValue,omitempty"`
 	Value     string `json:"value,omitempty"`
 
-	// If the key existed before the action, this field should be true
-	// If the key did not exist before the action, this field should be false
+	// If the key did not exist before the action, 
+	// this field should be set to true
 	NewKey    bool `json:"newKey,omitempty"`
 
 	Expiration *time.Time `json:"expiration,omitempty"`
@@ -243,18 +244,6 @@ func (s *Store) Set(key string, value string, expireTime time.Time, index uint64
 	}
 }
 
-// Get the value of the key
-func (s *Store) Get(key string) ([]byte, error) {
-	resp := s.internalGet(key)
-
-	if resp != nil {
-		return json.Marshal(resp)
-	} else {
-		err := NotFoundError(key)
-		return nil, err
-	}
-}	
-
 // Get the value of the key and return the raw response
 func (s *Store) internalGet(key string) *Response {
 
@@ -291,21 +280,51 @@ func (s *Store) internalGet(key string) *Response {
 }
 
 
-// List all the item in the prefix
-func (s *Store) List(prefix string) ([]byte, error) {
+// Get all the items under key
+// If key is a file return the file
+// If key is a directory reuturn an array of files
+func (s *Store) Get(key string) ([]byte, error) {
 
-	nodes, keys, dirs, ok := s.Tree.list(prefix)
+	key = path.Clean("/" + key)
 
-	var ln []ListNode
+	nodes, keys, dirs, ok := s.Tree.list(key)
 
 	if ok {
-		ln = make([]ListNode, len(nodes))
+		resps := make([]Response, len(nodes))
 		for i := 0; i < len(nodes); i++ {
-			ln[i] = ListNode{keys[i], nodes[i].Value, dirs[i]}
+
+			var TTL int64
+			var isExpire bool = false
+
+			isExpire = !nodes[i].ExpireTime.Equal(PERMANENT)
+
+			resps[i] = Response{
+				Action: "GET", 
+				Index: s.Index,
+				Key: path.Join(key, keys[i]),
+			}
+
+			if !dirs[i] {
+				resps[i].Value = nodes[i].Value
+			} else {
+				resps[i].Dir = true
+			}
+
+			// Update ttl
+			if isExpire {
+				TTL = int64(nodes[i].ExpireTime.Sub(time.Now()) / time.Second)
+				resps[i].Expiration = &nodes[i].ExpireTime 
+				resps[i].TTL = TTL 
+			} 
+
+		}
+		if len(resps) == 1 {
+			return json.Marshal(resps[0])
 		}
+		return json.Marshal(resps)
 	}
 
-	err := NotFoundError(prefix)
+	err := NotFoundError(key)
 	return nil, err
 }
 

+ 13 - 5
store/tree.go

@@ -140,32 +140,40 @@ func (t *tree) get(key string) (Node, bool) {
 	tn, ok := t.internalGet(key)
 
 	if ok {
+		if tn.Dir {
+			return emptyNode, false
+		}
 		return tn.InternalNode, ok
 	} else {
 		return emptyNode, ok
 	}
 }
 
-// return the nodes information under the directory
-func (t *tree) list(directory string) ([]Node, []string, []string, bool) {
+// get the internalNode of the key
+func (t *tree) list(directory string) ([]Node, []string, []bool, bool) {
 	treeNode, ok := t.internalGet(directory)
 
 	if !ok {
 		return nil, nil, nil, ok
 	} else {
+		if !treeNode.Dir {
+			nodes := make([]Node, 1)
+			nodes[0] = treeNode.InternalNode
+			return nodes, make([]string, 1), make([]bool, 1), true
+		} 
 		length := len(treeNode.NodeMap)
 		nodes := make([]Node, length)
 		keys := make([]string, length)
-		dirs := make([]string, length)
+		dirs := make([]bool, length)
 		i := 0
 
 		for key, node := range treeNode.NodeMap {
 			nodes[i] = node.InternalNode
 			keys[i] = key
 			if node.Dir {
-				dirs[i] = "d"
+				dirs[i] = true
 			} else {
-				dirs[i] = "f"
+				dirs[i] = false
 			}
 			i++
 		}