From: Willy Tarreau Date: Sun, 24 Aug 2025 09:21:02 +0000 (+0200) Subject: MEDIUM: server: index server ID using compact trees X-Git-Tag: v3.3-dev9~95 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d18d972b1f430684ff90683703de4e18650f0615;p=thirdparty%2Fhaproxy.git MEDIUM: server: index server ID using compact trees 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. --- diff --git a/include/haproxy/proxy-t.h b/include/haproxy/proxy-t.h index 50da4dcad..5e0d5bc4a 100644 --- a/include/haproxy/proxy-t.h +++ b/include/haproxy/proxy-t.h @@ -463,7 +463,7 @@ struct proxy { struct ceb_node uuid_node; /* place in the tree of used IDs, indexes 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 */ diff --git a/include/haproxy/server-t.h b/include/haproxy/server-t.h index e4685b540..093e7b5f2 100644 --- a/include/haproxy/server-t.h +++ b/include/haproxy/server-t.h @@ -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 above */ struct ceb_node name_node; /* place in the tree of used names, indexes above, not unique, indexed in px->used_server_name */ int line; /* line where the section appears */ } conf; /* config information */ diff --git a/include/haproxy/server.h b/include/haproxy/server.h index 606c1f4e8..1b311e4a1 100644 --- a/include/haproxy/server.h +++ b/include/haproxy/server.h @@ -24,6 +24,8 @@ #include +#include + #include #include #include @@ -199,7 +201,7 @@ static inline void srv_free(struct server **srv_ptr) /* index server 's id into proxy '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); } diff --git a/src/cfgparse.c b/src/cfgparse.c index 8bc57eebf..288502b61 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -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); } diff --git a/src/proxy.c b/src/proxy.c index 524c886d4..527ae09c4 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -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 */ diff --git a/src/server.c b/src/server.c index 94b76917a..8457573fe 100644 --- a/src/server.c +++ b/src/server.c @@ -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);