OPTIM: cfgparse: speed up duplicate server detection
Surprisingly, the duplicate server name detection has never made use of the names tree, so lookups were still in O(N^2). It took 1 second to validate 50k servers spread into 25 backends at 2k per backend. By simply using the tree (and since the current server already is in the tree), we just have to walk using ebpt_prev_dup to visit previous servers with the same name. We can then detect which ones conflict without having an ID set and error. The config check time is now 1/4 of the previous one for 2k servers per backend, and more importantly it will make it simpler to check for any duplicates later.
This commit is contained in:
parent
ccd1ecba1d
commit
029d75df1e
@ -3748,16 +3748,23 @@ out_uri_auth_compat:
|
|||||||
* in order to avoid combinatory explosion if all servers have the same
|
* in order to avoid combinatory explosion if all servers have the same
|
||||||
* name. We do that only for servers which do not have an explicit ID,
|
* name. We do that only for servers which do not have an explicit ID,
|
||||||
* because these IDs were made also for distinguishing them and we don't
|
* because these IDs were made also for distinguishing them and we don't
|
||||||
* want to annoy people who correctly manage them.
|
* want to annoy people who correctly manage them. Since servers names
|
||||||
|
* are stored in a tree before landing here, we simply have to check for
|
||||||
|
* the current server's duplicates to spot conflicts.
|
||||||
*/
|
*/
|
||||||
for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
|
for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
|
||||||
struct server *other_srv;
|
struct server *other_srv;
|
||||||
|
|
||||||
if (newsrv->puid)
|
/* Note: internal servers are not always registered and
|
||||||
|
* they do not conflict.
|
||||||
|
*/
|
||||||
|
if (!newsrv->conf.name.node.leaf_p)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (other_srv = curproxy->srv; other_srv && other_srv != newsrv; other_srv = other_srv->next) {
|
for (other_srv = newsrv;
|
||||||
if (!other_srv->puid && strcmp(other_srv->id, newsrv->id) == 0) {
|
(other_srv = container_of_safe(ebpt_prev_dup(&other_srv->conf.name),
|
||||||
|
struct server, conf.name)); ) {
|
||||||
|
if (!newsrv->puid && !other_srv->puid) {
|
||||||
ha_alert("parsing [%s:%d] : %s '%s', another server named '%s' was already defined at line %d, please use distinct names.\n",
|
ha_alert("parsing [%s:%d] : %s '%s', another server named '%s' was already defined at line %d, please use distinct names.\n",
|
||||||
newsrv->conf.file, newsrv->conf.line,
|
newsrv->conf.file, newsrv->conf.line,
|
||||||
proxy_type_str(curproxy), curproxy->id,
|
proxy_type_str(curproxy), curproxy->id,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user