1347
rrdset_metadata_updated(st);
1348
}
1349
1350
+struct pattern_array *pattern_array_allocate()
1351
+{
1352
+ struct pattern_array *pa = callocz(1, sizeof(*pa));
1353
+ return pa;
1354
+}
1355
+
1356
+static void pattern_array_add_lblkey_with_sp(struct pattern_array *pa, const char *key, SIMPLE_PATTERN *sp)
1357
+{
1358
+ if (!pa || !key || !sp)
1359
+ return;
1360
+
1361
+ STRING *string_key = string_strdupz(key);
1362
+ Pvoid_t *Pvalue = JudyLIns(&pa->JudyL, (Word_t) string_key, PJE0);
1363
+ if (!Pvalue) {
1364
+ string_freez(string_key);
1365
+ simple_pattern_free(sp);
1366
+ return;
1367
+ }
1368
+
1369
+ struct pattern_array_item *pai;
1370
+ if (*Pvalue) {
1371
+ pai = *Pvalue;
1372
+ } else {
1373
+ *Pvalue = pai = callocz(1, sizeof(*pai));
1374
+ pa->key_count++;
1375
+ }
1376
+
1377
+ pai->size++;
1378
+ Pvalue = JudyLIns(&pai->JudyL, (Word_t) pai->size, PJE0);
1379
+ if (!Pvalue) {
1380
+ simple_pattern_free(sp);
1381
+ return;
1382
+ }
1383
+
1384
+ *Pvalue = sp;
1385
+}
1386
+
1387
+bool pattern_array_label_match(
1388
+ struct pattern_array *pa,
1389
+ RRDLABELS *labels,
1390
+ char eq,
1391
+ size_t *searches,
1392
+ bool (*callback_function)(RRDLABELS *, SIMPLE_PATTERN *, char, size_t *))
1393
+{
1394
+ if (!pa || !labels)
1395
+ return true;
1396
+
1397
+ Pvoid_t *Pvalue;
1398
+ Word_t Index = 0;
1399
+ bool first_then_next = true;
1400
+ while ((Pvalue = JudyLFirstThenNext(pa->JudyL, &Index, &first_then_next))) {
1401
+ struct pattern_array_item *pai = *Pvalue;
1402
+ bool match = false;
1403
+ for (Word_t i = 1; !match && i <= pai->size; i++) {
1404
+ if (!(Pvalue = JudyLGet(pai->JudyL, i, PJE0)) || !*Pvalue)
1405
+ continue;
1406
+ match = callback_function(labels, (SIMPLE_PATTERN *)(*Pvalue), eq, searches);
1407
+ }
1408
+ if (!match)
1409
+ return false;
1410
+ }
1411
+ return true;
1412
+}
1413
+
1414
+struct pattern_array *pattern_array_add_key_simple_pattern(struct pattern_array *pa, const char *key, SIMPLE_PATTERN *pattern)
1415
+{
1416
+ if (unlikely(!pattern || !key))
1417
+ return pa;
1418
+
1419
+ if (!pa)
1420
+ pa = pattern_array_allocate();
1421
+
1422
+ pattern_array_add_lblkey_with_sp(pa, key, pattern);
1423
+ return pa;
1424
+}
1425
+
1426
+struct pattern_array *pattern_array_add_simple_pattern(struct pattern_array *pa, SIMPLE_PATTERN *pattern, char sep)
1427
+{
1428
+ if (unlikely(!pattern))
1429
+ return pa;
1430
+
1431
+ if (!pa)
1432
+ pa = pattern_array_allocate();
1433
+
1434
+ char *label_key;
1435
+ while (pattern && (label_key = simple_pattern_iterate(&pattern))) {
1436
+ char key[RRDLABELS_MAX_NAME_LENGTH + 1], *key_sep;
1437
+
1438
+ if (unlikely(!label_key || !(key_sep = strchr(label_key, sep))))
1439
+ return pa;
1440
+
1441
+ *key_sep = '\0';
1442
+ strncpyz(key, label_key, RRDLABELS_MAX_NAME_LENGTH);
1443
+ *key_sep = sep;
1444
+
1445
+ pattern_array_add_lblkey_with_sp(pa, key, string_to_simple_pattern(label_key));
1446
+ }
1447
+ return pa;
1448
+}
1449
+
1450
+struct pattern_array *pattern_array_add_key_value(struct pattern_array *pa, const char *key, const char *value, char sep)
1451
+{
1452
+ if (unlikely(!key || !value))
1453
+ return pa;
1454
+
1455
+ if (!pa)
1456
+ pa = pattern_array_allocate();
1457
+
1458
+ char label_key[RRDLABELS_MAX_NAME_LENGTH + RRDLABELS_MAX_VALUE_LENGTH + 2];
1459
+ snprintfz(label_key, sizeof(label_key) - 1, "%s%c%s", key, sep, value);
1460
+ pattern_array_add_lblkey_with_sp(
1461
+ pa, key, simple_pattern_create(label_key, SIMPLE_PATTERN_DEFAULT_WEB_SEPARATORS, SIMPLE_PATTERN_EXACT, true));
1462
+ return pa;
1463
+}
1464
+
1465
+void pattern_array_free(struct pattern_array *pa)
1466
+{
1467
+ if (!pa)
1468
+ return;
1469
+
1470
+ Pvoid_t *Pvalue;
1471
+ Word_t Index = 0;
1472
+ while ((Pvalue = JudyLFirst(pa->JudyL, &Index, PJE0))) {
1473
+ struct pattern_array_item *pai = *Pvalue;
1474
+
1475
+ for (Word_t i = 1; i <= pai->size; i++) {
1476
+ if (!(Pvalue = JudyLGet(pai->JudyL, i, PJE0)))
1477
+ continue;
1478
+ simple_pattern_free((SIMPLE_PATTERN *) (*Pvalue));
1479
+ }
1480
+ JudyLFreeArray(&(pai->JudyL), PJE0);
1481
+
1482
+ string_freez((STRING *)Index);
1483
+ (void) JudyLDel(&(pa->JudyL), Index, PJE0);
1484
+ Index = 0;
1485
+ }
1486
+}
1487
1488
// ----------------------------------------------------------------------------
1489
// rrdlabels unit test
1686
return 1;
1687
}
1688
1689
+static int rrdlabels_unittest_pattern_check()
1690
+{
1691
+ fprintf(stderr, "\n%s() tests\n", __FUNCTION__);
1692
+ int rc = 0;
1693
+
1694
+ RRDLABELS *labels = NULL;
1695
+
1696
+ labels = rrdlabels_create();
1697
+
1698
+ rrdlabels_add(labels, "_module", "disk_detection", RRDLABEL_SRC_CONFIG);
1699
+ rrdlabels_add(labels, "_plugin", "super_plugin", RRDLABEL_SRC_CONFIG);
1700
+ rrdlabels_add(labels, "key1", "value1", RRDLABEL_SRC_CONFIG);
1701
+ rrdlabels_add(labels, "key2", "caterpillar", RRDLABEL_SRC_CONFIG);
1702
+ rrdlabels_add(labels, "key3", "elephant", RRDLABEL_SRC_CONFIG);
1703
+ rrdlabels_add(labels, "key4", "value4", RRDLABEL_SRC_CONFIG);
1704
+
1705
+ bool match;
1706
+ struct pattern_array *pa = pattern_array_add_key_value(NULL, "_module", "wrong_module", '=');
1707
+ match = pattern_array_label_match(pa, labels, '=', NULL, rrdlabels_match_simple_pattern_parsed);
1708
+ // This should not match: _module in ("wrong_module")
1709
+ if (match)
1710
+ rc++;
1711
+
1712
+ pattern_array_add_key_value(pa, "_module", "disk_detection", '=');
1713
+ match = pattern_array_label_match(pa, labels, '=', NULL, rrdlabels_match_simple_pattern_parsed);
1714
+ // This should match: _module in ("wrong_module","disk_detection")
1715
+ if (!match)
1716
+ rc++;
1717
+
1718
+ pattern_array_add_key_value(pa, "key1", "wrong_key1_value", '=');
1719
+ match = pattern_array_label_match(pa, labels, '=', NULL, rrdlabels_match_simple_pattern_parsed);
1720
+ // This should not match: _module in ("wrong_module","disk_detection") AND key1 in ("wrong_key1_value")
1721
+ if (match)
1722
+ rc++;
1723
+
1724
+ pattern_array_add_key_value(pa, "key1", "value1", '=');
1725
+ match = pattern_array_label_match(pa, labels, '=', NULL, rrdlabels_match_simple_pattern_parsed);
1726
+ // This should match: _module in ("wrong_module","disk_detection") AND key1 in ("wrong_key1_value", "value1")
1727
+ if (!match)
1728
+ rc++;
1729
+
1730
+ SIMPLE_PATTERN *sp = simple_pattern_create("key2=cat*,!d*", SIMPLE_PATTERN_DEFAULT_WEB_SEPARATORS, SIMPLE_PATTERN_EXACT, true);
1731
+ pattern_array_add_lblkey_with_sp(pa, "key2", sp);
1732
+
1733
+ sp = simple_pattern_create("key3=*phant", SIMPLE_PATTERN_DEFAULT_WEB_SEPARATORS, SIMPLE_PATTERN_EXACT, true);
1734
+ pattern_array_add_lblkey_with_sp(pa, "key3", sp);
1735
+
1736
+ match = pattern_array_label_match(pa, labels, '=', NULL, rrdlabels_match_simple_pattern_parsed);
1737
+ // This should match: _module in ("wrong_module","disk_detection") AND key1 in ("wrong_key1_value", "value1") AND key2 in ("cat* !d*") AND key3 in ("*phant")
1738
+ if (!match)
1739
+ rc++;
1740
+
1741
+ rrdlabels_add(labels, "key3", "now_fail", RRDLABEL_SRC_CONFIG);
1742
+ match = pattern_array_label_match(pa, labels, '=', NULL, rrdlabels_match_simple_pattern_parsed);
1743
+ // This should not match: _module in ("wrong_module","disk_detection") AND key1 in ("wrong_key1_value", "value1") AND key2 in ("cat* !d*") AND key3 in ("*phant")
1744
+ if (match)
1745
+ rc++;
1746
+
1747
+ pattern_array_free(pa);
1748
+ rrdlabels_destroy(labels);
1749
+
1750
+ return rc;
1751
+}
1752
+
1753
static int rrdlabels_unittest_migrate_check()
1754
{
1755
fprintf(stderr, "\n%s() tests\n", __FUNCTION__);
1925
errors += rrdlabels_unittest_simple_pattern();
1926
errors += rrdlabels_unittest_double_check();
1927
errors += rrdlabels_unittest_migrate_check();
1928
+ errors += rrdlabels_unittest_pattern_check();
1929
1930
fprintf(stderr, "%d errors found\n", errors);
1931
return errors;
1932
}
1933
+