From: Maxime Henrion Date: Thu, 18 Dec 2025 04:31:29 +0000 (-0500) Subject: MINOR: patterns: preliminary changes for reorganization X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5547bedebb3136287b71309dae8761b4d0be3a79;p=thirdparty%2Fhaproxy.git MINOR: patterns: preliminary changes for reorganization Safe and non-functional changes that only add currently unused structures, field, functions and macros, in preparation of larger changes that alter the way pattern reference elements are stored. This includes code to create and lookup generation objects, and macros to iterate over the generations of a pattern reference. --- diff --git a/include/haproxy/hlua-t.h b/include/haproxy/hlua-t.h index 9716868f8..ac0b7d541 100644 --- a/include/haproxy/hlua-t.h +++ b/include/haproxy/hlua-t.h @@ -255,6 +255,7 @@ struct hlua_patref_iterator_context { struct hlua_patref *ref; struct bref bref; /* back-reference from the pat_ref_elt being accessed * during listing */ + struct pat_ref_gen *gen; /* the generation we are iterating over */ }; #else /* USE_LUA */ diff --git a/include/haproxy/pattern-t.h b/include/haproxy/pattern-t.h index a78c98443..42da6ed33 100644 --- a/include/haproxy/pattern-t.h +++ b/include/haproxy/pattern-t.h @@ -107,6 +107,7 @@ struct pat_ref { struct list list; /* Used to chain refs. */ char *reference; /* The reference name. */ char *display; /* String displayed to identify the pattern origin. */ + struct ceb_root *gen_root; /* The tree mapping generation IDs to pattern reference elements */ struct list head; /* The head of the list of struct pat_ref_elt. */ struct ceb_root *ceb_root; /* The tree where pattern reference elements are attached. */ struct list pat; /* The head of the list of struct pattern_expr. */ @@ -121,6 +122,16 @@ struct pat_ref { event_hdl_sub_list e_subs; /* event_hdl: pat_ref's subscribers list (atomically updated) */ }; +/* This struct represents all the elements in a pattern reference generation. The tree + * is used most of the time, but we also maintain a list for when order matters. + */ +struct pat_ref_gen { + struct list head; /* The head of the list of struct pat_ref_elt. */ + struct ceb_root *elt_root; /* The tree where pattern reference elements are attached. */ + struct ceb_node gen_node; /* Linkage for the gen_root cebtree in struct pat_ref */ + unsigned int gen_id; +}; + /* This is a part of struct pat_ref. Each entry contains one pattern and one * associated value as original string. All derivative forms (via exprs) are * accessed from list_head or tree_head. Be careful, it's variable-sized! diff --git a/include/haproxy/pattern.h b/include/haproxy/pattern.h index 1f3fdf164..73245096b 100644 --- a/include/haproxy/pattern.h +++ b/include/haproxy/pattern.h @@ -191,6 +191,8 @@ struct pat_ref_elt *pat_ref_find_elt(struct pat_ref *ref, const char *key); struct pat_ref_elt *pat_ref_gen_find_elt(struct pat_ref *ref, unsigned int gen_id, const char *key); struct pat_ref_elt *pat_ref_append(struct pat_ref *ref, const char *pattern, const char *sample, int line); struct pat_ref_elt *pat_ref_load(struct pat_ref *ref, unsigned int gen, const char *pattern, const char *sample, int line, char **err); +struct pat_ref_gen *pat_ref_gen_new(struct pat_ref *ref, unsigned int gen_id); +struct pat_ref_gen *pat_ref_gen_get(struct pat_ref *ref, unsigned int gen_id); int pat_ref_push(struct pat_ref_elt *elt, struct pattern_expr *expr, int patflags, char **err); int pat_ref_add(struct pat_ref *ref, const char *pattern, const char *sample, char **err); int pat_ref_set(struct pat_ref *ref, const char *pattern, const char *sample, char **err); diff --git a/src/map.c b/src/map.c index 7a6bd36f6..b02224d8d 100644 --- a/src/map.c +++ b/src/map.c @@ -362,6 +362,7 @@ struct show_map_ctx { unsigned int display_flags; unsigned int curr_gen; /* current/latest generation, for show/clear */ unsigned int prev_gen; /* prev generation, for clear */ + struct pat_ref_gen *gen; /* link to the generation being displayed, for show */ enum { STATE_INIT = 0, /* initialize list and backrefs */ STATE_LIST, /* list entries */ diff --git a/src/pattern.c b/src/pattern.c index 0c662a989..8270d3640 100644 --- a/src/pattern.c +++ b/src/pattern.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -31,6 +32,18 @@ #include +/* Convenience macros for iterating over generations. */ +#define pat_ref_gen_foreach(gen, ref) \ + for (gen = cebu32_item_first(&ref->gen_root, gen_node, gen_id, struct pat_ref_gen); \ + gen; \ + gen = cebu32_item_next(&ref->gen_root, gen_node, gen_id, gen)) + +/* Safe variant that allows deleting an entry in the body of the loop. */ +#define pat_ref_gen_foreach_safe(gen, next, ref) \ + for (gen = cebu32_item_first(&ref->gen_root, gen_node, gen_id, struct pat_ref_gen); \ + gen && (next = cebu32_item_next(&ref->gen_root, gen_node, gen_id, gen), 1); \ + gen = next) + const char *const pat_match_names[PAT_MATCH_NUM] = { [PAT_MATCH_FOUND] = "found", [PAT_MATCH_BOOL] = "bool", @@ -1621,6 +1634,37 @@ int pat_ref_delete_by_id(struct pat_ref *ref, struct pat_ref_elt *refelt) return 0; } +/* Create a new generation object. + * + * Returns NULL in case of memory allocation failure. + */ +struct pat_ref_gen *pat_ref_gen_new(struct pat_ref *ref, unsigned int gen_id) +{ + struct pat_ref_gen *gen, *old; + + gen = calloc(1, sizeof(struct pat_ref_gen)); + if (!gen) + return NULL; + + LIST_INIT(&gen->head); + ceb_init_root(&gen->elt_root); + gen->gen_id = gen_id; + + old = cebu32_item_insert(&ref->gen_root, gen_node, gen_id, gen); + BUG_ON(old != gen, "Generation ID already exists"); + + return gen; +} + +/* Find the generation in the pattern reference . + * + * Returns NULL if the generation cannot be found. + */ +struct pat_ref_gen *pat_ref_gen_get(struct pat_ref *ref, unsigned int gen_id) +{ + return cebu32_item_lookup(&ref->gen_root, gen_node, gen_id, gen_id, struct pat_ref_gen); +} + /* This function removes all elements belonging to and matching * from the reference . * This function returns 1 if the deletion is done and returns 0 if