refactor change Index to modifiedIndex

This commit is contained in:
Xiang Li 2013-11-09 20:49:19 -08:00
parent d8e5994c35
commit 06f1b7f2e8
11 changed files with 50 additions and 44 deletions

View File

@ -24,6 +24,6 @@ func TestV2DeleteKey(t *testing.T) {
resp, err = tests.DeleteForm(fmt.Sprintf("http://%s%s", s.URL(), "/v2/keys/foo/bar"), url.Values{}) resp, err = tests.DeleteForm(fmt.Sprintf("http://%s%s", s.URL(), "/v2/keys/foo/bar"), url.Values{})
body := tests.ReadBody(resp) body := tests.ReadBody(resp)
assert.Nil(t, err, "") assert.Nil(t, err, "")
assert.Equal(t, string(body), `{"action":"delete","key":"/foo/bar","prevValue":"XXX","index":2}`, "") assert.Equal(t, string(body), `{"action":"delete","key":"/foo/bar","prevValue":"XXX","modifiedIndex":2}`, "")
}) })
} }

View File

@ -27,7 +27,7 @@ func TestV2GetKey(t *testing.T) {
assert.Equal(t, body["action"], "get", "") assert.Equal(t, body["action"], "get", "")
assert.Equal(t, body["key"], "/foo/bar", "") assert.Equal(t, body["key"], "/foo/bar", "")
assert.Equal(t, body["value"], "XXX", "") assert.Equal(t, body["value"], "XXX", "")
assert.Equal(t, body["index"], 1, "") assert.Equal(t, body["modifiedIndex"], 1, "")
}) })
} }
@ -54,7 +54,7 @@ func TestV2GetKeyRecursively(t *testing.T) {
assert.Equal(t, body["action"], "get", "") assert.Equal(t, body["action"], "get", "")
assert.Equal(t, body["key"], "/foo", "") assert.Equal(t, body["key"], "/foo", "")
assert.Equal(t, body["dir"], true, "") assert.Equal(t, body["dir"], true, "")
assert.Equal(t, body["index"], 2, "") assert.Equal(t, body["modifiedIndex"], 1, "")
assert.Equal(t, len(body["kvs"].([]interface{})), 2, "") assert.Equal(t, len(body["kvs"].([]interface{})), 2, "")
kv0 := body["kvs"].([]interface{})[0].(map[string]interface{}) kv0 := body["kvs"].([]interface{})[0].(map[string]interface{})
@ -111,7 +111,7 @@ func TestV2WatchKey(t *testing.T) {
assert.Equal(t, body["action"], "set", "") assert.Equal(t, body["action"], "set", "")
assert.Equal(t, body["key"], "/foo/bar", "") assert.Equal(t, body["key"], "/foo/bar", "")
assert.Equal(t, body["value"], "XXX", "") assert.Equal(t, body["value"], "XXX", "")
assert.Equal(t, body["index"], 1, "") assert.Equal(t, body["modifiedIndex"], 1, "")
}) })
} }
@ -164,6 +164,6 @@ func TestV2WatchKeyWithIndex(t *testing.T) {
assert.Equal(t, body["action"], "set", "") assert.Equal(t, body["action"], "set", "")
assert.Equal(t, body["key"], "/foo/bar", "") assert.Equal(t, body["key"], "/foo/bar", "")
assert.Equal(t, body["value"], "YYY", "") assert.Equal(t, body["value"], "YYY", "")
assert.Equal(t, body["index"], 2, "") assert.Equal(t, body["modifiedIndex"], 2, "")
}) })
} }

View File

