From 0e99f64fc68341c37e21249f654f1a3b801c0492 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 7 Jul 2025 15:13:15 +0200 Subject: [PATCH] MEDIUM: server: switch addr_node to cebis_tree This contains the text representation of the server's address, for use with stick-tables with "srvkey addr". Switching them to a compact node saves 24 more bytes from this structure. The key was moved to an external pointer "addr_key" right after the node. The server struct is now 3968 bytes (down from 4032) due to alignment, and the proxy struct shrinks by 8 bytes to 3152. --- include/haproxy/proxy-t.h | 2 +- include/haproxy/server-t.h | 5 ++++- src/proxy.c | 2 +- src/server.c | 31 +++++++++++++++---------------- src/stream.c | 2 +- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/include/haproxy/proxy-t.h b/include/haproxy/proxy-t.h index cb6fc318a..db9526a8a 100644 --- a/include/haproxy/proxy-t.h +++ b/include/haproxy/proxy-t.h @@ -476,7 +476,7 @@ struct proxy { unsigned int refcount; /* refcount on this proxy (only used for default proxy for now) */ } conf; /* config information */ struct http_ext *http_ext; /* http ext options */ - struct eb_root used_server_addr; /* list of server addresses in use */ + struct ceb_root *used_server_addr; /* list of server addresses in use */ void *parent; /* parent of the proxy when applicable */ struct comp *comp; /* http compression */ diff --git a/include/haproxy/server-t.h b/include/haproxy/server-t.h index af6ffdee8..fe5e4d78e 100644 --- a/include/haproxy/server-t.h +++ b/include/haproxy/server-t.h @@ -513,7 +513,10 @@ struct server { struct ebpt_node name; /* place in the tree of used names */ int line; /* line where the section appears */ } conf; /* config information */ - struct ebpt_node addr_node; /* Node for string representation of address for the server (including port number) */ + + struct ceb_node addr_node; /* Indexing node for the addr_key below, from px->used_server_addr */ + char *addr_key; /* string representation of address for the server (including port number) */ + /* Template information used only for server objects which * serve as template filled at parsing time and used during * server allocations from server templates. diff --git a/src/proxy.c b/src/proxy.c index 7030eb803..038870e0e 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -1471,7 +1471,7 @@ void init_new_proxy(struct proxy *p) p->conf.used_listener_id = EB_ROOT; p->conf.used_server_id = EB_ROOT; - p->used_server_addr = EB_ROOT_UNIQUE; + p->used_server_addr = NULL; /* Timeouts are defined as -1 */ proxy_reset_timeouts(p); diff --git a/src/server.c b/src/server.c index 514a1c61f..b8dcc2bdc 100644 --- a/src/server.c +++ b/src/server.c @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -729,25 +730,25 @@ static void srv_set_addr_desc(struct server *s, int reattach) key = sa2str(&s->addr, s->svc_port, s->flags & SRV_F_MAPPORTS); - if (s->addr_node.key) { - if (key && strcmp(key, s->addr_node.key) == 0) { + if (s->addr_key) { + if (key && strcmp(key, s->addr_key) == 0) { free(key); return; } HA_RWLOCK_WRLOCK(PROXY_LOCK, &p->lock); - ebpt_delete(&s->addr_node); + cebuis_item_delete(&p->used_server_addr, addr_node, addr_key, s); HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &p->lock); - free(s->addr_node.key); + free(s->addr_key); } - s->addr_node.key = key; + s->addr_key = key; if (reattach) { - if (s->addr_node.key) { + if (s->addr_key) { HA_RWLOCK_WRLOCK(PROXY_LOCK, &p->lock); - ebis_insert(&p->used_server_addr, &s->addr_node); + cebuis_item_insert(&p->used_server_addr, addr_node, addr_key, s); HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &p->lock); } } @@ -3152,7 +3153,7 @@ void srv_free_params(struct server *srv) release_sample_expr(srv->pool_conn_name_expr); free(srv->resolvers_id); free(srv->tcp_md5sig); - free(srv->addr_node.key); + free(srv->addr_key); free(srv->lb_nodes); counters_be_shared_drop(&srv->counters.shared); if (srv->log_target) { @@ -3203,7 +3204,7 @@ struct server *srv_drop(struct server *srv) /* This BUG_ON() is invalid for now as server released on deinit will * trigger it as they are not properly removed from their tree. */ - //BUG_ON(srv->addr_node.node.leaf_p || + //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); @@ -4059,12 +4060,10 @@ struct server *server_find_by_name(struct proxy *px, const char *name) */ struct server *server_find_by_addr(struct proxy *px, const char *addr) { - struct ebpt_node *node; struct server *cursrv; HA_RWLOCK_RDLOCK(PROXY_LOCK, &px->lock); - node = ebis_lookup(&px->used_server_addr, addr); - cursrv = node ? container_of(node, struct server, addr_node) : NULL; + cursrv = cebuis_item_lookup(&px->used_server_addr, addr_node, addr_key, addr, struct server); HA_RWLOCK_RDUNLOCK(PROXY_LOCK, &px->lock); return cursrv; } @@ -6250,9 +6249,9 @@ static int cli_parse_add_server(char **args, char *payload, struct appctx *appct /* 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); - /* addr_node.key could be NULL if FQDN resolution is postponed (ie: add server from cli) */ - if (srv->addr_node.key) - ebis_insert(&be->used_server_addr, &srv->addr_node); + /* 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); /* check if LSB bit (odd bit) is set for reuse_cnt */ if (srv_id_reuse_cnt & 1) { @@ -6469,7 +6468,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); - ebpt_delete(&srv->addr_node); + cebuis_item_delete(&be->used_server_addr, addr_node, addr_key, srv); /* remove srv from idle_node tree for idle conn cleanup */ eb32_delete(&srv->idle_node); diff --git a/src/stream.c b/src/stream.c index f7784c53a..206facbe3 100644 --- a/src/stream.c +++ b/src/stream.c @@ -1439,7 +1439,7 @@ static int process_store_rules(struct stream *s, struct channel *rep, int an_bit if (t->server_key_type == STKTABLE_SRV_NAME) key = __objt_server(s->target)->id; else if (t->server_key_type == STKTABLE_SRV_ADDR) - key = __objt_server(s->target)->addr_node.key; + key = __objt_server(s->target)->addr_key; else key = NULL;