]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: proxy: index proxy ID using compact trees
authorWilly Tarreau <w@1wt.eu>
Sat, 23 Aug 2025 17:57:29 +0000 (19:57 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 16 Sep 2025 07:23:46 +0000 (09:23 +0200)
The proxy 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 proxy for this node, plus 8 bytes in
the root (which is static so not much relevant here). Now the proxy is
3088 bytes large.

include/haproxy/proxy-t.h
include/haproxy/proxy.h
src/cfgparse-listen.c
src/cfgparse.c
src/cli.c
src/proxy.c

index 6d93eeb54481a4ebd3f61cb5f924d7fe9fd15fb3..66b9f110a6a24ae7ae71d650d92dbe52c0bc0e69 100644 (file)
@@ -441,7 +441,7 @@ struct proxy {
        char *check_path;                       /* PATH environment to use for external agent checks */
        struct http_reply *replies[HTTP_ERR_SIZE]; /* HTTP replies for known errors */
        unsigned int log_count;                 /* number of logs produced by the frontend */
-       int uuid;                               /* universally unique proxy ID, used for SNMP */
+       int uuid;                               /* universally unique proxy ID, used for SNMP, indexed by conf.uuid_node below */
        unsigned int backlog;                   /* force the frontend's listen backlog */
        unsigned int li_all;                    /* total number of listeners attached to this proxy */
        unsigned int li_paused;                 /* total number of listeners paused (LI_PAUSED) */
@@ -460,7 +460,7 @@ struct proxy {
 
        struct {
                const char *file;               /* file where the section appears */
-               struct eb32_node id;            /* place in the tree of used IDs */
+               struct ceb_node uuid_node;      /* place in the tree of used IDs, indexes <uuid> above */
                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 */
index 98df4d1e692f0a5e1a136e01f4e6445ea981d632..c1407c3ccc2dcb84f23403b796159968cf25d27f 100644 (file)
@@ -22,7 +22,7 @@
 #ifndef _HAPROXY_PROXY_H
 #define _HAPROXY_PROXY_H
 
-#include <import/eb32tree.h>
+#include <import/ceb32_tree.h>
 
 #include <haproxy/api.h>
 #include <haproxy/applet-t.h>
@@ -36,7 +36,7 @@
 
 extern struct proxy *proxies_list;
 extern struct list proxies;
-extern struct eb_root used_proxy_id;   /* list of proxy IDs in use */
+extern struct ceb_root *used_proxy_id;  /* list of proxy IDs in use */
 extern unsigned int error_snapshot_id;  /* global ID assigned to each error then incremented */
 extern struct ceb_root *proxy_by_name;    /* tree of proxies sorted by name */
 
@@ -125,7 +125,7 @@ static inline struct proxy *proxy_be_by_name(const char *name)
 /* index proxy <px>'s id into used_proxy_id */
 static inline void proxy_index_id(struct proxy *px)
 {
-       eb32_insert(&used_proxy_id, &px->conf.id);
+       ceb32_item_insert(&used_proxy_id, conf.uuid_node, uuid, px);
 }
 
 /* this function initializes all timeouts for proxy p */
index 4cfd8630793ccf35a15e5d1f70850321cbeafbc0..b47e587f40a179132c77bd6469102460c17d1a4b 100644 (file)
@@ -732,7 +732,6 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
                }
 
                curproxy->uuid = atol(args[1]);
-               curproxy->conf.id.key = curproxy->uuid;
                curproxy->options |= PR_O_FORCED_ID;
 
                if (curproxy->uuid <= 0) {
index 26239b484851d1b692f9f5086074bee7bf1b9825..7814ceadc2852b6125383f2674cbd20e59bc7387 100644 (file)
@@ -2851,7 +2851,7 @@ init_proxies_list_stage1:
                         * possibly reuse existing IDs.
                         */
                        next_pxid = proxy_get_next_id(next_pxid);
-                       curproxy->conf.id.key = curproxy->uuid = next_pxid;
+                       curproxy->uuid = next_pxid;
                        proxy_index_id(curproxy);
                }
 
index 60f0119c5a874400fb7a1984e922fdd4c333b200..331764531fe50a630236398f97f1c799682c4818 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -466,7 +466,7 @@ static struct proxy *cli_alloc_fe(const char *name, const char *file, int line)
        fe->default_target = &cli_applet.obj_type;
 
        /* the stats frontend is the only one able to assign ID #0 */
-       fe->conf.id.key = fe->uuid = 0;
+       fe->uuid = 0;
        proxy_index_id(fe);
        return fe;
 }
index a9ca53482595589284ce39f361f36121168c4cda..7339945647427279361f465b8fc970dacb13ac62 100644 (file)
@@ -61,7 +61,7 @@
 int listeners; /* # of proxy listeners, set by cfgparse */
 struct proxy *proxies_list  = NULL;     /* list of main proxies */
 struct list proxies = LIST_HEAD_INIT(proxies); /* list of all proxies */
-struct eb_root used_proxy_id = EB_ROOT;        /* list of proxy IDs in use */
+struct ceb_root *used_proxy_id = NULL; /* list of proxy IDs in use */
 struct ceb_root *proxy_by_name = NULL; /* tree of proxies sorted by name */
 struct ceb_root *defproxy_by_name = NULL; /* tree of default proxies sorted by name (dups possible) */
 struct proxy *orphaned_default_proxies = NULL; /* deleted ones with refcount != 0 */
@@ -544,11 +544,11 @@ const char *proxy_find_best_option(const char *word, const char **extra)
  */
 uint proxy_get_next_id(uint from)
 {
-       struct eb32_node *used;
+       const struct proxy *px;
 
        do {
-               used = eb32_lookup_ge(&used_proxy_id, from);
-               if (!used || used->key > from)
+               px = ceb32_item_lookup_ge(&used_proxy_id, conf.uuid_node, uuid, from, struct proxy);
+               if (!px || px->uuid > from)
                        return from; /* available */
                from++;
        } while (from);
@@ -1200,14 +1200,10 @@ void proxy_store_name(struct proxy *px)
  */
 struct proxy *proxy_find_by_id(int id, int cap, int table)
 {
-       struct eb32_node *n;
-
-       for (n = eb32_lookup(&used_proxy_id, id); n; n = eb32_next(n)) {
-               struct proxy *px = container_of(n, struct proxy, conf.id);
-
-               if (px->uuid != id)
-                       break;
+       struct proxy *px;
 
+       for (px = ceb32_item_lookup(&used_proxy_id, conf.uuid_node, uuid, id, struct proxy);
+            px ; px = ceb32_item_next_dup(&used_proxy_id, conf.uuid_node, uuid, px)) {
                if ((px->cap & cap) != cap)
                        continue;