// SPDX-License-Identifier: GPL-3.0-or-later #include "pattern-array.h" struct pattern_array *pattern_array_allocate() { struct pattern_array *pa = callocz(1, sizeof(*pa)); return pa; } void pattern_array_add_lblkey_with_sp(struct pattern_array *pa, const char *key, SIMPLE_PATTERN *sp) { if (!pa || !key) { simple_pattern_free(sp); return; } if (!sp) return; STRING *string_key = string_strdupz(key); Pvoid_t *Pvalue = JudyLIns(&pa->JudyL, (Word_t) string_key, PJE0); if (!Pvalue || Pvalue == PJERR ) { string_freez(string_key); simple_pattern_free(sp); return; } struct pattern_array *pai; if (*Pvalue) string_freez(string_key); else *Pvalue = callocz(1, sizeof(*pai)); pai = *Pvalue; Pvalue = JudyLIns(&pai->JudyL, (Word_t) ++pai->key_count, PJE0); if (!Pvalue || Pvalue == PJERR) { simple_pattern_free(sp); return; } *Pvalue = sp; } bool pattern_array_label_match( struct pattern_array *pa, RRDLABELS *labels, char eq, size_t *searches) { if (!pa || !labels) return true; Pvoid_t *Pvalue; Word_t Index = 0; bool first_then_next = true; while ((Pvalue = JudyLFirstThenNext(pa->JudyL, &Index, &first_then_next))) { // for each label key in the pattern array struct pattern_array *pai = *Pvalue; SIMPLE_PATTERN_RESULT match = SP_NOT_MATCHED; Word_t Index2 = 0; bool first_then_next2 = true; while ((Pvalue = JudyLFirstThenNext(pai->JudyL, &Index2, &first_then_next2))) { // for each pattern in the label key pattern list if (!*Pvalue) continue; match = rrdlabels_match_simple_pattern_parsed(labels, (SIMPLE_PATTERN *)(*Pvalue), eq, searches); if (match != SP_NOT_MATCHED) break; } if (match != SP_MATCHED_POSITIVE) return false; } return true; } struct pattern_array *pattern_array_add_key_simple_pattern(struct pattern_array *pa, const char *key, SIMPLE_PATTERN *pattern) { if (unlikely(!pattern || !key)) return pa; if (!pa) pa = pattern_array_allocate(); pattern_array_add_lblkey_with_sp(pa, key, pattern); return pa; } struct pattern_array *pattern_array_add_simple_pattern(struct pattern_array *pa, SIMPLE_PATTERN *pattern, char sep) { if (unlikely(!pattern)) return pa; if (!pa) pa = pattern_array_allocate(); char *label_key; while (pattern && (label_key = simple_pattern_iterate(&pattern))) { char key[RRDLABELS_MAX_NAME_LENGTH + 1], *key_sep; if (unlikely(!label_key || !(key_sep = strchr(label_key, sep)))) return pa; *key_sep = '\0'; strncpyz(key, label_key, RRDLABELS_MAX_NAME_LENGTH); *key_sep = sep; pattern_array_add_lblkey_with_sp(pa, key, string_to_simple_pattern(label_key)); } return pa; } struct pattern_array *pattern_array_add_key_value(struct pattern_array *pa, const char *key, const char *value, char sep) { if (unlikely(!key || !value)) return pa; if (!pa) pa = pattern_array_allocate(); char label_key[RRDLABELS_MAX_NAME_LENGTH + RRDLABELS_MAX_VALUE_LENGTH + 2]; snprintfz(label_key, sizeof(label_key) - 1, "%s%c%s", key, sep, value); pattern_array_add_lblkey_with_sp( pa, key, simple_pattern_create(label_key, SIMPLE_PATTERN_DEFAULT_WEB_SEPARATORS, SIMPLE_PATTERN_EXACT, true)); return pa; } void pattern_array_free(struct pattern_array *pa) { if (!pa) return; Pvoid_t *Pvalue; Word_t Index = 0; bool first = true; while ((Pvalue = JudyLFirstThenNext(pa->JudyL, &Index, &first))) { struct pattern_array *pai = *Pvalue; Word_t Index2 = 0; bool first2 = true; while ((Pvalue = JudyLFirstThenNext(pai->JudyL, &Index2, &first2))) { SIMPLE_PATTERN *sp = (SIMPLE_PATTERN *)*Pvalue; simple_pattern_free(sp); } JudyLFreeArray(&(pai->JudyL), PJE0); string_freez((STRING *)Index); freez(pai); } JudyLFreeArray(&(pa->JudyL), PJE0); freez(pa); }