char *reference; /* The reference name. */
char *display; /* String displayed to identify the pattern origin. */
struct list head; /* The head of the list of struct pat_ref_elt. */
- struct eb_root ebpt_root; /* The tree where pattern reference elements are attached. */
+ struct eb_root ebmb_root; /* The tree where pattern reference elements are attached. */
struct list pat; /* The head of the list of struct pattern_expr. */
unsigned int flags; /* flags PAT_REF_*. */
unsigned int curr_gen; /* current generation number (anything below can be removed) */
/* 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.
+ * accessed from list_head or tree_head. Be careful, it's variable-sized!
*/
struct pat_ref_elt {
struct list list; /* Used to chain elements. */
- struct ebpt_node node; /* Node to attach this element to its <pat_ref> ebtree. */
struct list back_refs; /* list of users tracking this pat ref */
void *list_head; /* all &pattern_list->from_ref derived from this reference, ends with NULL */
void *tree_head; /* all &pattern_tree->from_ref derived from this reference, ends with NULL */
- char *pattern;
char *sample;
unsigned int gen_id; /* generation of pat_ref this was made for */
int line;
+ struct ebmb_node node; /* Node to attach this element to its <pat_ref> ebtree. */
+ const char pattern[0]; // const only to make sure nobody tries to free it.
};
/* This contain each tree indexed entry. This struct permit to associate
HA_RWLOCK_WRUNLOCK(PATEXP_LOCK, &expr->lock);
LIST_DELETE(&elt->list);
- ebpt_delete(&elt->node);
+ ebmb_delete(&elt->node);
free(elt->sample);
- free(elt->pattern);
free(elt);
}
{
int ret = !!refelt->node.node.leaf_p;
- ebpt_delete(&refelt->node);
+ ebmb_delete(&refelt->node);
return ret;
}
*/
int pat_ref_delete(struct pat_ref *ref, const char *key)
{
- struct ebpt_node *node;
+ struct ebmb_node *node;
int found = 0;
/* delete pattern from reference */
- node = ebis_lookup(&ref->ebpt_root, key);
+ node = ebst_lookup(&ref->ebmb_root, key);
while (node) {
struct pat_ref_elt *elt;
- elt = ebpt_entry(node, struct pat_ref_elt, node);
- node = ebpt_next_dup(node);
+ elt = ebmb_entry(node, struct pat_ref_elt, node);
+ node = ebmb_next_dup(node);
pat_ref_delete_by_ptr(ref, elt);
found = 1;
}
*/
struct pat_ref_elt *pat_ref_find_elt(struct pat_ref *ref, const char *key)
{
- struct ebpt_node *node;
+ struct ebmb_node *node;
- node = ebis_lookup(&ref->ebpt_root, key);
+ node = ebst_lookup(&ref->ebmb_root, key);
if (node)
- return ebpt_entry(node, struct pat_ref_elt, node);
+ return ebmb_entry(node, struct pat_ref_elt, node);
return NULL;
}
int found = 0;
char *_merr;
char **merr;
- struct ebpt_node *node;
+ struct ebmb_node *node;
if (err) {
merr = &_merr;
}
else {
/* Look for pattern in the reference. */
- node = ebis_lookup(&ref->ebpt_root, key);
+ node = ebst_lookup(&ref->ebmb_root, key);
}
while (node) {
- elt = ebpt_entry(node, struct pat_ref_elt, node);
- node = ebpt_next_dup(node);
+ elt = ebmb_entry(node, struct pat_ref_elt, node);
+ node = ebmb_next_dup(node);
if (!pat_ref_set_elt(ref, elt, value, merr)) {
if (err && merr) {
if (!found) {
ref->entry_cnt = 0;
LIST_INIT(&ref->head);
- ref->ebpt_root = EB_ROOT;
+ ref->ebmb_root = EB_ROOT;
LIST_INIT(&ref->pat);
HA_RWLOCK_INIT(&ref->lock);
LIST_APPEND(&pattern_reference, &ref->list);
ref->next_gen = 0;
ref->unique_id = unique_id;
LIST_INIT(&ref->head);
- ref->ebpt_root = EB_ROOT;
+ ref->ebmb_root = EB_ROOT;
LIST_INIT(&ref->pat);
HA_RWLOCK_INIT(&ref->lock);
LIST_APPEND(&pattern_reference, &ref->list);
struct pat_ref_elt *pat_ref_append(struct pat_ref *ref, const char *pattern, const char *sample, int line)
{
struct pat_ref_elt *elt;
+ int len = strlen(pattern);
- elt = calloc(1, sizeof(*elt));
+ elt = calloc(1, sizeof(*elt) + len + 1);
if (!elt)
goto fail;
elt->gen_id = ref->curr_gen;
elt->line = line;
- elt->pattern = strdup(pattern);
- if (!elt->pattern)
- goto fail;
+ memcpy((char*)elt->pattern, pattern, len + 1);
if (sample) {
elt->sample = strdup(sample);
LIST_APPEND(&ref->head, &elt->list);
/* Even if calloc()'ed, ensure this node is not linked to a tree. */
elt->node.node.leaf_p = NULL;
- elt->node.key = elt->pattern;
- ebis_insert(&ref->ebpt_root, &elt->node);
+ ebst_insert(&ref->ebmb_root, &elt->node);
return elt;
fail:
- if (elt)
- free(elt->pattern);
free(elt);
return NULL;
}
pat_delete_gen(ref, elt);
LIST_DELETE(&elt->list);
- ebpt_delete(&elt->node);
- free(elt->pattern);
+ ebmb_delete(&elt->node);
free(elt->sample);
free(elt);
}
{
struct pat_ref *ref;
struct pattern_expr *expr;
- struct ebpt_node *node;
+ struct ebmb_node *node;
struct pat_ref_elt *elt;
int reuse = 0;
return 1;
/* Load reference content in the pattern expression. */
- node = ebpt_first(&ref->ebpt_root);
+ node = ebmb_first(&ref->ebmb_root);
while (node) {
- elt = ebpt_entry(node, struct pat_ref_elt, node);
- node = ebpt_next(node);
+ elt = ebmb_entry(node, struct pat_ref_elt, node);
+ node = ebmb_next(node);
if (!pat_ref_push(elt, expr, patflags, err)) {
if (elt->line > 0)
memprintf(err, "%s at line %d of file '%s'",