Merge pull request #445 from AudriusButkevicius/dupes

Fixes and improvements
This commit is contained in:
Jakob Borg
2014-07-28 10:55:38 +02:00
2 changed files with 46 additions and 23 deletions

View File

@@ -313,10 +313,14 @@ func Load(rd io.Reader, myID protocol.NodeID) (Configuration, error) {
// Ensure this node is present in all relevant places // Ensure this node is present in all relevant places
// Ensure that any loose nodes are not present in the wrong 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) cfg.Nodes = ensureNodePresent(cfg.Nodes, myID)
sort.Sort(NodeConfigurationList(cfg.Nodes))
for i := range cfg.Repositories { for i := range cfg.Repositories {
cfg.Repositories[i].Nodes = ensureNodePresent(cfg.Repositories[i].Nodes, myID) cfg.Repositories[i].Nodes = ensureNodePresent(cfg.Repositories[i].Nodes, myID)
cfg.Repositories[i].Nodes = ensureExistingNodes(cfg.Repositories[i].Nodes, existingNodes) 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 // 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 { func ensureNodePresent(nodes []NodeConfiguration, myID protocol.NodeID) []NodeConfiguration {
var myIDExists bool
for _, node := range nodes { for _, node := range nodes {
if node.NodeID.Equals(myID) { if node.NodeID.Equals(myID) {
myIDExists = true return nodes
break
} }
} }
if !myIDExists { name, _ := os.Hostname()
name, _ := os.Hostname() nodes = append(nodes, NodeConfiguration{
nodes = append(nodes, NodeConfiguration{ NodeID: myID,
NodeID: myID, Name: name,
Name: name, })
})
}
sort.Sort(NodeConfigurationList(nodes))
return nodes return nodes
} }
func ensureExistingNodes(nodes []NodeConfiguration, existingNodes map[protocol.NodeID]bool) []NodeConfiguration { func ensureExistingNodes(nodes []NodeConfiguration, existingNodes map[protocol.NodeID]bool) []NodeConfiguration {
count := len(nodes)
i := 0 i := 0
for _, node := range nodes { loop:
if _, ok := existingNodes[node.NodeID]; !ok { for i < count {
last := len(nodes) - 1 if _, ok := existingNodes[nodes[i].NodeID]; !ok {
nodes[i] = nodes[last] nodes[i] = nodes[count-1]
nodes = nodes[:last] count--
} else { continue loop
i++
} }
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]
} }

View File

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