@ -23,7 +23,7 @@ func TestV2CreateUnique(t *testing.T) {
assert.Equal(t, body["action"], "create", "") assert.Equal(t, body["action"], "create", "")
assert.Equal(t, body["key"], "/foo/bar/1", "") assert.Equal(t, body["key"], "/foo/bar/1", "")
assert.Equal(t, body["dir"], true, "") assert.Equal(t, body["dir"], true, "")
assert.Equal(t, body["index"], 1, "") assert.Equal(t, body["modifiedIndex"], 1, "")
// Second POST should add next index to list. // Second POST should add next index to list.
resp, _ = tests.PostForm(fmt.Sprintf("http://%s%s", s.URL(), "/v2/keys/foo/bar"), nil) resp, _ = tests.PostForm(fmt.Sprintf("http://%s%s", s.URL(), "/v2/keys/foo/bar"), nil)

View File

@ -22,7 +22,7 @@ func TestV2SetKey(t *testing.T) {
resp, err := tests.PutForm(fmt.Sprintf("http://%s%s", s.URL(), "/v2/keys/foo/bar"), v) resp, err := tests.PutForm(fmt.Sprintf("http://%s%s", s.URL(), "/v2/keys/foo/bar"), v)
body := tests.ReadBody(resp) body := tests.ReadBody(resp)
assert.Nil(t, err, "") assert.Nil(t, err, "")
assert.Equal(t, string(body), `{"action":"set","key":"/foo/bar","value":"XXX","index":1}`, "") assert.Equal(t, string(body), `{"action":"set","key":"/foo/bar","value":"XXX","modifiedIndex":1}`, "")
}) })
} }
@ -175,7 +175,7 @@ func TestV2SetKeyCASOnIndexSuccess(t *testing.T) {
assert.Equal(t, body["action"], "compareAndSwap", "") assert.Equal(t, body["action"], "compareAndSwap", "")
assert.Equal(t, body["prevValue"], "XXX", "") assert.Equal(t, body["prevValue"], "XXX", "")
assert.Equal(t, body["value"], "YYY", "") assert.Equal(t, body["value"], "YYY", "")
assert.Equal(t, body["index"], 2, "") assert.Equal(t, body["modifiedIndex"], 2, "")
}) })
} }
@ -236,7 +236,7 @@ func TestV2SetKeyCASOnValueSuccess(t *testing.T) {
assert.Equal(t, body["action"], "compareAndSwap", "") assert.Equal(t, body["action"], "compareAndSwap", "")
assert.Equal(t, body["prevValue"], "XXX", "") assert.Equal(t, body["prevValue"], "XXX", "")
assert.Equal(t, body["value"], "YYY", "") assert.Equal(t, body["value"], "YYY", "")
assert.Equal(t, body["index"], 2, "") assert.Equal(t, body["modifiedIndex"], 2, "")
}) })
} }

View File

@ -15,23 +15,23 @@ const (
) )
type Event struct { type Event struct {
Action string `json:"action"` Action string `json:"action"`
Key string `json:"key, omitempty"`
Dir bool `json:"dir,omitempty"` Key string `json:"key, omitempty"`
PrevValue string `json:"prevValue,omitempty"` Dir bool `json:"dir,omitempty"`
Value string `json:"value,omitempty"` PrevValue string `json:"prevValue,omitempty"`
KVPairs kvPairs `json:"kvs,omitempty"` Value string `json:"value,omitempty"`
Expiration *time.Time `json:"expiration,omitempty"` KVPairs kvPairs `json:"kvs,omitempty"`
TTL int64 `json:"ttl,omitempty"` // Time to live in second Expiration *time.Time `json:"expiration,omitempty"`
// The index of the etcd state machine when the comment is executed TTL int64 `json:"ttl,omitempty"` // Time to live in second
Index uint64 `json:"index"` ModifiedIndex uint64 `json:"modifiedIndex"`
} }
func newEvent(action string, key string, index uint64) *Event { func newEvent(action string, key string, index uint64) *Event {
return &Event{ return &Event{
Action: action, Action: action,
Key: key, Key: key,
Index: index, ModifiedIndex: index,
} }
} }
@ -47,6 +47,10 @@ func (e *Event) IsCreated() bool {
return false return false
} }
func (e *Event) Index() uint64 {
return e.ModifiedIndex
}
// Converts an event object into a response object. // Converts an event object into a response object.
func (event *Event) Response() interface{} { func (event *Event) Response() interface{} {
if !event.Dir { if !event.Dir {
@ -55,7 +59,7 @@ func (event *Event) Response() interface{} {
Key: event.Key, Key: event.Key,
Value: event.Value, Value: event.Value,
PrevValue: event.PrevValue, PrevValue: event.PrevValue,
Index: event.Index, Index: event.ModifiedIndex,
TTL: event.TTL, TTL: event.TTL,
Expiration: event.Expiration, Expiration: event.Expiration,
} }
@ -80,7 +84,7 @@ func (event *Event) Response() interface{} {
Key: kv.Key, Key: kv.Key,
Value: kv.Value, Value: kv.Value,
Dir: kv.Dir, Dir: kv.Dir,
Index: event.Index, Index: event.ModifiedIndex,
} }
} }
return responses return responses

