diff --git a/config/config.go b/config/config.go
index f061ff8fc..5466d6d73 100644
--- a/config/config.go
+++ b/config/config.go
@@ -313,10 +313,14 @@ func Load(rd io.Reader, myID protocol.NodeID) (Configuration, error) {
// Ensure this node is present in all relevant places
// Ensure that any loose nodes are not present in the wrong places
+ // Ensure that there are no duplicate nodes
cfg.Nodes = ensureNodePresent(cfg.Nodes, myID)
+ sort.Sort(NodeConfigurationList(cfg.Nodes))
for i := range cfg.Repositories {
cfg.Repositories[i].Nodes = ensureNodePresent(cfg.Repositories[i].Nodes, myID)
cfg.Repositories[i].Nodes = ensureExistingNodes(cfg.Repositories[i].Nodes, existingNodes)
+ cfg.Repositories[i].Nodes = ensureNoDuplicates(cfg.Repositories[i].Nodes)
+ sort.Sort(NodeConfigurationList(cfg.Repositories[i].Nodes))
}
// An empty address list is equivalent to a single "dynamic" entry
@@ -381,40 +385,50 @@ func (l NodeConfigurationList) Len() int {
}
func ensureNodePresent(nodes []NodeConfiguration, myID protocol.NodeID) []NodeConfiguration {
- var myIDExists bool
for _, node := range nodes {
if node.NodeID.Equals(myID) {
- myIDExists = true
- break
+ return nodes
}
}
- if !myIDExists {
- name, _ := os.Hostname()
- nodes = append(nodes, NodeConfiguration{
- NodeID: myID,
- Name: name,
- })
- }
-
- sort.Sort(NodeConfigurationList(nodes))
+ name, _ := os.Hostname()
+ nodes = append(nodes, NodeConfiguration{
+ NodeID: myID,
+ Name: name,
+ })
return nodes
}
func ensureExistingNodes(nodes []NodeConfiguration, existingNodes map[protocol.NodeID]bool) []NodeConfiguration {
+ count := len(nodes)
i := 0
- for _, node := range nodes {
- if _, ok := existingNodes[node.NodeID]; !ok {
- last := len(nodes) - 1
- nodes[i] = nodes[last]
- nodes = nodes[:last]
- } else {
- i++
+loop:
+ for i < count {
+ if _, ok := existingNodes[nodes[i].NodeID]; !ok {
+ nodes[i] = nodes[count-1]
+ count--
+ continue loop
}
+ i++
}
-
- sort.Sort(NodeConfigurationList(nodes))
-
- return nodes
+ return nodes[0:count]
+}
+
+func ensureNoDuplicates(nodes []NodeConfiguration) []NodeConfiguration {
+ count := len(nodes)
+ i := 0
+ seenNodes := make(map[protocol.NodeID]bool)
+loop:
+ for i < count {
+ id := nodes[i].NodeID
+ if _, ok := seenNodes[id]; ok {
+ nodes[i] = nodes[count-1]
+ count--
+ continue loop
+ }
+ seenNodes[id] = true
+ i++
+ }
+ return nodes[0:count]
}
diff --git a/config/config_test.go b/config/config_test.go
index aceb2fc14..2caa823db 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -59,6 +59,12 @@ func TestNodeConfig(t *testing.T) {
b
+
+ a
+
+
+ b
+
true
@@ -69,9 +75,12 @@ func TestNodeConfig(t *testing.T) {
v2data := []byte(`
+
+
+
a