summaryrefslogtreecommitdiff
path: root/ctdb/server/ipalloc.c
diff options
context:
space:
mode:
authorMartin Schwenke <martin@meltin.net>2016-11-18 16:08:13 +1100
committerAmitay Isaacs <amitay@samba.org>2016-12-02 00:24:28 +0100
commit429377a2426fdfc8c3f7d8854fa2189ad36ff78c (patch)
tree4b7f0c2754529397df40eca7cc07b88c4170e465 /ctdb/server/ipalloc.c
parent24db43839f8a17c4498454d4bbd24411f647defa (diff)
downloadsamba-429377a2426fdfc8c3f7d8854fa2189ad36ff78c.tar.gz
ctdb-ipalloc: Optimise check to see if IP is available on a node
Use a "bitmap" of available IPs for each IP address instead of walking the list of available IP addresses. For ctdb/tests/takeover/lcp2.030.sh, this improves the time taken on my laptop from: real 0m11.997s user 0m11.960s sys 0m0.000s to real 0m8.571s user 0m8.544s sys 0m0.000s So, when assigning all 900 IP addresses the improvement is about 25%. For the no-op case (where all IPs are already assigned to nodes), the extra setup adds a small fraction of a second for 900 IPs. Intermediate cases result in intermediate improvements. Signed-off-by: Martin Schwenke <martin@meltin.net> Reviewed-by: Amitay Isaacs <amitay@gmail.com>
Diffstat (limited to 'ctdb/server/ipalloc.c')
-rw-r--r--ctdb/server/ipalloc.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/ctdb/server/ipalloc.c b/ctdb/server/ipalloc.c
index 37804ea029e..819add164b0 100644
--- a/ctdb/server/ipalloc.c
+++ b/ctdb/server/ipalloc.c
@@ -29,6 +29,8 @@
#include "common/logging.h"
#include "common/rb_tree.h"
+#include "protocol/protocol_api.h"
+
#include "server/ipalloc_private.h"
/* Initialise main ipalloc state and sub-structures */
@@ -160,6 +162,37 @@ create_merged_ip_list(struct ipalloc_state *ipalloc_state)
return ip_list;
}
+static bool populate_bitmap(struct ipalloc_state *ipalloc_state)
+{
+ struct public_ip_list *ip = NULL;
+ int i, j;
+
+ for (ip = ipalloc_state->all_ips; ip != NULL; ip = ip->next) {
+
+ ip->available_on = talloc_zero_array(ip, bool,
+ ipalloc_state->num);
+ if (ip->available_on == NULL) {
+ return false;
+ }
+
+ for (i = 0; i < ipalloc_state->num; i++) {
+ struct ctdb_public_ip_list *avail =
+ &ipalloc_state->available_public_ips[i];
+
+ /* Check to see if "ip" is available on node "i" */
+ for (j = 0; j < avail->num; j++) {
+ if (ctdb_sock_addr_same_ip(
+ &ip->addr, &avail->ip[j].addr)) {
+ ip->available_on[i] = true;
+ break;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
static bool all_nodes_are_disabled(struct ctdb_node_map *nodemap)
{
int i;
@@ -283,6 +316,10 @@ struct public_ip_list *ipalloc(struct ipalloc_state *ipalloc_state)
return NULL;
}
+ if (!populate_bitmap(ipalloc_state)) {
+ return NULL;
+ }
+
switch (ipalloc_state->algorithm) {
case IPALLOC_LCP2:
ret = ipalloc_lcp2(ipalloc_state);