From e3f023f67709d4fc44d3dbe5435010eb852d2dc6 Mon Sep 17 00:00:00 2001 From: willy tarreau Date: Sat, 8 Apr 2006 21:52:24 +0200 Subject: [PATCH] * added the 'weight' parameter to the servers, limited to 1..256. It is factored between all the servers so that the servers map will be smaller and easier to construct. --- haproxy.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/haproxy.c b/haproxy.c index 817cb0d2e..f1d369a57 100644 --- a/haproxy.c +++ b/haproxy.c @@ -511,6 +511,8 @@ struct server { int inter; /* time in milliseconds */ int result; /* 0 = connect OK, -1 = connect KO */ int curfd; /* file desc used for current test, or -1 if not in test */ + unsigned char uweight, eweight; /* user-specified weight-1, and effective weight-1 */ + unsigned short wsquare; /* eweight*eweight, to speed up map computation */ struct proxy *proxy; /* the proxy this server belongs to */ }; @@ -7075,6 +7077,17 @@ int cfg_parse_listen(char *file, int linenum, char **args) { newsrv->state |= SRV_BACKUP; cur_arg ++; } + else if (!strcmp(args[cur_arg], "weight")) { + int w; + w = atol(args[cur_arg + 1]); + if (w < 1 || w > 256) { + Alert("parsing [%s:%d] : weight of server %s is not within 1 and 256 (%d).\n", + file, linenum, newsrv->id, w); + return -1; + } + newsrv->uweight = w - 1; + cur_arg += 2; + } else if (!strcmp(args[cur_arg], "check")) { global.maxsock++; do_check = 1; @@ -7091,7 +7104,7 @@ int cfg_parse_listen(char *file, int linenum, char **args) { cur_arg += 2; } else { - Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'check', 'inter', 'rise', 'fall', 'port' and 'source'.\n", + Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'check', 'inter', 'rise', 'fall', 'port', 'source', and 'weight'.\n", file, linenum, newsrv->id); return -1; } @@ -7873,9 +7886,26 @@ int readcfgfile(char *file) { cfgerr++; } else { - while (newsrv != NULL) { - /* nothing to check for now */ - newsrv = newsrv->next; + struct server *srv; + int pgcd; + + if (newsrv) { + /* We will factor the weights to reduce the table, + * using Euclide's largest common divisor algorithm + */ + pgcd = newsrv->uweight + 1; + for (srv = newsrv->next; srv && pgcd > 1; srv = srv->next) { + int t, w; + + w = srv->uweight + 1; + while (w) { + t = pgcd % w; + pgcd = w; + w = t; + } + } + for (srv = newsrv; srv; srv = srv->next) + srv->eweight = ((srv->uweight + 1) / pgcd) - 1; } } }