master
c 158 lines 4.16 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "pattern-array.h"
4
5 struct pattern_array *pattern_array_allocate()
6 {
7 struct pattern_array *pa = callocz(1, sizeof(*pa));
8 return pa;
9 }
10
11 void pattern_array_add_lblkey_with_sp(struct pattern_array *pa, const char *key, SIMPLE_PATTERN *sp)
12 {
13 if (!pa || !key) {
14 simple_pattern_free(sp);
15 return;
16 }
17
18 if (!sp)
19 return;
20
21 STRING *string_key = string_strdupz(key);
22 Pvoid_t *Pvalue = JudyLIns(&pa->JudyL, (Word_t) string_key, PJE0);
23 if (!Pvalue || Pvalue == PJERR ) {
24 string_freez(string_key);
25 simple_pattern_free(sp);
26 return;
27 }
28
29 struct pattern_array *pai;
30 if (*Pvalue)
31 string_freez(string_key);
32 else
33 *Pvalue = callocz(1, sizeof(*pai));
34
35 pai = *Pvalue;
36
37 Pvalue = JudyLIns(&pai->JudyL, (Word_t) ++pai->key_count, PJE0);
38 if (!Pvalue || Pvalue == PJERR) {
39 simple_pattern_free(sp);
40 return;
41 }
42
43 *Pvalue = sp;
44 }
45
46 bool pattern_array_label_match(
47 struct pattern_array *pa,
48 RRDLABELS *labels,
49 char eq,
50 size_t *searches)
51 {
52 if (!pa || !labels)
53 return true;
54
55 Pvoid_t *Pvalue;
56 Word_t Index = 0;
57 bool first_then_next = true;
58 while ((Pvalue = JudyLFirstThenNext(pa->JudyL, &Index, &first_then_next))) {
59 // for each label key in the pattern array
60
61 struct pattern_array *pai = *Pvalue;
62 SIMPLE_PATTERN_RESULT match = SP_NOT_MATCHED;
63 Word_t Index2 = 0;
64 bool first_then_next2 = true;
65 while ((Pvalue = JudyLFirstThenNext(pai->JudyL, &Index2, &first_then_next2))) {
66 // for each pattern in the label key pattern list
67 if (!*Pvalue)
68 continue;
69
70 match = rrdlabels_match_simple_pattern_parsed(labels, (SIMPLE_PATTERN *)(*Pvalue), eq, searches);
71
72 if (match != SP_NOT_MATCHED)
73 break;
74 }
75 if (match != SP_MATCHED_POSITIVE)
76 return false;
77 }
78 return true;
79 }
80
81 struct pattern_array *pattern_array_add_key_simple_pattern(struct pattern_array *pa, const char *key, SIMPLE_PATTERN *pattern)
82 {
83 if (unlikely(!pattern || !key))
84 return pa;
85
86 if (!pa)
87 pa = pattern_array_allocate();
88
89 pattern_array_add_lblkey_with_sp(pa, key, pattern);
90 return pa;
91 }
92
93 struct pattern_array *pattern_array_add_simple_pattern(struct pattern_array *pa, SIMPLE_PATTERN *pattern, char sep)
94 {
95 if (unlikely(!pattern))
96 return pa;
97
98 if (!pa)
99 pa = pattern_array_allocate();
100
101 char *label_key;
102 while (pattern && (label_key = simple_pattern_iterate(&pattern))) {
103 char key[RRDLABELS_MAX_NAME_LENGTH + 1], *key_sep;
104
105 if (unlikely(!label_key || !(key_sep = strchr(label_key, sep))))
106 return pa;
107
108 *key_sep = '\0';
109 strncpyz(key, label_key, RRDLABELS_MAX_NAME_LENGTH);
110 *key_sep = sep;
111
112 pattern_array_add_lblkey_with_sp(pa, key, string_to_simple_pattern(label_key));
113 }
114 return pa;
115 }
116
117 struct pattern_array *pattern_array_add_key_value(struct pattern_array *pa, const char *key, const char *value, char sep)
118 {
119 if (unlikely(!key || !value))
120 return pa;
121
122 if (!pa)
123 pa = pattern_array_allocate();
124
125 char label_key[RRDLABELS_MAX_NAME_LENGTH + RRDLABELS_MAX_VALUE_LENGTH + 2];
126 snprintfz(label_key, sizeof(label_key) - 1, "%s%c%s", key, sep, value);
127 pattern_array_add_lblkey_with_sp(
128 pa, key, simple_pattern_create(label_key, SIMPLE_PATTERN_DEFAULT_WEB_SEPARATORS, SIMPLE_PATTERN_EXACT, true));
129 return pa;
130 }
131
132 void pattern_array_free(struct pattern_array *pa)
133 {
134 if (!pa)
135 return;
136
137 Pvoid_t *Pvalue;
138 Word_t Index = 0;
139 bool first = true;
140 while ((Pvalue = JudyLFirstThenNext(pa->JudyL, &Index, &first))) {
141 struct pattern_array *pai = *Pvalue;
142
143 Word_t Index2 = 0;
144 bool first2 = true;
145 while ((Pvalue = JudyLFirstThenNext(pai->JudyL, &Index2, &first2))) {
146 SIMPLE_PATTERN *sp = (SIMPLE_PATTERN *)*Pvalue;
147 simple_pattern_free(sp);
148 }
149
150 JudyLFreeArray(&(pai->JudyL), PJE0);
151 string_freez((STRING *)Index);
152 freez(pai);
153 }
154
155 JudyLFreeArray(&(pa->JudyL), PJE0);
156 freez(pa);
157 }
158