mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-20 13:21:29 +02:00
MEDIUM: proxy: switch conf.name to cebis_tree
This is used to index the proxy's name and it contains a copy of the pointer to the proxy's name in <id>. Changing that for a ceb_node placed just before <id> saves 32 bytes to the struct proxy, which is now 3112 bytes large. Here we need to continue to support duplicates since they're still allowed between type-incompatible proxies. Interestingly, the use of cebis_next_dup() instead of cebis_next() in proxy_find_by_name() allows us to get rid of an strcmp() that was performed for each use_backend rule. A test with a large config (100k backends) shows that we can get 3% extra performance on a config involving a static use_backend rule (3.09M to 3.18M rps), and even 4.5% on a dynamic rule selecting a random backend (2.47M to 2.59M).
This commit is contained in:
parent
fdf6fd5b45
commit
d0d60a007d
@ -396,7 +396,8 @@ struct proxy {
|
||||
} timeout;
|
||||
__decl_thread(HA_RWLOCK_T lock); /* may be taken under the server's lock */
|
||||
|
||||
char *id, *desc; /* proxy id (name) and description */
|
||||
char *id; /* proxy id (name), indexed by <conf.name_node> below */
|
||||
char *desc; /* proxy description */
|
||||
struct proxy_per_tgroup *per_tgrp; /* array of per-tgroup stuff such as queues */
|
||||
unsigned int queueslength; /* Sum of the length of each queue */
|
||||
int totpend; /* total number of pending connections on this instance (for stats) */
|
||||
@ -468,7 +469,7 @@ struct proxy {
|
||||
struct list listeners; /* list of listeners belonging to this frontend */
|
||||
struct list errors; /* list of all custom error files */
|
||||
struct arg_list args; /* sample arg list that need to be resolved */
|
||||
struct ebpt_node by_name; /* proxies are stored sorted by name here */
|
||||
struct ceb_node name_node; /* proxies are stored sorted by name here; indexes <id> below */
|
||||
struct list lf_checks; /* list of logformats found in the proxy section that needs to be checked during postparse */
|
||||
struct log_steps log_steps; /* bitfield of log origins where log should be generated during request handling */
|
||||
const char *file_prev; /* file of the previous instance found with the same name, or NULL */
|
||||
|
@ -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 unsigned int error_snapshot_id; /* global ID assigned to each error then incremented */
|
||||
extern struct eb_root proxy_by_name; /* tree of proxies sorted by name */
|
||||
extern struct ceb_root *proxy_by_name; /* tree of proxies sorted by name */
|
||||
|
||||
extern const struct cfg_opt cfg_opts[];
|
||||
extern const struct cfg_opt cfg_opts2[];
|
||||
|
36
src/proxy.c
36
src/proxy.c
@ -16,8 +16,8 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <import/cebis_tree.h>
|
||||
#include <import/eb32tree.h>
|
||||
#include <import/ebistree.h>
|
||||
|
||||
#include <haproxy/acl.h>
|
||||
#include <haproxy/api.h>
|
||||
@ -62,8 +62,8 @@ 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 eb_root proxy_by_name = EB_ROOT; /* tree of proxies sorted by name */
|
||||
struct eb_root defproxy_by_name = EB_ROOT; /* tree of default proxies sorted by name (dups possible) */
|
||||
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 */
|
||||
unsigned int error_snapshot_id = 0; /* global ID assigned to each error then incremented */
|
||||
|
||||
@ -217,7 +217,7 @@ static inline void proxy_free_common(struct proxy *px)
|
||||
struct lf_expr *lf, *lfb;
|
||||
|
||||
/* note that the node's key points to p->id */
|
||||
ebpt_delete(&px->conf.by_name);
|
||||
cebis_item_delete((px->cap & PR_CAP_DEF) ? &defproxy_by_name : &proxy_by_name, conf.name_node, id, px);
|
||||
ha_free(&px->id);
|
||||
LIST_DEL_INIT(&px->global_list);
|
||||
drop_file_name(&px->conf.file);
|
||||
@ -1172,10 +1172,9 @@ static int proxy_parse_guid(char **args, int section_type, struct proxy *curpx,
|
||||
*/
|
||||
void proxy_store_name(struct proxy *px)
|
||||
{
|
||||
struct eb_root *root = (px->cap & PR_CAP_DEF) ? &defproxy_by_name : &proxy_by_name;
|
||||
struct ceb_root **root = (px->cap & PR_CAP_DEF) ? &defproxy_by_name : &proxy_by_name;
|
||||
|
||||
px->conf.by_name.key = px->id;
|
||||
ebis_insert(root, &px->conf.by_name);
|
||||
cebis_item_insert(root, conf.name_node, id, px);
|
||||
}
|
||||
|
||||
/* Returns a pointer to the first proxy matching capabilities <cap> and id
|
||||
@ -1219,16 +1218,11 @@ struct proxy *proxy_find_by_name(const char *name, int cap, int table)
|
||||
return curproxy;
|
||||
}
|
||||
else {
|
||||
struct eb_root *root;
|
||||
struct ebpt_node *node;
|
||||
struct ceb_root **root;
|
||||
|
||||
root = (cap & PR_CAP_DEF) ? &defproxy_by_name : &proxy_by_name;
|
||||
for (node = ebis_lookup(root, name); node; node = ebpt_next(node)) {
|
||||
curproxy = container_of(node, struct proxy, conf.by_name);
|
||||
|
||||
if (strcmp(curproxy->id, name) != 0)
|
||||
break;
|
||||
|
||||
for (curproxy = cebis_item_lookup(root, conf.name_node, id, name, struct proxy);
|
||||
curproxy; curproxy = cebis_item_next_dup(root, conf.name_node, id, curproxy)) {
|
||||
if ((curproxy->cap & cap) != cap)
|
||||
continue;
|
||||
|
||||
@ -1583,7 +1577,8 @@ void proxy_destroy_defaults(struct proxy *px)
|
||||
if (!(px->cap & PR_CAP_DEF))
|
||||
return;
|
||||
BUG_ON(px->conf.refcount != 0);
|
||||
ebpt_delete(&px->conf.by_name);
|
||||
cebis_item_delete((px->cap & PR_CAP_DEF) ? &defproxy_by_name : &proxy_by_name,
|
||||
conf.name_node, id, px);
|
||||
proxy_free_defaults(px);
|
||||
free(px);
|
||||
}
|
||||
@ -1593,14 +1588,11 @@ void proxy_destroy_defaults(struct proxy *px)
|
||||
*/
|
||||
void proxy_destroy_all_unref_defaults()
|
||||
{
|
||||
struct ebpt_node *n;
|
||||
struct proxy *px, *nx;
|
||||
|
||||
n = ebpt_first(&defproxy_by_name);
|
||||
while (n) {
|
||||
px = container_of(n, struct proxy, conf.by_name);
|
||||
for (px = cebis_item_first(&defproxy_by_name, conf.name_node, id, struct proxy); px; px = nx) {
|
||||
BUG_ON(!(px->cap & PR_CAP_DEF));
|
||||
n = ebpt_next(n);
|
||||
nx = cebis_item_next(&defproxy_by_name, conf.name_node, id, px);
|
||||
if (!px->conf.refcount)
|
||||
proxy_destroy_defaults(px);
|
||||
}
|
||||
@ -1624,7 +1616,7 @@ void proxy_unref_or_destroy_defaults(struct proxy *px)
|
||||
if (!px || !(px->cap & PR_CAP_DEF))
|
||||
return;
|
||||
|
||||
ebpt_delete(&px->conf.by_name);
|
||||
cebis_item_delete((px->cap & PR_CAP_DEF) ? &defproxy_by_name : &proxy_by_name, conf.name_node, id, px);
|
||||
if (px->conf.refcount) {
|
||||
/* still referenced just append it to the orphaned list */
|
||||
px->next = orphaned_default_proxies;
|
||||
|
Loading…
x
Reference in New Issue
Block a user