View File

@ -31,9 +31,9 @@ func (eh *EventHistory) addEvent(e *Event) *Event {
eh.Queue.insert(e) eh.Queue.insert(e)
eh.LastIndex = e.Index eh.LastIndex = e.Index()
eh.StartIndex = eh.Queue.Events[eh.Queue.Front].Index eh.StartIndex = eh.Queue.Events[eh.Queue.Front].ModifiedIndex
return e return e
} }
@ -62,7 +62,7 @@ func (eh *EventHistory) scan(prefix string, index uint64) (*Event, *etcdErr.Erro
for { for {
e := eh.Queue.Events[i] e := eh.Queue.Events[i]
if strings.HasPrefix(e.Key, prefix) && index <= e.Index { // make sure we bypass the smaller one if strings.HasPrefix(e.Key, prefix) && index <= e.Index() { // make sure we bypass the smaller one
return e, nil return e, nil
} }

View File

@ -23,7 +23,7 @@ func TestEventQueue(t *testing.T) {
n := eh.Queue.Size n := eh.Queue.Size
for ; n > 0; n-- { for ; n > 0; n-- {
e := eh.Queue.Events[i] e := eh.Queue.Events[i]
if e.Index != uint64(j) { if e.Index() != uint64(j) {
t.Fatalf("queue error!") t.Fatalf("queue error!")
} }
j++ j++
@ -42,19 +42,19 @@ func TestScanHistory(t *testing.T) {
eh.addEvent(newEvent(Create, "/foo/foo/foo", 5)) eh.addEvent(newEvent(Create, "/foo/foo/foo", 5))
e, err := eh.scan("/foo", 1) e, err := eh.scan("/foo", 1)
if err != nil || e.Index != 1 { if err != nil || e.Index() != 1 {
t.Fatalf("scan error [/foo] [1] %v", e.Index) t.Fatalf("scan error [/foo] [1] %v", e.Index)
} }
e, err = eh.scan("/foo/bar", 1) e, err = eh.scan("/foo/bar", 1)
if err != nil || e.Index != 2 { if err != nil || e.Index() != 2 {
t.Fatalf("scan error [/foo/bar] [2] %v", e.Index) t.Fatalf("scan error [/foo/bar] [2] %v", e.Index)
} }
e, err = eh.scan("/foo/bar", 3) e, err = eh.scan("/foo/bar", 3)
if err != nil || e.Index != 4 { if err != nil || e.Index() != 4 {
t.Fatalf("scan error [/foo/bar/bar] [4] %v", e.Index) t.Fatalf("scan error [/foo/bar/bar] [4] %v", e.Index)
} }

View File

@ -51,13 +51,14 @@ func newDir(store *store, nodePath string, createIndex uint64, parent *Node,
ACL string, expireTime time.Time) *Node { ACL string, expireTime time.Time) *Node {
return &Node{ return &Node{
Path: nodePath, Path: nodePath,
CreateIndex: createIndex, CreateIndex: createIndex,
Parent: parent, ModifiedIndex: createIndex,
ACL: ACL, Parent: parent,
ExpireTime: expireTime, ACL: ACL,
Children: make(map[string]*Node), ExpireTime: expireTime,
store: store, Children: make(map[string]*Node),
store: store,
} }
} }

View File

@ -220,6 +220,8 @@ func (s *store) Delete(nodePath string, recursive bool) (*Event, error) {
s.worldLock.Lock() s.worldLock.Lock()
defer s.worldLock.Unlock() defer s.worldLock.Unlock()
nextIndex := s.CurrentIndex + 1
n, err := s.internalGet(nodePath) n, err := s.internalGet(nodePath)
if err != nil { // if the node does not exist, return error if err != nil { // if the node does not exist, return error
@ -227,7 +229,7 @@ func (s *store) Delete(nodePath string, recursive bool) (*Event, error) {
return nil, err return nil, err
} }
e := newEvent(Delete, nodePath, s.CurrentIndex) e := newEvent(Delete, nodePath, nextIndex)
if n.IsDir() { if n.IsDir() {
e.Dir = true e.Dir = true
@ -249,7 +251,6 @@ func (s *store) Delete(nodePath string, recursive bool) (*Event, error) {
// update etcd index // update etcd index
s.CurrentIndex++ s.CurrentIndex++
e.Index = s.CurrentIndex
s.WatcherHub.notify(e) s.WatcherHub.notify(e)
s.Stats.Inc(DeleteSuccess) s.Stats.Inc(DeleteSuccess)
@ -488,7 +489,7 @@ func (s *store) checkDir(parent *Node, dirName string) (*Node, *etcdErr.Error) {
return nil, etcdErr.NewError(etcdErr.EcodeNotDir, parent.Path, s.CurrentIndex) return nil, etcdErr.NewError(etcdErr.EcodeNotDir, parent.Path, s.CurrentIndex)
} }
n := newDir(s, path.Join(parent.Path, dirName), s.CurrentIndex, parent, parent.ACL, Permanent) n := newDir(s, path.Join(parent.Path, dirName), s.CurrentIndex+1, parent, parent.ACL, Permanent)
parent.Children[dirName] = n parent.Children[dirName] = n

View File

@ -81,7 +81,7 @@ func TestStoreCreateValue(t *testing.T) {
assert.Nil(t, e.KVPairs, "") assert.Nil(t, e.KVPairs, "")
assert.Nil(t, e.Expiration, "") assert.Nil(t, e.Expiration, "")
assert.Equal(t, e.TTL, 0, "") assert.Equal(t, e.TTL, 0, "")
assert.Equal(t, e.Index, uint64(1), "") assert.Equal(t, e.ModifiedIndex, uint64(1), "")
} }
// Ensure that the store can create a new directory if it doesn't already exist. // Ensure that the store can create a new directory if it doesn't already exist.
@ -119,7 +119,7 @@ func TestStoreUpdateValue(t *testing.T) {
assert.Equal(t, e.PrevValue, "bar", "") assert.Equal(t, e.PrevValue, "bar", "")
assert.Equal(t, e.Value, "baz", "") assert.Equal(t, e.Value, "baz", "")
assert.Equal(t, e.TTL, 0, "") assert.Equal(t, e.TTL, 0, "")
assert.Equal(t, e.Index, uint64(2), "") assert.Equal(t, e.ModifiedIndex, uint64(2), "")
e, _ = s.Get("/foo", false, false) e, _ = s.Get("/foo", false, false)
assert.Equal(t, e.Value, "baz", "") assert.Equal(t, e.Value, "baz", "")
} }

View File

@ -24,7 +24,7 @@ func (w *watcher) notify(e *Event, originalPath bool, deleted bool) bool {
// at the file we need to delete. // at the file we need to delete.
// For example a watcher is watching at "/foo/bar". And we deletes "/foo". The watcher // For example a watcher is watching at "/foo/bar". And we deletes "/foo". The watcher
// should get notified even if "/foo" is not the path it is watching. // should get notified even if "/foo" is not the path it is watching.
if (w.recursive || originalPath || deleted) && e.Index >= w.sinceIndex { if (w.recursive || originalPath || deleted) && e.Index() >= w.sinceIndex {
w.eventChan <- e w.eventChan <- e
return true return true
} }