Use ARAL for labels (#20502)
* Use ARAL for labels * Change label version to uint32_t * During shutdown call rrdlabels_aral_destroy() when running with FSANITIZE_ADDRESS * Remove memory accounting (handled by ARAL) * Fix unittest * Fix unit tests part 2
Stelios Fragkakis committed
Jun 18, 2025 at 16:25 UTC
4f3397ef94ffaba0131a56fd1348f5714e15676c
7 files changed
+44
-12
src/daemon/daemon-shutdown.c
+1
@@ -407,6 +407,7 @@ static void netdata_cleanup_and_exit(EXIT_REASON reason, bool abnormal, bool exi
407
fprintf(stderr, "WARNING: STRING has %zu strings still allocated.\n",
408
strings_referenced);
409
410
+ rrdlabels_aral_destroy(true);
411
fprintf(stderr, "RRDLABELS remaining in registry: %d.\n", rrdlabels_registry_count());
412
413
fprintf(stderr, "All done, exiting...\n");
src/daemon/main.c
+7
-1
@@ -380,6 +380,7 @@ int netdata_main(int argc, char **argv) {
380
381
if (sqlite_library_init())
382
return 1;
383
+ rrdlabels_aral_init(false);
384
385
if (pluginsd_parser_unittest()) return 1;
386
if (unit_test_static_threads()) return 1;
@@ -410,6 +411,7 @@ int netdata_main(int argc, char **argv) {
411
if (perflibnamestest_main()) return 1;
412
#endif
413
sqlite_library_shutdown();
414
+ rrdlabels_aral_destroy(false);
415
fprintf(stderr, "\n\nALL TESTS PASSED\n\n");
416
return 0;
417
}
@@ -446,7 +448,10 @@ int netdata_main(int argc, char **argv) {
448
}
449
else if(strcmp(optarg, "rrdlabelstest") == 0) {
450
unittest_running = true;
449
- return rrdlabels_unittest();
451
+ rrdlabels_aral_init(true);
452
+ int rc = rrdlabels_unittest();
453
+ rrdlabels_aral_destroy(true);
454
+ return rc;
455
}
456
else if(strcmp(optarg, "buffertest") == 0) {
457
unittest_running = true;
@@ -868,6 +873,7 @@ int netdata_main(int argc, char **argv) {
873
874
analytics_reset();
875
get_system_timezone();
876
+ rrdlabels_aral_init(true);
877
878
// ----------------------------------------------------------------------------------------------------------------
879
delta_startup_time("pulse");
src/database/rrdlabels.c
+29
-6
@@ -29,7 +29,7 @@ typedef struct labels_registry_idx_entry {
29
30
typedef struct rrdlabels {
31
SPINLOCK spinlock;
32
- size_t version;
32
+ uint32_t version;
33
Pvoid_t JudyL;
34
} RRDLABELS;
35
@@ -76,14 +76,37 @@ __attribute__((constructor)) void initialize_label_stats(void) {
76
dictionary_stats_category_rrdlabels.memory.values = 0;
77
}
78
79
+
80
+static ARAL *labels_aral;
81
+
82
+static struct aral_statistics label_aral_statistics = { 0 };
83
+
84
+void rrdlabels_aral_init(bool with_stats)
85
+{
86
+ labels_aral =
87
+ aral_create("label_stat", sizeof(RRDLABELS), 1, 0, &label_aral_statistics, NULL, NULL, false, false, false);
88
+
89
+ if (with_stats)
90
+ pulse_aral_register_statistics(&label_aral_statistics, "labels");
91
+}
92
+
93
+void rrdlabels_aral_destroy(bool with_stats)
94
+{
95
+ aral_destroy(labels_aral);
96
+ if (with_stats)
97
+ pulse_aral_unregister_statistics(&label_aral_statistics);
98
+}
99
+
100
+
101
// ----------------------------------------------------------------------------
102
// rrdlabels_create()
103
104
RRDLABELS *rrdlabels_create(void)
105
{
84
- RRDLABELS *labels = callocz(1, sizeof(*labels));
106
+ RRDLABELS *labels = aral_mallocz(labels_aral);
107
spinlock_init(&labels->spinlock);
86
- RRDLABELS_MEMORY_DELTA(&dictionary_stats_category_rrdlabels, 0, sizeof(RRDLABELS));
108
+ labels->version = 0;
109
+ labels->JudyL = NULL;
110
return labels;
111
}
112
@@ -200,7 +223,7 @@ void rrdlabels_destroy(RRDLABELS *labels)
223
return;
224
225
rrdlabels_flush(labels);
203
- freez(labels);
226
+ aral_freez(labels_aral, labels);
227
}
228
229
//
@@ -962,12 +985,12 @@ size_t rrdlabels_entries(RRDLABELS *labels __maybe_unused)
985
return count;
986
}
987
965
-size_t rrdlabels_version(RRDLABELS *labels __maybe_unused)
988
+uint32_t rrdlabels_version(RRDLABELS *labels __maybe_unused)
989
{
990
if (unlikely(!labels))
991
return 0;
992
970
- return (size_t) labels->version;
993
+ return labels->version;
994
}
995
996
void rrdset_update_rrdlabels(RRDSET *st, RRDLABELS *new_rrdlabels) {
src/database/rrdlabels.h
+3
-1
@@ -26,6 +26,8 @@ typedef enum __attribute__ ((__packed__)) rrdlabel_source {
26
struct rrdlabels;
27
typedef struct rrdlabels RRDLABELS;
28
29
+void rrdlabels_aral_init(bool with_stats);
30
+void rrdlabels_aral_destroy(bool with_stats);
31
RRDLABELS *rrdlabels_create(void);
32
void rrdlabels_destroy(RRDLABELS *labels_dict);
33
void rrdlabels_flush(RRDLABELS *labels);
@@ -38,7 +40,7 @@ void rrdlabels_get_value_strdup_or_null(RRDLABELS *labels, char **value, const c
40
void rrdlabels_get_value_to_buffer_or_unset(RRDLABELS *labels, BUFFER *wb, const char *key, const char *unset);
41
bool rrdlabels_exist(RRDLABELS *labels, const char *key);
42
size_t rrdlabels_entries(RRDLABELS *labels __maybe_unused);
41
-size_t rrdlabels_version(RRDLABELS *labels __maybe_unused);
43
+uint32_t rrdlabels_version(RRDLABELS *labels __maybe_unused);
44
void rrdlabels_get_value_strcpyz(RRDLABELS *labels, char *dst, size_t dst_len, const char *key);
45
46
void rrdlabels_unmark_all(RRDLABELS *labels);
src/database/sqlite/sqlite_metadata.c
+2
-2
@@ -830,8 +830,8 @@ static int chart_label_store_to_sql_callback(const char *name, const char *value
830
831
static int check_and_update_chart_labels(RRDSET *st, BUFFER *work_buffer)
832
{
833
- size_t old_version = st->rrdlabels_last_saved_version;
834
- size_t new_version = rrdlabels_version(st->rrdlabels);
833
+ uint32_t old_version = st->rrdlabels_last_saved_version;
834
+ uint32_t new_version = rrdlabels_version(st->rrdlabels);
835
836
if (new_version == old_version)
837
return 0;
src/health/rrdcalc.c
+1
-1
@@ -148,7 +148,7 @@ static STRING *rrdcalc_replace_variables_with_rrdset_labels(const char *line, RR
148
149
void rrdcalc_update_info_using_rrdset_labels(RRDCALC *rc) {
150
if(rc->rrdset && rc->rrdset->rrdlabels) {
151
- size_t labels_version = rrdlabels_version(rc->rrdset->rrdlabels);
151
+ uint32_t labels_version = rrdlabels_version(rc->rrdset->rrdlabels);
152
if (rc->labels_version != labels_version) {
153
STRING *old;
154
src/health/rrdcalc.h
+1
-1
@@ -83,7 +83,7 @@ struct rrdcalc {
83
// ------------------------------------------------------------------------
84
// the chart this alarm it is linked to
85
86
- size_t labels_version;
86
+ uint32_t labels_version;
87
struct rrdset *rrdset;
88
89
struct rrdcalc *next;