summaryrefslogtreecommitdiffstats
path: root/database
diff options
context:
space:
mode:
authorCosta Tsaousis <costa@netdata.cloud>2023-08-03 09:38:36 +0300
committerGitHub <noreply@github.com>2023-08-03 09:38:36 +0300
commit72549b3a2247f763180925d7c84b0eee8086fa14 (patch)
tree2926b8ef9497be029ac2a51128e83f7e2e926b31 /database
parent2fc53f00d40d87f9284e22a4df6014c82374fa0b (diff)
prefer titles, families, units and priorities from collected charts (#15614)
Diffstat (limited to 'database')
-rw-r--r--database/contexts/api_v2.c16
-rw-r--r--database/contexts/context.c125
-rw-r--r--database/contexts/internal.h4
-rw-r--r--database/contexts/worker.c7
4 files changed, 113 insertions, 39 deletions
diff --git a/database/contexts/api_v2.c b/database/contexts/api_v2.c
index 3bd6e3051d..ac6e9c4032 100644
--- a/database/contexts/api_v2.c
+++ b/database/contexts/api_v2.c
@@ -1103,9 +1103,19 @@ static bool contexts_conflict_callback(const DICTIONARY_ITEM *item __maybe_unuse
o->count++;
if(o->family != n->family) {
- STRING *m = string_2way_merge(o->family, n->family);
- string_freez(o->family);
- o->family = m;
+ if((o->flags & RRD_FLAG_COLLECTED) && !(n->flags & RRD_FLAG_COLLECTED))
+ // keep old
+ ;
+ else if(!(o->flags & RRD_FLAG_COLLECTED) && (n->flags & RRD_FLAG_COLLECTED)) {
+ // keep new
+ string_freez(o->family);
+ o->family = string_dup(n->family);
+ }
+ else {
+ // merge
+ string_freez(o->family);
+ o->family = string_2way_merge(o->family, n->family);
+ }
}
if(o->priority != n->priority) {
diff --git a/database/contexts/context.c b/database/contexts/context.c
index 47946f1e05..5613c63cff 100644
--- a/database/contexts/context.c
+++ b/database/contexts/context.c
@@ -94,6 +94,93 @@ static void rrdcontext_delete_callback(const DICTIONARY_ITEM *item __maybe_unuse
rrdcontext_freez(rc);
}
+typedef enum __attribute__((packed)) {
+ OLDNEW_KEEP_OLD,
+ OLDNEW_USE_NEW,
+ OLDNEW_MERGE,
+} OLDNEW;
+
+static inline OLDNEW oldnew_decide(bool archived, bool new_archived) {
+ if(archived && !new_archived)
+ return OLDNEW_USE_NEW;
+
+ if(!archived && new_archived)
+ return OLDNEW_KEEP_OLD;
+
+ return OLDNEW_MERGE;
+}
+
+static inline void string_replace(STRING **stringpp, STRING *new_string) {
+ STRING *old = *stringpp;
+ *stringpp = string_dup(new_string);
+ string_freez(old);
+}
+
+static inline void string_merge(STRING **stringpp, STRING *new_string) {
+ STRING *old = *stringpp;
+ *stringpp = string_2way_merge(*stringpp, new_string);
+ string_freez(old);
+}
+
+static void rrdcontext_merge_with(RRDCONTEXT *rc, bool archived, STRING *title, STRING *family, STRING *units, RRDSET_TYPE chart_type, uint32_t priority) {
+ OLDNEW oldnew = oldnew_decide(rrd_flag_is_archived(rc), archived);
+
+ switch(oldnew) {
+ case OLDNEW_KEEP_OLD:
+ break;
+
+ case OLDNEW_USE_NEW:
+ if(rc->title != title) {
+ string_replace(&rc->title, title);
+ rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
+ }
+ if(rc->family != family) {
+ string_replace(&rc->family, family);
+ rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
+ }
+ break;
+
+ case OLDNEW_MERGE:
+ if(rc->title != title) {
+ string_merge(&rc->title, title);
+ rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
+ }
+ if(rc->family != family) {
+ string_merge(&rc->family, family);
+ rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
+ }
+ break;
+ }
+
+ switch(oldnew) {
+ case OLDNEW_KEEP_OLD:
+ break;
+
+ case OLDNEW_USE_NEW:
+ case OLDNEW_MERGE:
+ if(rc->units != units) {
+ string_replace(&rc->units, units);
+ rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
+ }
+
+ if(rc->chart_type != chart_type) {
+ rc->chart_type = chart_type;
+ rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
+ }
+
+ if(rc->priority != priority) {
+ rc->priority = priority;
+ rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
+ }
+ break;
+ }
+}
+
+void rrdcontext_update_from_collected_rrdinstance(RRDINSTANCE *ri) {
+ rrdcontext_merge_with(ri->rc, rrd_flag_is_archived(ri),
+ ri->title, ri->family, ri->units, ri->chart_type, ri->priority);
+}
+
static bool rrdcontext_conflict_callback(const DICTIONARY_ITEM *item __maybe_unused, void *old_value, void *new_value, void *rrdhost __maybe_unused) {
RRDCONTEXT *rc = (RRDCONTEXT *)old_value;
RRDCONTEXT *rc_new = (RRDCONTEXT *)new_value;
@@ -106,42 +193,8 @@ static bool rrdcontext_conflict_callback(const DICTIONARY_ITEM *item __maybe_unu
rrdcontext_lock(rc);
- if(rc->title != rc_new->title) {
- STRING *old_title = rc->title;
- if (rrd_flag_is_archived(rc) && !rrd_flag_is_archived(rc_new))
- rc->title = string_dup(rc_new->title);
- else
- rc->title = string_2way_merge(rc->title, rc_new->title);
- string_freez(old_title);
- rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
- }
-
- if(rc->units != rc_new->units) {
- STRING *old_units = rc->units;
- rc->units = string_dup(rc_new->units);
- string_freez(old_units);
- rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
- }
-
- if(rc->family != rc_new->family) {
- STRING *old_family = rc->family;
- if (rrd_flag_is_archived(rc) && !rrd_flag_is_archived(rc_new))
- rc->family = string_dup(rc_new->family);
- else
- rc->family = string_2way_merge(rc->family, rc_new->family);
- string_freez(old_family);
- rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
- }
-
- if(rc->chart_type != rc_new->chart_type) {
- rc->chart_type = rc_new->chart_type;
- rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
- }
-
- if(rc->priority != rc_new->priority) {
- rc->priority = rc_new->priority;
- rrd_flag_set_updated(rc, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
- }
+ rrdcontext_merge_with(rc, rrd_flag_is_archived(rc_new),
+ rc_new->title, rc_new->family, rc_new->units, rc_new->chart_type, rc_new->priority);
rrd_flag_set(rc, rc_new->flags & RRD_FLAGS_ALLOWED_EXTERNALLY_ON_NEW_OBJECTS); // no need for atomics on rc_new
diff --git a/database/contexts/internal.h b/database/contexts/internal.h
index bdd1fa4bc4..81b4271347 100644
--- a/database/contexts/internal.h
+++ b/database/contexts/internal.h
@@ -58,6 +58,8 @@ typedef enum __attribute__ ((__packed__)) {
RRD_FLAG_UPDATE_REASON_UNUSED = (1 << 21), // this context is not used anymore
RRD_FLAG_UPDATE_REASON_DB_ROTATION = (1 << 22), // this context changed because of a db rotation
+ RRD_FLAG_MERGED_COLLECTED_RI_TO_RC = (1 << 29),
+
// action to perform on an object
RRD_FLAG_UPDATE_REASON_UPDATE_RETENTION = (1 << 30), // this object has to update its retention from the db
} RRD_FLAGS;
@@ -380,4 +382,6 @@ uint64_t rrdcontext_version_hash_with_callback(
void rrdcontext_message_send_unsafe(RRDCONTEXT *rc, bool snapshot __maybe_unused, void *bundle __maybe_unused);
+void rrdcontext_update_from_collected_rrdinstance(RRDINSTANCE *ri);
+
#endif //NETDATA_RRDCONTEXT_INTERNAL_H
diff --git a/database/contexts/worker.c b/database/contexts/worker.c
index c10cb7c241..e145c1093f 100644
--- a/database/contexts/worker.c
+++ b/database/contexts/worker.c
@@ -609,6 +609,13 @@ static void rrdcontext_post_process_updates(RRDCONTEXT *rc, bool force, RRD_FLAG
continue;
}
+ bool ri_collected = rrd_flag_is_collected(ri);
+
+ if(ri_collected && !rrd_flag_check(ri, RRD_FLAG_MERGED_COLLECTED_RI_TO_RC)) {
+ rrdcontext_update_from_collected_rrdinstance(ri);
+ rrd_flag_set(ri, RRD_FLAG_MERGED_COLLECTED_RI_TO_RC);
+ }
+
if(unlikely(!currently_collected && rrd_flag_is_collected(ri) && ri->first_time_s))
currently_collected = true;