|
@@ -1040,14 +1040,13 @@ void rrdlabels_copy(RRDLABELS *dst, RRDLABELS *src)
|
|
|
lfe_start_nolock(src, label, ls)
|
|
|
{
|
|
|
RRDLABEL *old_label_with_key = rrdlabels_find_label_with_key_unsafe(dst, label);
|
|
|
-
|
|
|
Pvoid_t *PValue = JudyLIns(&dst->JudyL, (Word_t)label, PJE0);
|
|
|
if(unlikely(!PValue || PValue == PJERR))
|
|
|
fatal("RRDLABELS: corrupted labels array");
|
|
|
|
|
|
if (!*PValue) {
|
|
|
dup_label(label);
|
|
|
- *((RRDLABEL_SRC *)PValue) = ls;
|
|
|
+ ls = (ls & ~(RRDLABEL_FLAG_OLD)) | RRDLABEL_FLAG_NEW;
|
|
|
dst->version++;
|
|
|
update_statistics = true;
|
|
|
if (old_label_with_key) {
|
|
@@ -1055,6 +1054,10 @@ void rrdlabels_copy(RRDLABELS *dst, RRDLABELS *src)
|
|
|
delete_label((RRDLABEL *)old_label_with_key);
|
|
|
}
|
|
|
}
|
|
|
+ else
|
|
|
+ ls = (ls & ~(RRDLABEL_FLAG_NEW)) | RRDLABEL_FLAG_OLD;
|
|
|
+
|
|
|
+ *((RRDLABEL_SRC *)PValue) = ls;
|
|
|
}
|
|
|
lfe_done_nolock();
|
|
|
if (update_statistics) {
|
|
@@ -1318,7 +1321,30 @@ struct rrdlabels_unittest_add_a_pair {
|
|
|
int errors;
|
|
|
};
|
|
|
|
|
|
-int rrdlabels_unittest_add_a_pair_callback(const char *name, const char *value, RRDLABEL_SRC ls __maybe_unused, void *data) {
|
|
|
+RRDLABEL *rrdlabels_find_label_with_key(RRDLABELS *labels, const char *key, RRDLABEL_SRC *source)
|
|
|
+{
|
|
|
+ if (!labels || !key)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ STRING *this_key = string_strdupz(key);
|
|
|
+
|
|
|
+ RRDLABEL *lb = NULL;
|
|
|
+ RRDLABEL_SRC ls;
|
|
|
+
|
|
|
+ lfe_start_read(labels, lb, ls)
|
|
|
+ {
|
|
|
+ if (lb->index.key == this_key) {
|
|
|
+ if (source)
|
|
|
+ *source = ls;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ lfe_done(labels);
|
|
|
+ string_freez(this_key);
|
|
|
+ return lb;
|
|
|
+}
|
|
|
+
|
|
|
+static int rrdlabels_unittest_add_a_pair_callback(const char *name, const char *value, RRDLABEL_SRC ls __maybe_unused, void *data) {
|
|
|
struct rrdlabels_unittest_add_a_pair *t = (struct rrdlabels_unittest_add_a_pair *)data;
|
|
|
|
|
|
t->name = name;
|
|
@@ -1344,7 +1370,7 @@ int rrdlabels_unittest_add_a_pair_callback(const char *name, const char *value,
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
-int rrdlabels_unittest_add_a_pair(const char *pair, const char *name, const char *value) {
|
|
|
+static int rrdlabels_unittest_add_a_pair(const char *pair, const char *name, const char *value) {
|
|
|
RRDLABELS *labels = rrdlabels_create();
|
|
|
int errors;
|
|
|
|
|
@@ -1374,7 +1400,7 @@ int rrdlabels_unittest_add_a_pair(const char *pair, const char *name, const char
|
|
|
return errors;
|
|
|
}
|
|
|
|
|
|
-int rrdlabels_unittest_add_pairs() {
|
|
|
+static int rrdlabels_unittest_add_pairs() {
|
|
|
fprintf(stderr, "\n%s() tests\n", __FUNCTION__);
|
|
|
|
|
|
int errors = 0;
|
|
@@ -1422,66 +1448,33 @@ int rrdlabels_unittest_add_pairs() {
|
|
|
return errors;
|
|
|
}
|
|
|
|
|
|
-int rrdlabels_unittest_double_check() {
|
|
|
+static int rrdlabels_unittest_expect_value(RRDLABELS *labels, const char *key, const char *value, RRDLABEL_SRC required_source)
|
|
|
+{
|
|
|
+ RRDLABEL_SRC source;
|
|
|
+ RRDLABEL *label = rrdlabels_find_label_with_key(labels, key, &source);
|
|
|
+ return (!label || strcmp(string2str(label->index.value), value) != 0 || !(source & required_source));
|
|
|
+}
|
|
|
+
|
|
|
+static int rrdlabels_unittest_double_check()
|
|
|
+{
|
|
|
fprintf(stderr, "\n%s() tests\n", __FUNCTION__);
|
|
|
|
|
|
- int errors = 1;
|
|
|
int ret = 0;
|
|
|
RRDLABELS *labels = rrdlabels_create();
|
|
|
|
|
|
- const char *pair = "key1=value1";
|
|
|
-
|
|
|
- struct rrdlabels_unittest_add_a_pair tmp = {
|
|
|
- .pair = pair,
|
|
|
- .expected_name = "key1",
|
|
|
- .expected_value = NULL,
|
|
|
- .errors = 0
|
|
|
- };
|
|
|
+ rrdlabels_add(labels, "key1", "value1", RRDLABEL_SRC_CONFIG);
|
|
|
+ ret += rrdlabels_unittest_expect_value(labels, "key1", "value1", RRDLABEL_FLAG_NEW);
|
|
|
|
|
|
- fprintf(stderr, "rrdlabels_add_pair(labels, %s) ...\n ", pair);
|
|
|
-
|
|
|
- rrdlabels_add_pair(labels, pair, RRDLABEL_SRC_CONFIG);
|
|
|
- size_t count = rrdlabels_entries(labels);
|
|
|
- fprintf(stderr, "Added one key with \"value1\", entries found %zu\n", count);
|
|
|
- tmp.expected_value = "value1";
|
|
|
- ret = rrdlabels_walkthrough_read(labels, rrdlabels_unittest_add_a_pair_callback, &tmp);
|
|
|
-
|
|
|
- fprintf(stderr, "Adding key with same value \"value1\" (collision check)\n");
|
|
|
- rrdlabels_add_pair(labels, pair, RRDLABEL_SRC_CONFIG);
|
|
|
- count = rrdlabels_entries(labels);
|
|
|
- fprintf(stderr, "Added same key again \"value1\", entries found %zu\n", count);
|
|
|
+ rrdlabels_add(labels, "key1", "value2", RRDLABEL_SRC_CONFIG);
|
|
|
+ ret += !rrdlabels_unittest_expect_value(labels, "key1", "value2", RRDLABEL_FLAG_OLD);
|
|
|
|
|
|
- ret = rrdlabels_walkthrough_read(labels, rrdlabels_unittest_add_a_pair_callback, &tmp);
|
|
|
-
|
|
|
- // Add same key with different value
|
|
|
- pair = "key1=value2";
|
|
|
- rrdlabels_add_pair(labels, pair, RRDLABEL_SRC_CONFIG);
|
|
|
- count = rrdlabels_entries(labels);
|
|
|
- fprintf(stderr, "Added same key again with \"value2\", entries found %zu\n", count);
|
|
|
-
|
|
|
- tmp.expected_value = "value2";
|
|
|
- ret = rrdlabels_walkthrough_read(labels, rrdlabels_unittest_add_a_pair_callback, &tmp);
|
|
|
-
|
|
|
- fprintf(stderr, "Adding key with same value \"value2\" (collision check)\n");
|
|
|
- rrdlabels_add_pair(labels, pair, RRDLABEL_SRC_CONFIG);
|
|
|
- count = rrdlabels_entries(labels);
|
|
|
- fprintf(stderr, "Added same key again with \"value2\", entries found %zu\n", count);
|
|
|
-
|
|
|
- ret = rrdlabels_walkthrough_read(labels, rrdlabels_unittest_add_a_pair_callback, &tmp);
|
|
|
- errors = tmp.errors;
|
|
|
- if(ret != 1) {
|
|
|
- fprintf(stderr, "failed to get \"%s\" label", "key1");
|
|
|
- errors++;
|
|
|
- }
|
|
|
-
|
|
|
- if(!errors)
|
|
|
- fprintf(stderr, " OK, name='%s' and value='%s'\n", tmp.name, tmp.value?tmp.value:"(null)");
|
|
|
- else
|
|
|
- fprintf(stderr, " FAILED\n");
|
|
|
+ ret += (rrdlabels_entries(labels) != 1);
|
|
|
|
|
|
rrdlabels_destroy(labels);
|
|
|
|
|
|
- return errors;
|
|
|
+ if (ret)
|
|
|
+ fprintf(stderr, "\n%s() tests failed\n", __FUNCTION__);
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static int rrdlabels_walkthrough_index_read(RRDLABELS *labels, int (*callback)(const char *name, const char *value, RRDLABEL_SRC ls, size_t index, void *data), void *data)
|
|
@@ -1514,7 +1507,8 @@ static int unittest_dump_labels(const char *name, const char *value, RRDLABEL_SR
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
-int rrdlabels_unittest_migrate_check() {
|
|
|
+static int rrdlabels_unittest_migrate_check()
|
|
|
+{
|
|
|
fprintf(stderr, "\n%s() tests\n", __FUNCTION__);
|
|
|
|
|
|
RRDLABELS *labels1 = NULL;
|
|
@@ -1553,38 +1547,43 @@ int rrdlabels_unittest_migrate_check() {
|
|
|
rrdlabels_add(labels1, "key4", "value4", RRDLABEL_SRC_CONFIG); // 4 keys
|
|
|
rrdlabels_walkthrough_index_read(labels1, unittest_dump_labels, "\nlabels1");
|
|
|
|
|
|
- rrdlabels_add(labels2, "key1", "value1_new", RRDLABEL_SRC_CONFIG);
|
|
|
- rrdlabels_add(labels2, "key2", "value2", RRDLABEL_SRC_CONFIG);
|
|
|
rrdlabels_add(labels2, "key0", "value0", RRDLABEL_SRC_CONFIG);
|
|
|
+ rrdlabels_add(labels2, "key1", "value1", RRDLABEL_SRC_CONFIG);
|
|
|
+ rrdlabels_add(labels2, "key2", "value2", RRDLABEL_SRC_CONFIG);
|
|
|
+
|
|
|
+ int rc = 0;
|
|
|
+ rc = rrdlabels_unittest_expect_value(labels1, "key1", "value1", RRDLABEL_FLAG_NEW);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+
|
|
|
rrdlabels_walkthrough_index_read(labels2, unittest_dump_labels, "\nlabels2");
|
|
|
|
|
|
rrdlabels_copy(labels1, labels2); // labels1 should have 5 keys
|
|
|
- rrdlabels_walkthrough_index_read(labels1, unittest_dump_labels, "\nlabels1 after copy from labels2");
|
|
|
+ rc = rrdlabels_unittest_expect_value(labels1, "key1", "value1", RRDLABEL_FLAG_OLD);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ rc = rrdlabels_unittest_expect_value(labels1, "key0", "value0", RRDLABEL_FLAG_NEW);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
|
|
|
+ rrdlabels_walkthrough_index_read(labels1, unittest_dump_labels, "\nlabels1 after copy from labels2");
|
|
|
entries = rrdlabels_entries(labels1);
|
|
|
+
|
|
|
fprintf(stderr, "labels1 (copied) entries found %zu (should be 5)\n", rrdlabels_entries(labels1));
|
|
|
if (entries != 5)
|
|
|
return 1;
|
|
|
|
|
|
- rrdlabels_add(labels1, "key100", "value100", RRDLABEL_SRC_CONFIG);
|
|
|
- rrdlabels_walkthrough_index_read(labels1, unittest_dump_labels, "\nlabels1 now after key100");
|
|
|
-
|
|
|
- rrdlabels_copy(labels2, labels1); // labels2 should have 6 keys
|
|
|
- entries = rrdlabels_entries(labels1);
|
|
|
-
|
|
|
- fprintf(stderr, "labels2 (copied) entries found %zu (should be 6)\n", rrdlabels_entries(labels1));
|
|
|
-
|
|
|
- rrdlabels_walkthrough_index_read(labels1, unittest_dump_labels, "\nlabels2 after labels1 copy");
|
|
|
-
|
|
|
- rrdlabels_walkthrough_index_read(labels1, unittest_dump_labels, "\nfinal labels1");
|
|
|
+ rrdlabels_add(labels1, "key0", "value0", RRDLABEL_SRC_CONFIG);
|
|
|
+ rc = rrdlabels_unittest_expect_value(labels1, "key0", "value0", RRDLABEL_FLAG_OLD);
|
|
|
|
|
|
rrdlabels_destroy(labels1);
|
|
|
rrdlabels_destroy(labels2);
|
|
|
|
|
|
- return entries != 6;
|
|
|
+ return rc;
|
|
|
}
|
|
|
|
|
|
-int rrdlabels_unittest_check_simple_pattern(RRDLABELS *labels, const char *pattern, bool expected) {
|
|
|
+static int rrdlabels_unittest_check_simple_pattern(RRDLABELS *labels, const char *pattern, bool expected) {
|
|
|
fprintf(stderr, "rrdlabels_match_simple_pattern(labels, \"%s\") ... ", pattern);
|
|
|
|
|
|
bool ret = rrdlabels_match_simple_pattern(labels, pattern);
|
|
@@ -1593,7 +1592,7 @@ int rrdlabels_unittest_check_simple_pattern(RRDLABELS *labels, const char *patte
|
|
|
return (ret == expected)?0:1;
|
|
|
}
|
|
|
|
|
|
-int rrdlabels_unittest_simple_pattern() {
|
|
|
+static int rrdlabels_unittest_simple_pattern() {
|
|
|
fprintf(stderr, "\n%s() tests\n", __FUNCTION__);
|
|
|
|
|
|
int errors = 0;
|