From 2546930a1af1ca8f6ddbee166c87ecaaac818059 Mon Sep 17 00:00:00 2001 From: Audrius Butkevicius Date: Mon, 28 Jul 2014 00:08:15 +0100 Subject: [PATCH 1/3] Fix in-place removal --- config/config.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/config/config.go b/config/config.go index f061ff8f..44bb4528 100644 --- a/config/config.go +++ b/config/config.go @@ -403,16 +403,18 @@ func ensureNodePresent(nodes []NodeConfiguration, myID protocol.NodeID) []NodeCo } 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++ } + nodes = nodes[0:count] sort.Sort(NodeConfigurationList(nodes)) From 75388caeedd196e77b75d0c427e4a3156a46e0f7 Mon Sep 17 00:00:00 2001 From: Audrius Butkevicius Date: Mon, 28 Jul 2014 00:15:16 +0100 Subject: [PATCH 2/3] Prevent duplicate nodes in repos --- config/config.go | 24 ++++++++++++++++++++++++ config/config_test.go | 9 +++++++++ 2 files changed, 33 insertions(+) diff --git a/config/config.go b/config/config.go index 44bb4528..2d17604f 100644 --- a/config/config.go +++ b/config/config.go @@ -313,10 +313,12 @@ 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) 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) } // An empty address list is equivalent to a single "dynamic" entry @@ -420,3 +422,25 @@ loop: 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++ + } + nodes = nodes[0:count] + + sort.Sort(NodeConfigurationList(nodes)) + + return nodes +} diff --git a/config/config_test.go b/config/config_test.go index aceb2fc1..2caa823d 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
From 6b46465c77bfbd6c553394d38d6d7bb81a68141c Mon Sep 17 00:00:00 2001 From: Audrius Butkevicius Date: Mon, 28 Jul 2014 00:20:36 +0100 Subject: [PATCH 3/3] Avoid resorting multiple times --- config/config.go | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/config/config.go b/config/config.go index 2d17604f..5466d6d7 100644 --- a/config/config.go +++ b/config/config.go @@ -315,10 +315,12 @@ func Load(rd io.Reader, myID protocol.NodeID) (Configuration, error) { // 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 @@ -383,23 +385,17 @@ 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 } @@ -416,11 +412,7 @@ loop: } i++ } - nodes = nodes[0:count] - - sort.Sort(NodeConfigurationList(nodes)) - - return nodes + return nodes[0:count] } func ensureNoDuplicates(nodes []NodeConfiguration) []NodeConfiguration { @@ -438,9 +430,5 @@ loop: seenNodes[id] = true i++ } - nodes = nodes[0:count] - - sort.Sort(NodeConfigurationList(nodes)) - - return nodes + return nodes[0:count] }