diff options
author | Costa Tsaousis <costa@netdata.cloud> | 2023-08-03 09:38:36 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-03 09:38:36 +0300 |
commit | 72549b3a2247f763180925d7c84b0eee8086fa14 (patch) | |
tree | 2926b8ef9497be029ac2a51128e83f7e2e926b31 /database | |
parent | 2fc53f00d40d87f9284e22a4df6014c82374fa0b (diff) |
prefer titles, families, units and priorities from collected charts (#15614)
Diffstat (limited to 'database')
-rw-r--r-- | database/contexts/api_v2.c | 16 | ||||
-rw-r--r-- | database/contexts/context.c | 125 | ||||
-rw-r--r-- | database/contexts/internal.h | 4 | ||||
-rw-r--r-- | database/contexts/worker.c | 7 |
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; |