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