|
|
@@ -325,75 +325,81 @@ func (s *Store) Get(key string) ([]byte, error) {
|
|
|
return json.Marshal(resps)
|
|
|
}
|
|
|
|
|
|
-func (s *Store) RawGet(key string) ([]*Response, error) {
|
|
|
- // Update stats
|
|
|
- s.BasicStats.Gets++
|
|
|
+func (s *Store) rawGetNode(key string, node *Node) ([]*Response, error) {
|
|
|
+ resps := make([]*Response, 1)
|
|
|
|
|
|
- key = path.Clean("/" + key)
|
|
|
+ isExpire := !node.ExpireTime.Equal(PERMANENT)
|
|
|
|
|
|
- nodes, keys, ok := s.Tree.list(key)
|
|
|
-
|
|
|
- if ok {
|
|
|
+ resps[0] = &Response{
|
|
|
+ Action: "GET",
|
|
|
+ Index: s.Index,
|
|
|
+ Key: key,
|
|
|
+ Value: node.Value,
|
|
|
+ }
|
|
|
|
|
|
- node, ok := nodes.(*Node)
|
|
|
+ // Update ttl
|
|
|
+ if isExpire {
|
|
|
+ TTL := int64(node.ExpireTime.Sub(time.Now()) / time.Second)
|
|
|
+ resps[0].Expiration = &node.ExpireTime
|
|
|
+ resps[0].TTL = TTL
|
|
|
+ }
|
|
|
|
|
|
- if ok {
|
|
|
- resps := make([]*Response, 1)
|
|
|
+ return resps, nil
|
|
|
+}
|
|
|
|
|
|
- isExpire := !node.ExpireTime.Equal(PERMANENT)
|
|
|
+func (s *Store) rawGetNodeList(key string, keys []string, nodes []*Node) ([]*Response, error) {
|
|
|
+ resps := make([]*Response, len(nodes))
|
|
|
|
|
|
- resps[0] = &Response{
|
|
|
- Action: "GET",
|
|
|
- Index: s.Index,
|
|
|
- Key: key,
|
|
|
- Value: node.Value,
|
|
|
- }
|
|
|
+ // TODO: check if nodes and keys are the same length
|
|
|
+ for i := 0; i < len(nodes); i++ {
|
|
|
+ var TTL int64
|
|
|
+ var isExpire bool = false
|
|
|
|
|
|
- // Update ttl
|
|
|
- if isExpire {
|
|
|
- TTL := int64(node.ExpireTime.Sub(time.Now()) / time.Second)
|
|
|
- resps[0].Expiration = &node.ExpireTime
|
|
|
- resps[0].TTL = TTL
|
|
|
- }
|
|
|
+ isExpire = !nodes[i].ExpireTime.Equal(PERMANENT)
|
|
|
|
|
|
- return resps, nil
|
|
|
+ resps[i] = &Response{
|
|
|
+ Action: "GET",
|
|
|
+ Index: s.Index,
|
|
|
+ Key: path.Join(key, keys[i]),
|
|
|
}
|
|
|
|
|
|
- nodes, _ := nodes.([]*Node)
|
|
|
-
|
|
|
- resps := make([]*Response, len(nodes))
|
|
|
- for i := 0; i < len(nodes); i++ {
|
|
|
-
|
|
|
- var TTL int64
|
|
|
- var isExpire bool = false
|
|
|
+ if len(nodes[i].Value) != 0 {
|
|
|
+ resps[i].Value = nodes[i].Value
|
|
|
+ } else {
|
|
|
+ resps[i].Dir = true
|
|
|
+ }
|
|
|
|
|
|
- isExpire = !nodes[i].ExpireTime.Equal(PERMANENT)
|
|
|
+ // Update ttl
|
|
|
+ if isExpire {
|
|
|
+ TTL = int64(nodes[i].ExpireTime.Sub(time.Now()) / time.Second)
|
|
|
+ resps[i].Expiration = &nodes[i].ExpireTime
|
|
|
+ resps[i].TTL = TTL
|
|
|
+ }
|
|
|
|
|
|
- resps[i] = &Response{
|
|
|
- Action: "GET",
|
|
|
- Index: s.Index,
|
|
|
- Key: path.Join(key, keys[i]),
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- if len(nodes[i].Value) != 0 {
|
|
|
- resps[i].Value = nodes[i].Value
|
|
|
- } else {
|
|
|
- resps[i].Dir = true
|
|
|
- }
|
|
|
+ return resps, nil
|
|
|
+}
|
|
|
|
|
|
- // Update ttl
|
|
|
- if isExpire {
|
|
|
- TTL = int64(nodes[i].ExpireTime.Sub(time.Now()) / time.Second)
|
|
|
- resps[i].Expiration = &nodes[i].ExpireTime
|
|
|
- resps[i].TTL = TTL
|
|
|
- }
|
|
|
+func (s *Store) RawGet(key string) ([]*Response, error) {
|
|
|
+ // Update stats
|
|
|
+ s.BasicStats.Gets++
|
|
|
|
|
|
- }
|
|
|
+ key = path.Clean("/" + key)
|
|
|
|
|
|
- return resps, nil
|
|
|
+ nodes, keys, ok := s.Tree.list(key)
|
|
|
+ if !ok {
|
|
|
+ return nil, etcdErr.NewError(100, "get: "+key)
|
|
|
}
|
|
|
|
|
|
- return nil, etcdErr.NewError(100, "get: "+key)
|
|
|
+ switch node := nodes.(type) {
|
|
|
+ case *Node:
|
|
|
+ return s.rawGetNode(key, node)
|
|
|
+ case []*Node:
|
|
|
+ return s.rawGetNodeList(key, keys, node)
|
|
|
+ default:
|
|
|
+ panic("invalid cast ")
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
func (s *Store) Delete(key string, index uint64) ([]byte, error) {
|
|
|
@@ -415,43 +421,41 @@ func (s *Store) internalDelete(key string, index uint64) ([]byte, error) {
|
|
|
|
|
|
node, ok := s.Tree.get(key)
|
|
|
|
|
|
- if ok {
|
|
|
+ if !ok {
|
|
|
+ return nil, etcdErr.NewError(100, "delete: "+key)
|
|
|
+ }
|
|
|
|
|
|
- resp := Response{
|
|
|
- Action: "DELETE",
|
|
|
- Key: key,
|
|
|
- PrevValue: node.Value,
|
|
|
- Index: index,
|
|
|
- }
|
|
|
+ resp := Response{
|
|
|
+ Action: "DELETE",
|
|
|
+ Key: key,
|
|
|
+ PrevValue: node.Value,
|
|
|
+ Index: index,
|
|
|
+ }
|
|
|
|
|
|
- if node.ExpireTime.Equal(PERMANENT) {
|
|
|
+ if node.ExpireTime.Equal(PERMANENT) {
|
|
|
|
|
|
- s.Tree.delete(key)
|
|
|
+ s.Tree.delete(key)
|
|
|
|
|
|
- } else {
|
|
|
- resp.Expiration = &node.ExpireTime
|
|
|
- // Kill the expire go routine
|
|
|
- node.update <- PERMANENT
|
|
|
- s.Tree.delete(key)
|
|
|
-
|
|
|
- }
|
|
|
+ } else {
|
|
|
+ resp.Expiration = &node.ExpireTime
|
|
|
+ // Kill the expire go routine
|
|
|
+ node.update <- PERMANENT
|
|
|
+ s.Tree.delete(key)
|
|
|
|
|
|
- msg, err := json.Marshal(resp)
|
|
|
+ }
|
|
|
|
|
|
- s.watcher.notify(resp)
|
|
|
+ msg, err := json.Marshal(resp)
|
|
|
|
|
|
- // notify the messager
|
|
|
- if s.messager != nil && err == nil {
|
|
|
- s.messager <- string(msg)
|
|
|
- }
|
|
|
+ s.watcher.notify(resp)
|
|
|
|
|
|
- s.addToResponseMap(index, &resp)
|
|
|
+ // notify the messager
|
|
|
+ if s.messager != nil && err == nil {
|
|
|
+ s.messager <- string(msg)
|
|
|
+ }
|
|
|
|
|
|
- return msg, err
|
|
|
+ s.addToResponseMap(index, &resp)
|
|
|
|
|
|
- } else {
|
|
|
- return nil, etcdErr.NewError(100, "delete: "+key)
|
|
|
- }
|
|
|
+ return msg, err
|
|
|
}
|
|
|
|
|
|
// Set the value of the key to the value if the given prevValue is equal to the value of the key
|