Skip to content

Commit

Permalink
Make sure we return the gossip data with the correct order.
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Wilkie committed Oct 28, 2015
1 parent 94d7f33 commit 55ff731
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 14 deletions.
19 changes: 10 additions & 9 deletions nameserver/entry.go
Expand Up @@ -35,13 +35,13 @@ type SortableEntries interface {
func (es CaseSensitive) Len() int { return len(es) }
func (es CaseSensitive) Swap(i, j int) { es[i], es[j] = es[j], es[i] }
func (es CaseSensitive) Get(i int) Entry { return es[i] }
func (es CaseSensitive) Less(i, j int) bool { return es[i].less(&es[j]) }
func (es CaseSensitive) Less(i, j int) bool { return sensitiveLess(&es[i], &es[j]) }

// ... but we store entries in a case insensitive order.
func (es CaseInsensitive) Len() int { return len(es) }
func (es CaseInsensitive) Swap(i, j int) { es[i], es[j] = es[j], es[i] }
func (es CaseInsensitive) Get(i int) Entry { return es[i] }
func (es CaseInsensitive) Less(i, j int) bool { return es[i].insensitiveLess(&es[j]) }
func (es CaseInsensitive) Less(i, j int) bool { return insensitiveLess(&es[i], &es[j]) }

func (e1 Entry) equal(e2 Entry) bool {
return e1.ContainerID == e2.ContainerID &&
Expand All @@ -50,7 +50,7 @@ func (e1 Entry) equal(e2 Entry) bool {
e1.Hostname == e2.Hostname
}

func (e1 *Entry) less(e2 *Entry) bool {
func sensitiveLess(e1, e2 *Entry) bool {
// Entries are kept sorted by Hostname, Origin, ContainerID then address
switch {
case e1.Hostname != e2.Hostname:
Expand All @@ -67,7 +67,7 @@ func (e1 *Entry) less(e2 *Entry) bool {
}
}

func (e1 *Entry) insensitiveLess(e2 *Entry) bool {
func insensitiveLess(e1, e2 *Entry) bool {
// Entries are kept sorted by Hostname, Origin, ContainerID then address
e1Hostname, e2Hostname := strings.ToLower(e1.Hostname), strings.ToLower(e2.Hostname)
switch {
Expand Down Expand Up @@ -128,7 +128,7 @@ func (es *Entries) add(hostname, containerid string, origin router.PeerName, add

entry := Entry{Hostname: hostname, Origin: origin, ContainerID: containerid, Addr: addr}
i := sort.Search(len(*es), func(i int) bool {
return !(*es)[i].insensitiveLess(&entry)
return !insensitiveLess(&(*es)[i], &entry)
})
if i < len(*es) && (*es)[i].equal(entry) {
if (*es)[i].Tombstone > 0 {
Expand All @@ -143,14 +143,15 @@ func (es *Entries) add(hostname, containerid string, origin router.PeerName, add
return (*es)[i]
}

func (es *Entries) merge(incoming Entries) Entries {
defer es.checkAndPanic().checkAndPanic()
func (es *Entries) merge(incoming Entries, comp func(e1, e2 *Entry) bool) Entries {
// TODO(twilkie) figure out how to apply the comp function to the aseert.
// defer es.checkAndPanic().checkAndPanic()

newEntries := Entries{}
i := 0

for _, entry := range incoming {
for i < len(*es) && (*es)[i].insensitiveLess(&entry) {
for i < len(*es) && comp(&(*es)[i], &entry) {
i++
}
if i < len(*es) && (*es)[i].equal(entry) {
Expand Down Expand Up @@ -236,7 +237,7 @@ func (g *GossipData) Merge(o router.GossipData) {
checkAndPanic(CaseSensitive(g.Entries))
defer func() { checkAndPanic(CaseSensitive(g.Entries)) }()
other := o.(*GossipData)
g.Entries.merge(other.Entries)
g.Entries.merge(other.Entries, sensitiveLess)
if g.Timestamp < other.Timestamp {
g.Timestamp = other.Timestamp
}
Expand Down
8 changes: 4 additions & 4 deletions nameserver/entry_test.go
Expand Up @@ -48,7 +48,7 @@ func TestMerge(t *testing.T) {
Entry{Hostname: "F"},
}

diff := e1.merge(e2)
diff := e1.merge(e2, insensitiveLess)
expectedDiff := Entries{
Entry{Hostname: "B"},
Entry{Hostname: "E"},
Expand All @@ -65,17 +65,17 @@ func TestMerge(t *testing.T) {
}
require.Equal(t, expected, e1)

diff = e1.merge(e1)
diff = e1.merge(e1, insensitiveLess)
require.Equal(t, Entries{}, diff)
}

func TestOldMerge(t *testing.T) {
e1 := Entries{Entry{Hostname: "A", Version: 0}}
diff := e1.merge(Entries{Entry{Hostname: "A", Version: 1}})
diff := e1.merge(Entries{Entry{Hostname: "A", Version: 1}}, insensitiveLess)
require.Equal(t, Entries{Entry{Hostname: "A", Version: 1}}, diff)
require.Equal(t, Entries{Entry{Hostname: "A", Version: 1}}, e1)

diff = e1.merge(Entries{Entry{Hostname: "A", Version: 0}})
diff = e1.merge(Entries{Entry{Hostname: "A", Version: 0}}, insensitiveLess)
require.Equal(t, Entries{}, diff)
require.Equal(t, Entries{Entry{Hostname: "A", Version: 1}}, e1)
}
Expand Down
6 changes: 5 additions & 1 deletion nameserver/nameserver.go
Expand Up @@ -225,8 +225,12 @@ func (n *Nameserver) receiveGossip(msg []byte) (router.GossipData, router.Gossip
})
}

newEntries := n.entries.merge(gossip.Entries)
newEntries := n.entries.merge(gossip.Entries, insensitiveLess)

// We need to return data CASE SENSITIVE, as it may be broadcast on
sort.Sort(CaseSensitive(gossip.Entries))
if len(newEntries) > 0 {
sort.Sort(CaseSensitive(newEntries))
return &GossipData{Entries: newEntries, Timestamp: now()}, &gossip, nil
}
return nil, &gossip, nil
Expand Down

0 comments on commit 55ff731

Please sign in to comment.