MINOR: checks: Use a tree instead of a list to store tcp-check rulesets

Since all tcp-check rulesets are globally stored, it is a problem to use
list. For configuration with many backends, the lookups in list may be costly
and slow downs HAProxy startup. To solve this problem, tcp-check rulesets are
now stored in a tree.
diff --git a/include/types/checks.h b/include/types/checks.h
index 84e9f07..5f6b5c9 100644
--- a/include/types/checks.h
+++ b/include/types/checks.h
@@ -329,9 +329,8 @@
 
 /* A list of tcp-check rules with a name */
 struct tcpcheck_ruleset {
-	char *name;         /* the ruleset name */
-	struct list rules;  /* the list of tcpcheck_rule */
-	struct list list;   /* used to chain rulesets */
+	struct list rules;     /* the list of tcpcheck_rule */
+	struct ebpt_node node; /* node in the shared tree */
 };
 
 
diff --git a/src/checks.c b/src/checks.c
index 0ea389e..9b28295 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -79,8 +79,8 @@
 	.name = "CHCK",
 };
 
-/* Global list to share all tcp-checks */
-struct list tcpchecks_list = LIST_HEAD_INIT(tcpchecks_list);
+/* Global tree to share all tcp-checks */
+struct eb_root shared_tcpchecks = EB_ROOT;
 
 
 DECLARE_STATIC_POOL(pool_head_email_alert,   "email_alert",   sizeof(struct email_alert));
@@ -899,10 +899,12 @@
 static struct tcpcheck_ruleset *find_tcpcheck_ruleset(const char *name)
 {
 	struct tcpcheck_ruleset *rs;
+	struct ebpt_node *node;
 
-	list_for_each_entry(rs, &tcpchecks_list, list) {
-		if (strcmp(rs->name, name) == 0)
-			return rs;
+	node = ebis_lookup_len(&shared_tcpchecks, name, strlen(name));
+	if (node) {
+		rs = container_of(node, typeof(*rs), node);
+		return rs;
 	}
 	return NULL;
 }
@@ -916,15 +918,14 @@
 	if (rs == NULL)
 		return NULL;
 
-	rs->name = strdup(name);
-	if (rs->name == NULL) {
+	rs->node.key = strdup(name);
+	if (rs->node.key == NULL) {
 		free(rs);
 		return NULL;
 	}
 
-	LIST_INIT(&rs->list);
 	LIST_INIT(&rs->rules);
-	LIST_ADDQ(&tcpchecks_list, &rs->list);
+	ebis_insert(&shared_tcpchecks, &rs->node);
 	return rs;
 }
 
@@ -935,12 +936,12 @@
 	if (!rs)
 		return;
 
-	LIST_DEL(&rs->list);
+	ebpt_delete(&rs->node);
+	free(rs->node.key);
 	list_for_each_entry_safe(r, rb, &rs->rules, list) {
 		LIST_DEL(&r->list);
 		free_tcpcheck(r, 0);
 	}
-	free(rs->name);
 	free(rs);
 }
 
@@ -5044,17 +5045,22 @@
 
 static void deinit_tcpchecks()
 {
-	struct tcpcheck_ruleset *rs, *rsb;
+	struct tcpcheck_ruleset *rs;
 	struct tcpcheck_rule *r, *rb;
+	struct ebpt_node *node, *next;
 
-	list_for_each_entry_safe(rs, rsb, &tcpchecks_list, list) {
-		LIST_DEL(&rs->list);
+	node = ebpt_first(&shared_tcpchecks);
+	while (node) {
+		next = ebpt_next(node);
+		ebpt_delete(node);
+		free(node->key);
+		rs = container_of(node, typeof(*rs), node);
 		list_for_each_entry_safe(r, rb, &rs->rules, list) {
 			LIST_DEL(&r->list);
 			free_tcpcheck(r, 0);
 		}
-		free(rs->name);
 		free(rs);
+		node = next;
 	}
 }
 
@@ -5830,7 +5836,7 @@
 	chk->index = 1;
 	LIST_ADDQ(&rs->rules, &chk->list);
 
-	LIST_ADDQ(&tcpchecks_list, &rs->list);
+	ebis_insert(&shared_tcpchecks, &rs->node);
 
   ruleset_found:
 	rules->list = &rs->rules;
@@ -5931,7 +5937,7 @@
 	chk->index = 1;
 	LIST_ADDQ(&rs->rules, &chk->list);
 
-	LIST_ADDQ(&tcpchecks_list, &rs->list);
+	ebis_insert(&shared_tcpchecks, &rs->node);
 
   ruleset_found:
 	rules->list = &rs->rules;
@@ -6069,7 +6075,7 @@
 	chk->index = 4;
 	LIST_ADDQ(&rs->rules, &chk->list);
 
-	LIST_ADDQ(&tcpchecks_list, &rs->list);
+	ebis_insert(&shared_tcpchecks, &rs->node);
 
   ruleset_found:
 	rules->list = &rs->rules;
@@ -6216,7 +6222,7 @@
 	chk->index = 3;
 	LIST_ADDQ(&rs->rules, &chk->list);
 
-	LIST_ADDQ(&tcpchecks_list, &rs->list);
+	ebis_insert(&shared_tcpchecks, &rs->node);
 
   ruleset_found:
 	rules->list = &rs->rules;
@@ -6442,7 +6448,7 @@
 		LIST_ADDQ(&rs->rules, &chk->list);
 	}
 
-	LIST_ADDQ(&tcpchecks_list, &rs->list);
+	ebis_insert(&shared_tcpchecks, &rs->node);
 
   ruleset_found:
 	rules->list = &rs->rules;
@@ -6527,7 +6533,7 @@
 	chk->index = 2;
 	LIST_ADDQ(&rs->rules, &chk->list);
 
-	LIST_ADDQ(&tcpchecks_list, &rs->list);
+	ebis_insert(&shared_tcpchecks, &rs->node);
 
   ruleset_found:
 	rules->list = &rs->rules;
@@ -6604,7 +6610,7 @@
 	chk->index = 1;
 	LIST_ADDQ(&rs->rules, &chk->list);
 
-	LIST_ADDQ(&tcpchecks_list, &rs->list);
+	ebis_insert(&shared_tcpchecks, &rs->node);
 
   ruleset_found:
 	rules->list = &rs->rules;
@@ -6953,7 +6959,7 @@
 	chk->index = 1;
 	LIST_ADDQ(&rs->rules, &chk->list);
 
-	LIST_ADDQ(&tcpchecks_list, &rs->list);
+	ebis_insert(&shared_tcpchecks, &rs->node);
 
   ruleset_found:
 	rules->list = &rs->rules;