]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: server: index server ID using compact trees
authorWilly Tarreau <w@1wt.eu>
Sun, 24 Aug 2025 09:21:02 +0000 (11:21 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 16 Sep 2025 07:23:46 +0000 (09:23 +0200)
The server ID is currently stored as a 32-bit int using an eb32 tree.
It's used essentially to find holes in order to automatically assign IDs,
and to detect duplicates. Let's change this to use compact trees instead
in order to save 24 bytes in struct server for this node, plus 8 bytes in
struct proxy. The server struct is still 3904 bytes large (due to
alignment) and the proxy struct is 3072.

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

index 50da4dcad0869076c07a244b6abf13cf121c0aeb..5e0d5bc4a7eee7acd6a4bbb85f1b5b28c12c551b 100644 (file)
@@ -463,7 +463,7 @@ struct proxy {
                struct ceb_node uuid_node;      /* place in the tree of used IDs, indexes <uuid> above */
                int line;                       /* line where the section appears */
                struct ceb_root *used_listener_id; /* list of listener IDs in use */
-               struct eb_root used_server_id;  /* list of server IDs in use */
+               struct ceb_root *used_server_id;   /* list of server IDs 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 */
index e4685b540e146d18296942c4ffe0ddcefc88441f..093e7b5f2f7bca64fc6dc00001c6722345e81b66 100644 (file)
@@ -439,7 +439,7 @@ struct server {
        unsigned int svc_port;                  /* the port to connect to (for relevant families) */
        unsigned down_time;                     /* total time the server was down */
 
-       int puid;                               /* proxy-unique server ID, used for SNMP, and "first" LB algo */
+       int puid;                               /* proxy-unique server ID, used for SNMP, and "first" LB algo, indexed via puid_node below */
        int tcp_ut;                             /* for TCP, user timeout */
        char *tcp_md5sig;                       /* TCP MD5 signature password (RFC2385) */
 
@@ -511,7 +511,7 @@ struct server {
        struct task *srvrq_check;               /* Task testing SRV record expiration date for this server */
        struct {
                const char *file;               /* file where the section appears */
-               struct eb32_node id;            /* place in the tree of used IDs */
+               struct ceb_node puid_node;      /* place in the tree of used IDs, indexes <puid> above */
                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 606c1f4e8fb3a37b9b0a9fa12907569a27e2861b..1b311e4a137c0fadd6d4973b00efc2e46a37f27a 100644 (file)
@@ -24,6 +24,8 @@
 
 #include <unistd.h>
 
+#include <import/ceb32_tree.h>
+
 #include <haproxy/api.h>
 #include <haproxy/applet-t.h>
 #include <haproxy/arg-t.h>
@@ -199,7 +201,7 @@ static inline void srv_free(struct server **srv_ptr)
 /* index server <srv>'s id into proxy <px>'s used_server_id */
 static inline void server_index_id(struct proxy *px, struct server *srv)
 {
-       eb32_insert(&px->conf.used_server_id, &srv->conf.id);
+       ceb32_item_insert(&px->conf.used_server_id, conf.puid_node, puid, srv);
 }
 
 /* increase the number of cumulated streams on the designated server */
@@ -372,10 +374,7 @@ static inline void srv_detach(struct server *srv)
  */
 static inline struct server *server_find_by_id(struct proxy *bk, int id)
 {
-       struct eb32_node *eb32;
-
-       eb32 = eb32_lookup(&bk->conf.used_server_id, id);
-       return eb32 ? container_of(eb32, struct server, conf.id) : NULL;
+       return ceb32_item_lookup(&bk->conf.used_server_id, conf.puid_node, puid, id, struct server);
 }
 
 
index 8bc57eebf8d23082626fb1d7f19775c2fd31f12a..288502b61cdd222c3af2161de1e70f0057e3b232 100644 (file)
@@ -3727,7 +3727,7 @@ out_uri_auth_compat:
                                 * spare entry starting with next_svid.
                                 */
                                next_id = server_get_next_id(curproxy, next_id);
-                               newsrv->conf.id.key = newsrv->puid = next_id;
+                               newsrv->puid = next_id;
                                server_index_id(curproxy, newsrv);
                        }
 
index 524c886d4aefb051814984a40f3be8ed1169449b..527ae09c452b58338120372339954fe850c17f97 100644 (file)
@@ -1477,7 +1477,7 @@ void init_new_proxy(struct proxy *p)
        MT_LIST_INIT(&p->lbprm.lb_free_list);
 
        p->conf.used_listener_id = NULL;
-       p->conf.used_server_id   = EB_ROOT;
+       p->conf.used_server_id   = NULL;
        p->used_server_addr      = NULL;
 
        /* Timeouts are defined as -1 */
index 94b76917a557cdff759afcb770cbad339476b78c..8457573fedab42664326a53ff0e21a16c97f6fda 100644 (file)
@@ -872,11 +872,11 @@ static const char *srv_find_best_kw(const char *word)
  */
 uint server_get_next_id(const struct proxy *px, uint from)
 {
-       const struct eb32_node *used;
+       const struct server *sv;
 
        do {
-               used = eb32_lookup_ge((struct eb_root *)&px->conf.used_server_id, from);
-               if (!used || used->key > from)
+               sv = ceb32_item_lookup_ge(&px->conf.used_server_id, conf.puid_node, puid, from, struct server);
+               if (!sv || sv->puid > from)
                        return from; /* available */
                from++;
        } while (from);
@@ -1310,7 +1310,6 @@ static int srv_parse_id(char **args, int *cur_arg, struct proxy *curproxy, struc
        }
 
        newsrv->puid = atol(args[*cur_arg + 1]);
-       newsrv->conf.id.key = newsrv->puid;
 
        if (newsrv->puid <= 0) {
                memprintf(err, "'%s' : custom id has to be > 0", args[*cur_arg]);
@@ -6250,7 +6249,7 @@ static int cli_parse_add_server(char **args, char *payload, struct appctx *appct
                        goto out;
                }
 
-               srv->conf.id.key = srv->puid = next_id;
+               srv->puid = next_id;
        }
 
        /* insert the server in the backend trees */
@@ -6473,7 +6472,7 @@ static int cli_parse_delete_server(char **args, char *payload, struct appctx *ap
        srv_detach(srv);
 
        /* remove srv from addr_node tree */
-       eb32_delete(&srv->conf.id);
+       ceb32_item_delete(&be->conf.used_server_id, conf.puid_node, puid, srv);
        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);