prefer titles, families, units and priorities from collected charts (#15614)
Costa Tsaousis committed
Aug 3, 2023 at 09:38 UTC
72549b3a2247f763180925d7c84b0eee8086fa14
4 files changed
+113
-39
database/contexts/api_v2.c
+13
-3
@@ -1103,9 +1103,19 @@ static bool contexts_conflict_callback(const DICTIONARY_ITEM *item __maybe_unuse
1103
o->count++;
1104
1105
if(o->family != n->family) {
1106
- STRING *m = string_2way_merge(o->family, n->family);
1107
- string_freez(o->family);
1108
- o->family = m;
1106
+ if((o->flags & RRD_FLAG_COLLECTED) && !(n->flags & RRD_FLAG_COLLECTED))
1107
+ // keep old
1108
+ ;
1109
+ else if(!(o->flags & RRD_FLAG_COLLECTED) && (n->flags & RRD_FLAG_COLLECTED)) {
1110
+ // keep new
1111
+ string_freez(o->family);
1112
+ o->family = string_dup(n->family);
1113
+ }
1114
+ else {
1115
+ // merge
1116
+ string_freez(o->family);
1117
+ o->family = string_2way_merge(o->family, n->family);
1118
+ }
1119
}
1120
1121
if(o->priority != n->priority) {
database/contexts/context.c
+89
-36
@@ -94,6 +94,93 @@ static void rrdcontext_delete_callback(const DICTIONARY_ITEM *item __maybe_unuse
94
rrdcontext_freez(rc);
95
}
96
97
+typedef enum __attribute__((packed)) {
98
+ OLDNEW_KEEP_OLD,
99
+ OLDNEW_USE_NEW,
100
+ OLDNEW_MERGE,
101
+} OLDNEW;
102
+
103
+static inline OLDNEW oldnew_decide(bool archived, bool new_archived) {
104
+ if(archived && !new_archived)
105
+ return OLDNEW_USE_NEW;
106
+
107
+ if(!archived && new_archived)
108
+ return OLDNEW_KEEP_OLD;
109
+
110
+ return OLDNEW_MERGE;
111
+}
112
+
113
+static inline void string_replace(STRING **stringpp, STRING *new_string) {
114
+ STRING *old = *stringpp;
115
+ *stringpp = string_dup(new_string);
116
+ string_freez(old);
117
+}
118
+
119
+static inline void string_merge(STRING **stringpp, STRING *new_string) {
120
+ STRING *old = *stringpp;
121
+ *stringpp = string_2way_merge(*stringpp, new_string);
122
+ string_freez(old);
123
+}
124
+
125
+static void rrdcontext_merge_with(RRDCONTEXT *rc, bool archived, STRING *title, STRING *family, STRING *units, RRDSET_TYPE chart_type, uint32_t priority) {
126
+ OLDNEW oldnew = oldnew_decide(rrd_flag_is_archived(rc), archived);
127
+
128
+ switch(oldnew) {
129
+ case OLDNEW_KEEP_OLD:
130
+ break;
131
+
132
+ case OLDNEW_USE_NEW:
133
+ if(rc->title != title) {
134
+ string_replace(&rc->title, title);
135
+ rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
136
+ }
137
+ if(rc->family != family) {
138
+ string_replace(&rc->family, family);
139
+ rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
140
+ }
141
+ break;
142
+
143
+ case OLDNEW_MERGE:
144
+ if(rc->title != title) {
145
+ string_merge(&rc->title, title);
146
+ rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
147
+ }
148
+ if(rc->family != family) {
149
+ string_merge(&rc->family, family);
150
+ rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
151
+ }
152
+ break;
153
+ }
154
+
155
+ switch(oldnew) {
156
+ case OLDNEW_KEEP_OLD:
157
+ break;
158
+
159
+ case OLDNEW_USE_NEW:
160
+ case OLDNEW_MERGE:
161
+ if(rc->units != units) {
162
+ string_replace(&rc->units, units);
163
+ rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
164
+ }
165
+
166
+ if(rc->chart_type != chart_type) {
167
+ rc->chart_type = chart_type;
168
+ rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
169
+ }
170
+
171
+ if(rc->priority != priority) {
172
+ rc->priority = priority;
173
+ rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
174
+ }
175
+ break;
176
+ }
177
+}
178
+
179
+void rrdcontext_update_from_collected_rrdinstance(RRDINSTANCE *ri) {
180
+ rrdcontext_merge_with(ri->rc, rrd_flag_is_archived(ri),
181
+ ri->title, ri->family, ri->units, ri->chart_type, ri->priority);
182
+}
183
+
184
static bool rrdcontext_conflict_callback(const DICTIONARY_ITEM *item __maybe_unused, void *old_value, void *new_value, void *rrdhost __maybe_unused) {
185
RRDCONTEXT *rc = (RRDCONTEXT *)old_value;
186
RRDCONTEXT *rc_new = (RRDCONTEXT *)new_value;
@@ -106,42 +193,8 @@ static bool rrdcontext_conflict_callback(const DICTIONARY_ITEM *item __maybe_unu
193
194
rrdcontext_lock(rc);
195
109
- if(rc->title != rc_new->title) {
110
- STRING *old_title = rc->title;
111
- if (rrd_flag_is_archived(rc) && !rrd_flag_is_archived(rc_new))
112
- rc->title = string_dup(rc_new->title);
113
- else
114
- rc->title = string_2way_merge(rc->title, rc_new->title);
115
- string_freez(old_title);
116
- rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
117
- }
118
-
119
- if(rc->units != rc_new->units) {
120
- STRING *old_units = rc->units;
121
- rc->units = string_dup(rc_new->units);
122
- string_freez(old_units);
123
- rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
124
- }
125
-
126
- if(rc->family != rc_new->family) {
127
- STRING *old_family = rc->family;
128
- if (rrd_flag_is_archived(rc) && !rrd_flag_is_archived(rc_new))
129
- rc->family = string_dup(rc_new->family);
130
- else
131
- rc->family = string_2way_merge(rc->family, rc_new->family);
132
- string_freez(old_family);
133
- rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
134
- }
135
-
136
- if(rc->chart_type != rc_new->chart_type) {
137
- rc->chart_type = rc_new->chart_type;
138
- rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
139
- }
140
-
141
- if(rc->priority != rc_new->priority) {
142
- rc->priority = rc_new->priority;
143
- rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
144
- }
196
+ rrdcontext_merge_with(rc, rrd_flag_is_archived(rc_new),
197
+ rc_new->title, rc_new->family, rc_new->units, rc_new->chart_type, rc_new->priority);
198
199
rrd_flag_set(rc, rc_new->flags & RRD_FLAGS_ALLOWED_EXTERNALLY_ON_NEW_OBJECTS); // no need for atomics on rc_new
200
database/contexts/internal.h
+4
@@ -58,6 +58,8 @@ typedef enum __attribute__ ((__packed__)) {
58
RRD_FLAG_UPDATE_REASON_UNUSED = (1 << 21), // this context is not used anymore
59
RRD_FLAG_UPDATE_REASON_DB_ROTATION = (1 << 22), // this context changed because of a db rotation
60
61
+ RRD_FLAG_MERGED_COLLECTED_RI_TO_RC = (1 << 29),
62
+
63
// action to perform on an object
64
RRD_FLAG_UPDATE_REASON_UPDATE_RETENTION = (1 << 30), // this object has to update its retention from the db
65
} RRD_FLAGS;
@@ -380,4 +382,6 @@ uint64_t rrdcontext_version_hash_with_callback(
382
383
void rrdcontext_message_send_unsafe(RRDCONTEXT *rc, bool snapshot __maybe_unused, void *bundle __maybe_unused);
384
385
+void rrdcontext_update_from_collected_rrdinstance(RRDINSTANCE *ri);
386
+
387
#endif //NETDATA_RRDCONTEXT_INTERNAL_H
database/contexts/worker.c
+7
@@ -609,6 +609,13 @@ static void rrdcontext_post_process_updates(RRDCONTEXT *rc, bool force, RRD_FLAG
609
continue;
610
}
611
612
+ bool ri_collected = rrd_flag_is_collected(ri);
613
+
614
+ if(ri_collected && !rrd_flag_check(ri, RRD_FLAG_MERGED_COLLECTED_RI_TO_RC)) {
615
+ rrdcontext_update_from_collected_rrdinstance(ri);
616
+ rrd_flag_set(ri, RRD_FLAG_MERGED_COLLECTED_RI_TO_RC);
617
+ }
618
+
619
if(unlikely(!currently_collected && rrd_flag_is_collected(ri) && ri->first_time_s))
620
currently_collected = true;
621