Browse Source

Merge pull request #445 from AudriusButkevicius/dupes

Fixes and improvements
Jakob Borg 11 years ago
parent
commit
6a441d5013
2 changed files with 45 additions and 22 deletions
  1. 36 22
      config/config.go
  2. 9 0
      config/config_test.go

+ 36 - 22
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++
 	}
+	return nodes[0:count]
+}
 
-	sort.Sort(NodeConfigurationList(nodes))
-
-	return nodes
+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]
 }

+ 9 - 0
config/config_test.go

@@ -59,6 +59,12 @@ func TestNodeConfig(t *testing.T) {
         <node id="P56IOI7MZJNU2IQGDREYDM2MGTMGL3BXNPQ6W5BTBBZ4TJXZWICQ" name="node two">
             <address>b</address>
         </node>
+        <node id="AIR6LPZ7K4PTTUXQSMUUCPQ5YWOEDFIIQJUG7772YQXXR5YD6AWQ" name="node one">
+            <address>a</address>
+        </node>
+        <node id="P56IOI7MZJNU2IQGDREYDM2MGTMGL3BXNPQ6W5BTBBZ4TJXZWICQ" name="node two">
+            <address>b</address>
+        </node>
     </repository>
     <options>
         <readOnly>true</readOnly>
@@ -69,9 +75,12 @@ func TestNodeConfig(t *testing.T) {
 	v2data := []byte(`
 <configuration version="2">
     <repository id="test" directory="~/Sync" ro="true">
+        <node id="P56IOI7MZJNU2IQGDREYDM2MGTMGL3BXNPQ6W5BTBBZ4TJXZWICQ"/>
         <node id="AIR6LPZ7K4PTTUXQSMUUCPQ5YWOEDFIIQJUG7772YQXXR5YD6AWQ"/>
         <node id="C4YBIESWDUAIGU62GOSRXCRAAJDWVE3TKCPMURZE2LH5QHAF576A"/>
         <node id="P56IOI7MZJNU2IQGDREYDM2MGTMGL3BXNPQ6W5BTBBZ4TJXZWICQ"/>
+        <node id="AIR6LPZ7K4PTTUXQSMUUCPQ5YWOEDFIIQJUG7772YQXXR5YD6AWQ"/>
+        <node id="C4YBIESWDUAIGU62GOSRXCRAAJDWVE3TKCPMURZE2LH5QHAF576A"/>
     </repository>
     <node id="AIR6LPZ7K4PTTUXQSMUUCPQ5YWOEDFIIQJUG7772YQXXR5YD6AWQ" name="node one">
         <address>a</address>