]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: patterns: preliminary changes for reorganization
authorMaxime Henrion <mhenrion@haproxy.com>
Thu, 18 Dec 2025 04:31:29 +0000 (23:31 -0500)
committerWilly Tarreau <w@1wt.eu>
Tue, 23 Dec 2025 20:17:39 +0000 (21:17 +0100)
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.

include/haproxy/hlua-t.h
include/haproxy/pattern-t.h
include/haproxy/pattern.h
src/map.c
src/pattern.c

index 9716868f8af622e761d79f7716d5d7ac2d2cd42f..ac0b7d541a05586ede52b421c640f76a31f0b421 100644 (file)
@@ -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 */
index a78c98443f0902da7cc3e313af6f6bc35fa6f7b1..42da6ed3307adb1a14e422b085317d115e4ddcde 100644 (file)
@@ -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!
index 1f3fdf164fb581b8d7d306c858e33f91cfef867a..73245096b8d7852c0a5233d475ae33155424c1ba 100644 (file)
@@ -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);
index 7a6bd36f623e646e63ccdbc712fbb57af54a80cf..b02224d8d479dbaf80d189801d06aaabdd569870 100644 (file)
--- 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 */
index 0c662a9893271d49ebd4710644ee0814cd63d898..8270d36401aa50eeb1fb6760c8e97217c3406eb4 100644 (file)
@@ -15,6 +15,7 @@
 #include <errno.h>
 
 #include <import/cebs_tree.h>
+#include <import/ceb32_tree.h>
 #include <import/ebistree.h>
 #include <import/ebpttree.h>
 #include <import/ebsttree.h>
 #include <haproxy/xxhash.h>
 
 
+/* 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 <gen_id> in the pattern reference <ref>.
+ *
+ * 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 <gen_id> and matching <key>
  * from the reference <ref>.
  * This function returns 1 if the deletion is done and returns 0 if