BUG/MINOR: map: list-based matching potential ordering regression
An unexpected side-effect was introduced by5fea597
("MEDIUM: map/acl: Accelerate several functions using pat_ref_elt struct ->head list") The above commit tried to use eb tree API to manipulate elements as much as possible in the hope to accelerate some functions. Prior to5fea597
, pattern_read_from_file() used to iterate over all elements from the map file in the same order they were seen in the file (using list_for_each_entry) to push them in the pattern expression. Now, since eb api is used to iterate over elements, the ordering is lost very early. This is known to cause behavior changes with existing setups (same conf and map file) when compared with previous versions for some list-based matching methods as described in GH #2400. For instance, the map_dom() converter may return a different matching key from the one that was returned by older haproxy versions. For IP or STR matching, matching is based on tree lookups for better efficiency, so in this case the ordering is lost at the name of performance. The order in which they are loaded doesn't matter because tree ordering is based on the content, it is not positional. But with some other types, matching is based on list lookups (e.g.: dom), and the order in which elements are pushed into the list can affect the matching element that will be returned (in case of multiple matches, since only the first matching element in the list will be returned). Despite the documentation not officially stating that the file ordering should be preserved for list-based matching methods, it's probably best to be conservative here and stick to historical behavior. Moreover, there was no performance benefit from using the eb tree api to iterate over elements in pattern_read_from_file() since all elements are visited anyway. This should be backported to 2.9.
This commit is contained in:
parent
37d5a26cc5
commit
b546bb6d67
|
@ -2419,7 +2419,6 @@ int pattern_read_from_file(struct pattern_head *head, unsigned int refflags,
|
|||
{
|
||||
struct pat_ref *ref;
|
||||
struct pattern_expr *expr;
|
||||
struct ebmb_node *node;
|
||||
struct pat_ref_elt *elt;
|
||||
int reuse = 0;
|
||||
|
||||
|
@ -2511,11 +2510,11 @@ int pattern_read_from_file(struct pattern_head *head, unsigned int refflags,
|
|||
if (reuse)
|
||||
return 1;
|
||||
|
||||
/* Load reference content in the pattern expression. */
|
||||
node = ebmb_first(&ref->ebmb_root);
|
||||
while (node) {
|
||||
elt = ebmb_entry(node, struct pat_ref_elt, node);
|
||||
node = ebmb_next(node);
|
||||
/* Load reference content in the pattern expression.
|
||||
* We need to load elements in the same order they were seen in the
|
||||
* file as list-based matching types may rely on it.
|
||||
*/
|
||||
list_for_each_entry(elt, &ref->head, list) {
|
||||
if (!pat_ref_push(elt, expr, patflags, err)) {
|
||||
if (elt->line > 0)
|
||||
memprintf(err, "%s at line %d of file '%s'",
|
||||
|
|
Loading…
Reference in New Issue