@cryptotaxi247 / netdata-1 / commits / a4341ee3d

fix contexts labels to avoid clearing the rrdlabels pointer (#19853)

Costa Tsaousis committed Mar 13, 2025 at 17:16 UTC a4341ee3d7c0a3e9bab3c098c26531a3efe8b9a9
7 files changed +51 -44
src/database/contexts/api_v1_contexts.c
+12 -7
@@ -131,13 +131,18 @@ static inline int rrdinstance_to_json_callback(const DICTIONARY_ITEM *item, void
131 if(before && (!ri->first_time_s || before < ri->first_time_s))
132 return 0;
133
134 - if(t_parent->chart_label_key && rrdlabels_match_simple_pattern_parsed(ri->rrdlabels, t_parent->chart_label_key,
135 - '\0', NULL) != SP_MATCHED_POSITIVE)
134 + RRDLABELS *labels = rrdinstance_labels(ri);
135 +
136 + if(t_parent->chart_label_key && rrdlabels_match_simple_pattern_parsed(
137 + labels,
138 + t_parent->chart_label_key,
139 + '\0', NULL) != SP_MATCHED_POSITIVE)
140 return 0;
141
138 - if(t_parent->chart_labels_filter && rrdlabels_match_simple_pattern_parsed(ri->rrdlabels,
139 - t_parent->chart_labels_filter, ':',
140 - NULL) != SP_MATCHED_POSITIVE)
142 + if(t_parent->chart_labels_filter && rrdlabels_match_simple_pattern_parsed(
143 + labels,
144 + t_parent->chart_labels_filter, ':',
145 + NULL) != SP_MATCHED_POSITIVE)
146 return 0;
147
148 time_t first_time_s = ri->first_time_s;
@@ -213,9 +218,9 @@ static inline int rrdinstance_to_json_callback(const DICTIONARY_ITEM *item, void
218 buffer_json_array_close(wb);
219 }
220
216 - if(options & RRDCONTEXT_OPTION_SHOW_LABELS && ri->rrdlabels && rrdlabels_entries(ri->rrdlabels)) {
221 + if(options & RRDCONTEXT_OPTION_SHOW_LABELS && rrdlabels_entries(labels)) {
222 buffer_json_member_add_object(wb, "labels");
218 - rrdlabels_to_buffer_json_members(ri->rrdlabels, wb);
223 + rrdlabels_to_buffer_json_members(labels, wb);
224 buffer_json_object_close(wb);
225 }
226
src/database/contexts/api_v2_contexts.c
+3 -2
@@ -118,8 +118,9 @@ static FTS_MATCH rrdcontext_to_json_v2_full_text_search(struct rrdcontext_to_jso
118 dfe_done(rm);
119
120 size_t label_searches = 0;
121 - if(unlikely(ri->rrdlabels && rrdlabels_entries(ri->rrdlabels) &&
122 - rrdlabels_match_simple_pattern_parsed(ri->rrdlabels, q, ':', &label_searches) == SP_MATCHED_POSITIVE)) {
121 + RRDLABELS *labels = rrdinstance_labels(ri);
122 + if(unlikely(rrdlabels_entries(labels) &&
123 + rrdlabels_match_simple_pattern_parsed(labels, q, ':', &label_searches) == SP_MATCHED_POSITIVE)) {
124 ctl->q.fts.searches += label_searches;
125 ctl->q.fts.char_searches += label_searches;
126 matched = FTS_MATCHED_LABEL;
src/database/contexts/instance.c
+21 -31
@@ -35,16 +35,24 @@ inline STRING *rrdinstance_acquired_units_dup(RRDINSTANCE_ACQUIRED *ria) {
35 return string_dup(ri->units);
36 }
37
38 -inline RRDLABELS *rrdinstance_acquired_labels(RRDINSTANCE_ACQUIRED *ria) {
39 - RRDINSTANCE *ri = rrdinstance_acquired_value(ria);
40 - if (rrd_flag_check(ri, RRD_FLAG_OWN_LABELS | RRD_FLAG_DEMAND_LABELS)) {
38 +inline RRDLABELS *rrdinstance_labels(RRDINSTANCE *ri) {
39 + if(ri->rrdset)
40 + return ri->rrdset->rrdlabels;
41 +
42 + if (rrd_flag_check_all(ri, RRD_FLAG_OWN_LABELS | RRD_FLAG_DEMAND_LABELS)) {
43 rrd_flag_clear(ri, RRD_FLAG_DEMAND_LABELS);
44 load_instance_labels_on_demand(uuidmap_uuid_ptr(ri->uuid), ri);
45 rrdinstance_trigger_updates(ri, __FUNCTION__ );
46 }
47 +
48 return ri->rrdlabels;
49 }
50
51 +inline RRDLABELS *rrdinstance_acquired_labels(RRDINSTANCE_ACQUIRED *ria) {
52 + RRDINSTANCE *ri = rrdinstance_acquired_value(ria);
53 + return rrdinstance_labels(ri);
54 +}
55 +
56 inline DICTIONARY *rrdinstance_acquired_functions(RRDINSTANCE_ACQUIRED *ria) {
57 RRDINSTANCE *ri = rrdinstance_acquired_value(ria);
58 if(!ri->rrdset) return NULL;
@@ -107,14 +115,12 @@ static void rrdinstance_insert_callback(const DICTIONARY_ITEM *item __maybe_unus
115 if(!ri->name)
116 ri->name = string_dup(ri->id);
117
110 - if(ri->rrdset) {
111 - ri->rrdlabels = ri->rrdset->rrdlabels;
118 + ri->rrdlabels = rrdlabels_create();
119 +
120 + if(ri->rrdset)
121 ri->flags &= ~(RRD_FLAG_OWN_LABELS| RRD_FLAG_DEMAND_LABELS); // no need of atomics at the constructor
113 - }
114 - else {
115 - ri->rrdlabels = rrdlabels_create();
122 + else
123 ri->flags |= (RRD_FLAG_OWN_LABELS | RRD_FLAG_DEMAND_LABELS); // no need of atomics at the constructor
117 - }
124
125 if(ri->rrdset) {
126 if(unlikely(rrdset_flag_check(ri->rrdset, RRDSET_FLAG_HIDDEN)))
@@ -199,27 +205,15 @@ static bool rrdinstance_conflict_callback(const DICTIONARY_ITEM *item __maybe_un
205 rrd_flag_set_updated(ri, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
206 }
207
202 - if(ri->rrdset && ri_new->rrdset && ri->rrdset != ri_new->rrdset) {
208 + if(ri_new->rrdset && ri->rrdset != ri_new->rrdset) {
209 ri->rrdset = ri_new->rrdset;
210 rrd_flag_set_updated(ri, RRD_FLAG_UPDATE_REASON_CHANGED_LINKING);
211 }
212
207 - if(ri->rrdset != ri_new->rrdset) {
208 - ri->rrdset = ri_new->rrdset;
209 -
210 - if(ri->rrdset && rrd_flag_check(ri, RRD_FLAG_OWN_LABELS)) {
211 - RRDLABELS *old = ri->rrdlabels;
212 - ri->rrdlabels = ri->rrdset->rrdlabels;
213 - rrd_flag_clear(ri, RRD_FLAG_OWN_LABELS| RRD_FLAG_DEMAND_LABELS);
214 - rrdlabels_destroy(old);
215 - }
216 - else if(!ri->rrdset && !rrd_flag_check(ri, RRD_FLAG_OWN_LABELS)) {
217 - ri->rrdlabels = rrdlabels_create();
218 - rrd_flag_set(ri, RRD_FLAG_OWN_LABELS | RRD_FLAG_DEMAND_LABELS);
219 - }
220 - }
221 -
213 if(ri->rrdset) {
214 + // our labels are not needed any more
215 + rrdlabels_flush(ri->rrdlabels);
216 +
217 if(unlikely(rrdset_flag_check(ri->rrdset, RRDSET_FLAG_HIDDEN)))
218 rrd_flag_set(ri, RRD_FLAG_HIDDEN);
219 else
@@ -438,12 +432,8 @@ inline void rrdinstance_rrdset_is_freed(RRDSET *st) {
432
433 rrdinstance_set_archived(ri);
434
441 - if(!rrd_flag_check(ri, RRD_FLAG_OWN_LABELS)) {
442 - ri->rrdlabels = rrdlabels_create();
443 - // Do not load copy labels, just load on demand
444 - //rrdlabels_copy(ri->rrdlabels, st->rrdlabels);
445 - rrd_flag_set(ri, RRD_FLAG_OWN_LABELS | RRD_FLAG_DEMAND_LABELS);
446 - }
435 + SWAP(ri->rrdlabels, st->rrdlabels);
436 + rrd_flag_set(ri, RRD_FLAG_OWN_LABELS);
437
438 ri->rrdset = NULL;
439
src/database/contexts/internal.h
+2
@@ -481,4 +481,6 @@ void get_metric_retention_by_id(RRDHOST *host, UUIDMAP_ID id, time_t *min_first_
481 void rrdcontext_delete_after_loading(RRDHOST *host, RRDCONTEXT *rc);
482 void rrdcontext_initial_processing_after_loading(RRDCONTEXT *rc);
483
484 +RRDLABELS *rrdinstance_labels(RRDINSTANCE *ri);
485 +
486 #endif //NETDATA_RRDCONTEXT_INTERNAL_H
src/database/contexts/query_target.c
+3 -2
@@ -732,12 +732,13 @@ static inline bool query_instance_matches_labels(
732 SIMPLE_PATTERN *labels_sp)
733 {
734
735 - if (chart_label_key_sp && rrdlabels_match_simple_pattern_parsed(ri->rrdlabels, chart_label_key_sp, '\0', NULL) != SP_MATCHED_POSITIVE)
735 + RRDLABELS *labels = rrdinstance_labels(ri);
736 + if (chart_label_key_sp && rrdlabels_match_simple_pattern_parsed(labels, chart_label_key_sp, '\0', NULL) != SP_MATCHED_POSITIVE)
737 return false;
738
739 if (labels_sp) {
740 struct pattern_array *pa = pattern_array_add_simple_pattern(NULL, labels_sp, ':');
740 - bool found = pattern_array_label_match(pa, ri->rrdlabels, ':', NULL);
741 + bool found = pattern_array_label_match(pa, labels, ':', NULL);
742 pattern_array_free(pa);
743 return found;
744 }
src/database/rrdlabels.c
+9 -2
@@ -183,8 +183,7 @@ static void delete_label(RRDLABEL *label)
183 // ----------------------------------------------------------------------------
184 // rrdlabels_destroy()
185
186 -void rrdlabels_destroy(RRDLABELS *labels)
187 -{
186 +void rrdlabels_flush(RRDLABELS *labels) {
187 if (unlikely(!labels))
188 return;
189
@@ -199,6 +198,14 @@ void rrdlabels_destroy(RRDLABELS *labels)
198 size_t memory_freed = JudyLFreeArray(&labels->JudyL, PJE0);
199 STATS_MINUS_MEMORY(&dictionary_stats_category_rrdlabels, 0, memory_freed + sizeof(RRDLABELS), 0);
200 spinlock_unlock(&labels->spinlock);
201 +}
202 +
203 +void rrdlabels_destroy(RRDLABELS *labels)
204 +{
205 + if (unlikely(!labels))
206 + return;
207 +
208 + rrdlabels_flush(labels);
209 freez(labels);
210 }
211
src/database/rrdlabels.h
+1
@@ -35,6 +35,7 @@ typedef struct rrdlabels RRDLABELS;
35
36 RRDLABELS *rrdlabels_create(void);
37 void rrdlabels_destroy(RRDLABELS *labels_dict);
38 +void rrdlabels_flush(RRDLABELS *labels);
39 void rrdlabels_add(RRDLABELS *labels, const char *name, const char *value, RRDLABEL_SRC ls);
40 void rrdlabels_add_pair(RRDLABELS *labels, const char *string, RRDLABEL_SRC ls);
41 void rrdlabels_value_to_buffer_array_item_or_null(RRDLABELS *labels, BUFFER *wb, const char *key);