]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: server: switch conf.name to cebis_tree
authorWilly Tarreau <w@1wt.eu>
Mon, 7 Jul 2025 13:33:40 +0000 (15:33 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 16 Sep 2025 07:23:46 +0000 (09:23 +0200)
This is used to index the server name and it contains a copy of the
pointer to the server's name in <id>. Changing that for a ceb_node placed
just before <id> saves 32 bytes to the struct server, which remains 3968
bytes large due to alignment. The proxy struct shrinks by 8 bytes to 3144.

It's worth noting that the current way duplicate names are handled remains
based on the previous mechanism where dups were permitted. Ideally we
should now reject them during insertion and use unique key trees instead.

include/haproxy/proxy-t.h
include/haproxy/server-t.h
src/cfgparse.c
src/server.c

index db9526a8a5ed0854b8eea47a6ce791ac4f82e978..1bf0008cdc2471e215c62dfb65896f9f8d4e5485 100644 (file)
@@ -463,7 +463,7 @@ struct proxy {
                int line;                       /* line where the section appears */
                struct eb_root used_listener_id;/* list of listener IDs in use */
                struct eb_root used_server_id;  /* list of server IDs in use */
-               struct eb_root used_server_name; /* list of server names in use */
+               struct ceb_root *used_server_name; /* list of server names in use */
                struct list bind;               /* list of bind settings */
                struct list listeners;          /* list of listeners belonging to this frontend */
                struct list errors;             /* list of all custom error files */
index fe5e4d78e0c92bb6fcb82e4ba2621ddfed3c5792..f55488d33b9c746ff620a5c58edad3ef80b14493 100644 (file)
@@ -368,6 +368,7 @@ struct server {
        unsigned long last_change;              /* internal use only (not for stats purpose): last time the server state was changed, doesn't change often, not updated atomically on purpose */
 
        char *id;                               /* just for identification */
+
        uint32_t rid;                           /* revision: if id has been reused for a new server, rid won't match */
        unsigned iweight,uweight, cur_eweight;  /* initial weight, user-specified weight, and effective weight */
        unsigned wscore;                        /* weight score, used during srv map computation */
@@ -510,7 +511,7 @@ struct server {
        struct {
                const char *file;               /* file where the section appears */
                struct eb32_node id;            /* place in the tree of used IDs */
-               struct ebpt_node name;          /* place in the tree of used names */
+               struct ceb_node name_node;      /* place in the tree of used names, indexes <id> above, not unique, indexed in px->used_server_name */
                int line;                       /* line where the section appears */
        } conf;                                 /* config information */
 
index 0bd29feb01c9e945adf15c04f711bea38c962204..8e25c9ef4a8d37e099838122961c233b41b2114c 100644 (file)
@@ -36,6 +36,8 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include <import/cebis_tree.h>
+
 #include <haproxy/acl.h>
 #include <haproxy/action.h>
 #include <haproxy/api.h>
@@ -3702,12 +3704,11 @@ out_uri_auth_compat:
                        /* Note: internal servers are not always registered and
                         * they do not conflict.
                         */
-                       if (!newsrv->conf.name.node.leaf_p)
+                       if (!ceb_intree(&newsrv->conf.name_node))
                                continue;
 
                        for (other_srv = newsrv;
-                            (other_srv = container_of_safe(ebpt_prev_dup(&other_srv->conf.name),
-                                                           struct server, conf.name)); ) {
+                            (other_srv = cebis_item_prev_dup(&curproxy->conf.used_server_name, conf.name_node, id, other_srv)); ) {
                                ha_alert("parsing [%s:%d] : %s '%s', another server named '%s' was already defined at line %d, please use distinct names.\n",
                                         newsrv->conf.file, newsrv->conf.line,
                                         proxy_type_str(curproxy), curproxy->id,
index b8dcc2bdc15901c27e0099a5ae1433b2c746eb51..a9dad40aa7d6cdeb7fbcffa1117aa3275be8582a 100644 (file)
@@ -3207,7 +3207,7 @@ struct server *srv_drop(struct server *srv)
        //BUG_ON(ceb_intree(&srv->addr_node) ||
        //       srv->idle_node.node.leaf_p ||
        //       srv->conf.id.node.leaf_p ||
-       //       srv->conf.name.node.leaf_p);
+       //       ceb_intree(&srv->name_node));
 
        guid_remove(&srv->guid);
 
@@ -3359,8 +3359,7 @@ static int _srv_parse_tmpl_init(struct server *srv, struct proxy *px)
 
        /* Set the first server's ID. */
        _srv_parse_set_id_from_prefix(srv, srv->tmpl_info.prefix, srv->tmpl_info.nb_low);
-       srv->conf.name.key = srv->id;
-       ebis_insert(&curproxy->conf.used_server_name, &srv->conf.name);
+       cebis_item_insert(&curproxy->conf.used_server_name, conf.name_node, id, srv);
 
        /* then create other servers from this one */
        for (i = srv->tmpl_info.nb_low + 1; i <= srv->tmpl_info.nb_high; i++) {
@@ -3384,8 +3383,7 @@ static int _srv_parse_tmpl_init(struct server *srv, struct proxy *px)
                /* Set this new server ID. */
                _srv_parse_set_id_from_prefix(newsrv, srv->tmpl_info.prefix, i);
 
-               newsrv->conf.name.key = newsrv->id;
-               ebis_insert(&curproxy->conf.used_server_name, &newsrv->conf.name);
+               cebis_item_insert(&curproxy->conf.used_server_name, conf.name_node, id, newsrv);
        }
 
        return i - srv->tmpl_info.nb_low;
@@ -3993,8 +3991,7 @@ int parse_server(const char *file, int linenum, char **args,
                _srv_parse_tmpl_init(newsrv, curproxy);
        }
        else if (!(parse_flags & SRV_PARSE_DEFAULT_SERVER)) {
-               newsrv->conf.name.key = newsrv->id;
-               ebis_insert(&curproxy->conf.used_server_name, &newsrv->conf.name);
+               cebis_item_insert(&curproxy->conf.used_server_name, conf.name_node, id, newsrv);
        }
 
        /* If the server id is fixed, insert it in the proxy used_id tree.
@@ -4042,15 +4039,10 @@ struct server *server_find_by_id_unique(struct proxy *bk, int id, uint32_t rid)
  */
 struct server *server_find_by_name(struct proxy *px, const char *name)
 {
-       struct ebpt_node *node;
-       struct server *cursrv;
-
        if (!px)
                return NULL;
 
-       node = ebis_lookup(&px->conf.used_server_name, name);
-       cursrv = node ? container_of(node, struct server, conf.name) : NULL;
-       return cursrv;
+       return cebis_item_lookup(&px->conf.used_server_name, conf.name_node, id, name, struct server);
 }
 
 /*
@@ -6244,11 +6236,10 @@ static int cli_parse_add_server(char **args, char *payload, struct appctx *appct
 
                srv->conf.id.key = srv->puid = next_id;
        }
-       srv->conf.name.key = srv->id;
 
        /* insert the server in the backend trees */
        eb32_insert(&be->conf.used_server_id, &srv->conf.id);
-       ebis_insert(&be->conf.used_server_name, &srv->conf.name);
+       cebis_item_insert(&be->conf.used_server_name, conf.name_node, id, srv);
        /* addr_key could be NULL if FQDN resolution is postponed (ie: add server from cli) */
        if (srv->addr_key)
                cebuis_item_insert(&be->used_server_addr, addr_node, addr_key, srv);
@@ -6467,7 +6458,7 @@ static int cli_parse_delete_server(char **args, char *payload, struct appctx *ap
 
        /* remove srv from addr_node tree */
        eb32_delete(&srv->conf.id);
-       ebpt_delete(&srv->conf.name);
+       cebis_item_delete(&be->conf.used_server_name, conf.name_node, id, srv);
        cebuis_item_delete(&be->used_server_addr, addr_node, addr_key, srv);
 
        /* remove srv from idle_node tree for idle conn cleanup */