Browse Source

etcdserver: sort Members() in Cluster

Jonathan Boulle 11 years ago
parent
commit
af42f4a56b
4 changed files with 51 additions and 19 deletions
  1. 16 2
      etcdserver/cluster.go
  2. 22 0
      etcdserver/cluster_test.go
  3. 1 13
      etcdserver/etcdhttp/http.go
  4. 12 4
      etcdserver/etcdhttp/http_test.go

+ 16 - 2
etcdserver/cluster.go

@@ -41,7 +41,8 @@ const (
 type ClusterInfo interface {
 	ID() uint64
 	ClientURLs() []string
-	Members() map[uint64]*Member
+	// Members returns a slice of members sorted by their ID
+	Members() []*Member
 	Member(id uint64) *Member
 }
 
@@ -123,7 +124,20 @@ func newCluster(name string) *Cluster {
 
 func (c Cluster) ID() uint64 { return c.id }
 
-func (c Cluster) Members() map[uint64]*Member { return c.members }
+func (c Cluster) Members() []*Member {
+	var sms SortableMemberSlice
+	for _, m := range c.members {
+		sms = append(sms, m)
+	}
+	sort.Sort(sms)
+	return []*Member(sms)
+}
+
+type SortableMemberSlice []*Member
+
+func (s SortableMemberSlice) Len() int           { return len(s) }
+func (s SortableMemberSlice) Less(i, j int) bool { return s[i].ID < s[j].ID }
+func (s SortableMemberSlice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
 
 func (c *Cluster) Member(id uint64) *Member {
 	return c.members[id]

+ 22 - 0
etcdserver/cluster_test.go

@@ -365,6 +365,28 @@ func TestClusterAddMember(t *testing.T) {
 	}
 }
 
+func TestClusterMembers(t *testing.T) {
+	cls := &Cluster{
+		members: map[uint64]*Member{
+			1:   &Member{ID: 1},
+			20:  &Member{ID: 20},
+			100: &Member{ID: 100},
+			5:   &Member{ID: 5},
+			50:  &Member{ID: 50},
+		},
+	}
+	w := []*Member{
+		&Member{ID: 1},
+		&Member{ID: 5},
+		&Member{ID: 20},
+		&Member{ID: 50},
+		&Member{ID: 100},
+	}
+	if g := cls.Members(); !reflect.DeepEqual(g, w) {
+		t.Fatalf("Members()=%#v, want %#v", g, w)
+	}
+}
+
 func TestClusterRemoveMember(t *testing.T) {
 	st := &storeRecorder{}
 	c := newTestCluster(nil)

+ 1 - 13
etcdserver/etcdhttp/http.go

@@ -25,7 +25,6 @@ import (
 	"net/http"
 	"net/url"
 	"path"
-	"sort"
 	"strconv"
 	"strings"
 	"time"
@@ -160,12 +159,7 @@ func (h serverHandler) serveAdminMembers(w http.ResponseWriter, r *http.Request)
 	case "GET":
 		idStr := strings.TrimPrefix(r.URL.Path, adminMembersPrefix)
 		if idStr == "" {
-			msmap := h.clusterInfo.Members()
-			ms := make(SortableMemberSlice, 0, len(msmap))
-			for _, m := range msmap {
-				ms = append(ms, m)
-			}
-			sort.Sort(ms)
+			ms := h.clusterInfo.Members()
 			w.Header().Set("Content-Type", "application/json")
 			if err := json.NewEncoder(w).Encode(ms); err != nil {
 				log.Printf("etcdhttp: %v", err)
@@ -582,9 +576,3 @@ func trimNodeExternPrefix(n *store.NodeExtern, prefix string) *store.NodeExtern
 	}
 	return n
 }
-
-type SortableMemberSlice []*etcdserver.Member
-
-func (s SortableMemberSlice) Len() int           { return len(s) }
-func (s SortableMemberSlice) Less(i, j int) bool { return s[i].ID < s[j].ID }
-func (s SortableMemberSlice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

+ 12 - 4
etcdserver/etcdhttp/http_test.go

@@ -27,6 +27,7 @@ import (
 	"net/url"
 	"path"
 	"reflect"
+	"sort"
 	"strings"
 	"testing"
 	"time"
@@ -1749,7 +1750,14 @@ type fakeCluster struct {
 	members    map[uint64]*etcdserver.Member
 }
 
-func (c *fakeCluster) ID() uint64                             { return c.id }
-func (c *fakeCluster) ClientURLs() []string                   { return c.clientURLs }
-func (c *fakeCluster) Members() map[uint64]*etcdserver.Member { return c.members }
-func (c *fakeCluster) Member(id uint64) *etcdserver.Member    { return c.members[id] }
+func (c *fakeCluster) ID() uint64           { return c.id }
+func (c *fakeCluster) ClientURLs() []string { return c.clientURLs }
+func (c *fakeCluster) Members() []*etcdserver.Member {
+	var sms etcdserver.SortableMemberSlice
+	for _, m := range c.members {
+		sms = append(sms, m)
+	}
+	sort.Sort(sms)
+	return []*etcdserver.Member(sms)
+}
+func (c *fakeCluster) Member(id uint64) *etcdserver.Member { return c.members[id] }