master
h 559 lines 25.3 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #ifndef NETDATA_RRDCONTEXT_INTERNAL_H
4 #define NETDATA_RRDCONTEXT_INTERNAL_H 1
5
6 #include "rrdcontext.h"
7 #include "rrdcontext-context-registry.h"
8 #include "../sqlite/sqlite_context.h"
9 #include "../../aclk/schema-wrappers/rrdcontext-context.h"
10 #include "../../aclk/aclk_contexts_api.h"
11 #include "../../aclk/aclk.h"
12 #include "../storage-engine.h"
13
14 #define MESSAGES_PER_BUNDLE_TO_SEND_TO_HUB_PER_HOST 5000
15 #define FULL_RETENTION_SCAN_DELAY_AFTER_DB_ROTATION_SECS 120
16 #define RRDCONTEXT_WORKER_THREAD_HEARTBEAT_USEC (1000 * USEC_PER_MS)
17 #define RRDCONTEXT_MINIMUM_ALLOWED_PRIORITY 10
18
19 #define LOG_TRANSITIONS false
20
21 #define WORKER_JOB_HOSTS 1
22 #define WORKER_JOB_CHECK 2
23 #define WORKER_JOB_SEND 3
24 #define WORKER_JOB_DEQUEUE 4
25 #define WORKER_JOB_RETENTION 5
26 #define WORKER_JOB_QUEUED 6
27 #define WORKER_JOB_CLEANUP 7
28 #define WORKER_JOB_CLEANUP_DELETE 8
29 #define WORKER_JOB_PP_METRIC 9 // post-processing metrics
30 #define WORKER_JOB_PP_INSTANCE 10 // post-processing instances
31 #define WORKER_JOB_PP_CONTEXT 11 // post-processing contexts
32 #define WORKER_JOB_HUB_QUEUE_SIZE 12
33 #define WORKER_JOB_PP_QUEUE_SIZE 13
34
35
36 typedef enum __attribute__ ((__packed__)) {
37 RRD_FLAG_NONE = 0,
38 RRD_FLAG_DELETED = (1 << 0), // this is a deleted object (metrics, instances, contexts)
39 RRD_FLAG_COLLECTED = (1 << 1), // this object is currently being collected
40 RRD_FLAG_UPDATED = (1 << 2), // this object has updates to propagate
41 RRD_FLAG_ARCHIVED = (1 << 3), // this object is not currently being collected
42 RRD_FLAG_OWN_LABELS = (1 << 4), // this instance has its own labels - not linked to an RRDSET
43 RRD_FLAG_DEMAND_LABELS = (1 << 5), // this instance should load labels on demand
44 RRD_FLAG_LIVE_RETENTION = (1 << 6), // we have got live retention from the database
45 RRD_FLAG_QUEUED_FOR_HUB = (1 << 7), // this context is currently queued to be dispatched to hub
46 RRD_FLAG_QUEUED_FOR_PP = (1 << 8), // this context is currently queued to be post-processed
47 RRD_FLAG_HIDDEN = (1 << 9), // don't expose this to the hub or the API
48
49 RRD_FLAG_UPDATE_REASON_TRIGGERED = (1 << 10), // the update was triggered by the child object
50 RRD_FLAG_UPDATE_REASON_LOAD_SQL = (1 << 11), // this object has just been loaded from SQL
51 RRD_FLAG_UPDATE_REASON_NEW_OBJECT = (1 << 12), // this object has just been created
52 RRD_FLAG_UPDATE_REASON_UPDATED_OBJECT = (1 << 13), // we received an update on this object
53 RRD_FLAG_UPDATE_REASON_CHANGED_LINKING = (1 << 14), // an instance or a metric switched RRDSET or RRDDIM
54 RRD_FLAG_UPDATE_REASON_CHANGED_METADATA = (1 << 15), // this context or instance changed uuid, name, units, title, family, chart type, priority, update every, rrd changed flags
55 RRD_FLAG_UPDATE_REASON_ZERO_RETENTION = (1 << 16), // this object has no retention
56 RRD_FLAG_UPDATE_REASON_CHANGED_FIRST_TIME_T = (1 << 17), // this object changed its oldest time in the db
57 RRD_FLAG_UPDATE_REASON_CHANGED_LAST_TIME_T = (1 << 18), // this object change its latest time in the db
58 RRD_FLAG_UPDATE_REASON_STOPPED_BEING_COLLECTED = (1 << 19), // this object has stopped being collected
59 RRD_FLAG_UPDATE_REASON_STARTED_BEING_COLLECTED = (1 << 20), // this object has started being collected
60 RRD_FLAG_UPDATE_REASON_DISCONNECTED_CHILD = (1 << 21), // this context belongs to a host that just disconnected
61 RRD_FLAG_UPDATE_REASON_UNUSED = (1 << 22), // this context is not used anymore
62 RRD_FLAG_UPDATE_REASON_DB_ROTATION = (1 << 23), // this context changed because of a db rotation
63
64 RRD_FLAG_NO_TIER0_RETENTION = (1 << 28),
65 RRD_FLAG_MERGED_COLLECTED_RI_TO_RC = (1 << 29),
66
67 // action to perform on an object
68 RRD_FLAG_UPDATE_REASON_UPDATE_RETENTION = (1 << 30), // this object has to update its retention from the db
69 } RRD_FLAGS;
70
71 struct rrdcontext_reason {
72 RRD_FLAGS flag;
73 const char *name;
74 usec_t delay_ut;
75 };
76
77 extern struct rrdcontext_reason rrdcontext_reasons[];
78
79 #define RRD_FLAG_ALL_UPDATE_REASONS ( \
80 RRD_FLAG_UPDATE_REASON_TRIGGERED \
81 |RRD_FLAG_UPDATE_REASON_LOAD_SQL \
82 |RRD_FLAG_UPDATE_REASON_NEW_OBJECT \
83 |RRD_FLAG_UPDATE_REASON_UPDATED_OBJECT \
84 |RRD_FLAG_UPDATE_REASON_CHANGED_LINKING \
85 |RRD_FLAG_UPDATE_REASON_CHANGED_METADATA \
86 |RRD_FLAG_UPDATE_REASON_ZERO_RETENTION \
87 |RRD_FLAG_UPDATE_REASON_CHANGED_FIRST_TIME_T \
88 |RRD_FLAG_UPDATE_REASON_CHANGED_LAST_TIME_T \
89 |RRD_FLAG_UPDATE_REASON_STOPPED_BEING_COLLECTED \
90 |RRD_FLAG_UPDATE_REASON_STARTED_BEING_COLLECTED \
91 |RRD_FLAG_UPDATE_REASON_DISCONNECTED_CHILD \
92 |RRD_FLAG_UPDATE_REASON_DB_ROTATION \
93 |RRD_FLAG_UPDATE_REASON_UNUSED \
94 )
95
96 #define RRD_FLAGS_ALLOWED_EXTERNALLY_ON_NEW_OBJECTS ( \
97 RRD_FLAG_ARCHIVED \
98 |RRD_FLAG_HIDDEN \
99 |RRD_FLAG_ALL_UPDATE_REASONS \
100 )
101
102 #define RRD_FLAGS_REQUIRED_FOR_DELETIONS ( \
103 RRD_FLAG_DELETED \
104 |RRD_FLAG_LIVE_RETENTION \
105 )
106
107 #define RRD_FLAGS_PREVENTING_DELETIONS ( \
108 RRD_FLAG_QUEUED_FOR_HUB \
109 |RRD_FLAG_COLLECTED \
110 |RRD_FLAG_QUEUED_FOR_PP \
111 )
112
113 // get all the flags of an object
114 #define rrd_flags_get(obj) __atomic_load_n(&((obj)->flags), __ATOMIC_SEQ_CST)
115
116 // check if ANY of the given flags (bits) is set
117 #define rrd_flag_check(obj, flag) (rrd_flags_get(obj) & (flag))
118
119 // check if ALL the given flags (bits) are set
120 #define rrd_flag_check_all(obj, flag) (rrd_flag_check(obj, flag) == (flag))
121
122 // set one or more flags (bits)
123 // NEVER alter RRD_FLAG_COLLECTED, RRD_FLAG_ARCHIVED, RRD_FLAG_DELETED with this
124 #define rrd_flag_set(obj, flag) __atomic_or_fetch(&((obj)->flags), flag, __ATOMIC_SEQ_CST)
125
126 // clear one or more flags (bits)
127 // NEVER alter RRD_FLAG_COLLECTED, RRD_FLAG_ARCHIVED, RRD_FLAG_DELETED with this
128 #define rrd_flag_clear(obj, flag) __atomic_and_fetch(&((obj)->flags), ~(flag), __ATOMIC_SEQ_CST)
129
130 static ALWAYS_INLINE RRD_FLAGS
131 rrd_flag_add_remove_atomic(RRD_FLAGS *flags, RRD_FLAGS check, RRD_FLAGS conditionally_add, RRD_FLAGS always_remove) {
132 RRD_FLAGS expected, desired;
133
134 do {
135 expected = *flags;
136
137 desired = expected;
138 desired &= ~(always_remove);
139
140 if(!(expected & check))
141 desired |= (check | conditionally_add);
142
143 } while(!__atomic_compare_exchange_n(flags, &expected, desired, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST));
144
145 return expected;
146 }
147
148 static ALWAYS_INLINE RRD_FLAGS
149 rrd_flags_replace_atomic(RRD_FLAGS *flags, RRD_FLAGS desired) {
150 RRD_FLAGS expected;
151
152 do {
153 expected = *flags;
154 } while(!__atomic_compare_exchange_n(flags, &expected, desired, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST));
155
156 return expected;
157 }
158
159 #define rrd_flag_set_collected(obj) \
160 rrd_flag_add_remove_atomic(&((obj)->flags) \
161 /* check this flag */ \
162 , RRD_FLAG_COLLECTED \
163 \
164 /* add these flags together with the above, if the above is not already set */ \
165 , RRD_FLAG_UPDATE_REASON_STARTED_BEING_COLLECTED | RRD_FLAG_UPDATED \
166 \
167 /* always remove these flags */ \
168 , RRD_FLAG_ARCHIVED \
169 | RRD_FLAG_DELETED \
170 | RRD_FLAG_UPDATE_REASON_STOPPED_BEING_COLLECTED \
171 | RRD_FLAG_UPDATE_REASON_ZERO_RETENTION \
172 | RRD_FLAG_UPDATE_REASON_DISCONNECTED_CHILD \
173 )
174
175 #define rrd_flag_set_archived(obj) \
176 rrd_flag_add_remove_atomic(&((obj)->flags) \
177 /* check this flag */ \
178 , RRD_FLAG_ARCHIVED \
179 \
180 /* add these flags together with the above, if the above is not already set */ \
181 , RRD_FLAG_UPDATE_REASON_STOPPED_BEING_COLLECTED | RRD_FLAG_UPDATED \
182 \
183 /* always remove these flags */ \
184 , RRD_FLAG_COLLECTED \
185 | RRD_FLAG_DELETED \
186 | RRD_FLAG_UPDATE_REASON_STARTED_BEING_COLLECTED \
187 | RRD_FLAG_UPDATE_REASON_ZERO_RETENTION \
188 )
189
190 #define rrd_flag_set_deleted(obj, reason) \
191 rrd_flag_add_remove_atomic(&((obj)->flags) \
192 /* check this flag */ \
193 , RRD_FLAG_DELETED \
194 \
195 /* add these flags together with the above, if the above is not already set */ \
196 , RRD_FLAG_UPDATE_REASON_ZERO_RETENTION | RRD_FLAG_UPDATED | (reason) \
197 \
198 /* always remove these flags */ \
199 , RRD_FLAG_ARCHIVED \
200 | RRD_FLAG_COLLECTED \
201 )
202
203 #define rrd_flag_is_collected(obj) rrd_flag_check(obj, RRD_FLAG_COLLECTED)
204 #define rrd_flag_is_archived(obj) rrd_flag_check(obj, RRD_FLAG_ARCHIVED)
205 #define rrd_flag_is_deleted(obj) rrd_flag_check(obj, RRD_FLAG_DELETED)
206 #define rrd_flag_is_updated(obj) rrd_flag_check(obj, RRD_FLAG_UPDATED)
207
208 // mark an object as updated, providing reasons (additional bits)
209 #define rrd_flag_set_updated(obj, reason) rrd_flag_set(obj, RRD_FLAG_UPDATED | (reason))
210
211 // clear an object as being updated, clearing also all the reasons
212 #define rrd_flag_unset_updated(obj) rrd_flag_clear(obj, RRD_FLAG_UPDATED | RRD_FLAG_ALL_UPDATE_REASONS)
213
214
215 typedef struct rrdmetric {
216 UUIDMAP_ID uuid;
217 RRD_FLAGS flags;
218
219 STRING *id;
220 STRING *name;
221
222 RRDDIM *rrddim;
223 RRD_ALGORITHM algorithm; // atomic load/store; survives RRDDIM archive so query paths don't need a live rrddim
224
225 time_t first_time_s;
226 time_t last_time_s;
227
228 struct rrdinstance *ri;
229 } RRDMETRIC;
230
231 static ALWAYS_INLINE RRDDIM *rrdmetric_rrddim_atomic_load(RRDMETRIC *rm) {
232 return __atomic_load_n(&rm->rrddim, __ATOMIC_ACQUIRE);
233 }
234
235 static ALWAYS_INLINE void rrdmetric_rrddim_atomic_store(RRDMETRIC *rm, RRDDIM *rd) {
236 __atomic_store_n(&rm->rrddim, rd, __ATOMIC_RELEASE);
237 }
238
239 static ALWAYS_INLINE RRD_ALGORITHM rrdmetric_algorithm_atomic_load(RRDMETRIC *rm) {
240 return __atomic_load_n(&rm->algorithm, __ATOMIC_ACQUIRE);
241 }
242
243 static ALWAYS_INLINE void rrdmetric_algorithm_atomic_store(RRDMETRIC *rm, RRD_ALGORITHM algorithm) {
244 __atomic_store_n(&rm->algorithm, algorithm, __ATOMIC_RELEASE);
245 }
246
247 static ALWAYS_INLINE RRDDIM *rrdmetric_rrddim_get_and_lock(RRDMETRIC *rm) {
248 for(size_t retries = 0; retries < 5; retries++) {
249 RRDDIM *rd = rrdmetric_rrddim_atomic_load(rm);
250 if(unlikely(!rd))
251 return NULL;
252
253 if(unlikely(!spinlock_trylock(&rd->destroy_lock))) {
254 if(retries + 1 < 5)
255 microsleep(1 * USEC_PER_MS);
256 continue;
257 }
258
259 if(unlikely(rrdmetric_rrddim_atomic_load(rm) != rd)) {
260 spinlock_unlock(&rd->destroy_lock);
261 continue;
262 }
263
264 return rd;
265 }
266
267 return NULL;
268 }
269
270 static ALWAYS_INLINE void rrdmetric_rrddim_unlock(RRDDIM *rd) {
271 if(likely(rd))
272 spinlock_unlock(&rd->destroy_lock);
273 }
274
275 typedef struct rrdinstance {
276 UUIDMAP_ID uuid;
277 int update_every_s; // data collection frequency
278
279 RRD_FLAGS flags; // flags related to this instance
280 uint32_t priority:24;
281 RRDSET_TYPE chart_type;
282
283 STRING *id;
284 STRING *name;
285 STRING *title;
286 STRING *units;
287 STRING *family;
288
289 time_t first_time_s;
290 time_t last_time_s;
291
292 RRDSET *rrdset; // pointer to RRDSET when collected, or NULL
293
294 RRDLABELS *rrdlabels; // linked to RRDSET->chart_labels or own version
295
296 struct rrdcontext *rc;
297 DICTIONARY *rrdmetrics;
298
299 struct {
300 uint32_t collected_metrics_count; // a temporary variable to detect BEGIN/END without SET
301 // don't use it for other purposes
302 // it goes up and then resets to zero, on every iteration
303 } internal;
304 } RRDINSTANCE;
305
306 typedef struct rrdcontext {
307 uint64_t version;
308
309 STRING *id;
310 STRING *title;
311 STRING *units;
312 STRING *family;
313 uint32_t priority;
314 RRDSET_TYPE chart_type;
315
316 SPINLOCK spinlock;
317
318 RRD_FLAGS flags;
319 time_t first_time_s;
320 time_t last_time_s;
321
322 VERSIONED_CONTEXT_DATA hub;
323
324 DICTIONARY *rrdinstances;
325 RRDHOST *rrdhost;
326
327 struct {
328 Word_t idx;
329 RRD_FLAGS queued_flags; // the last flags that triggered the post-processing
330 size_t executions; // how many times this context has been processed
331 usec_t queued_ut; // the last time this was queued
332 usec_t dequeued_ut; // the last time we sent (or deduplicated) this context
333 } pp;
334
335 struct {
336 Word_t idx;
337 RRD_FLAGS queued_flags; // the last flags that triggered the queueing
338 size_t dispatches; // the number of times this has been dispatched to hub
339 usec_t queued_ut; // the last time this was queued
340 usec_t delay_calc_ut; // the last time we calculated the scheduled_dispatched_ut
341 usec_t scheduled_dispatch_ut; // the time it was/is scheduled to be sent
342 usec_t dequeued_ut; // the last time we sent (or deduplicated) this context
343 } queue;
344 } RRDCONTEXT;
345
346 void rrdcontext_add_to_pp_queue(RRDCONTEXT *rc);
347 void rrdcontext_add_to_hub_queue(RRDCONTEXT *rc);
348 void rrdcontext_del_from_hub_queue(RRDCONTEXT *rc, bool having_lock);
349 void rrdcontext_del_from_pp_queue(RRDCONTEXT *rc, bool having_lock);
350
351 // ----------------------------------------------------------------------------
352 // helpers for counting collected metrics, instances and contexts
353
354 static ALWAYS_INLINE void rrdmetric_set_collected(RRDMETRIC *rm) {
355 RRD_FLAGS old = rrd_flag_set_collected(rm);
356 if(!(old & RRD_FLAG_COLLECTED))
357 __atomic_add_fetch(&rm->ri->rc->rrdhost->collected.metrics_count, 1, __ATOMIC_RELAXED);
358
359 RRDDIM *rd = rrdmetric_rrddim_atomic_load(rm);
360 if(likely(rd))
361 rd->rrdcontexts.collected = true;
362 }
363
364 static ALWAYS_INLINE void rrdmetric_set_archived(RRDMETRIC *rm) {
365 RRD_FLAGS old = rrd_flag_set_archived(rm);
366 if(old & RRD_FLAG_COLLECTED)
367 __atomic_sub_fetch(&rm->ri->rc->rrdhost->collected.metrics_count, 1, __ATOMIC_RELAXED);
368 }
369
370 static ALWAYS_INLINE void rrdmetric_set_deleted(RRDMETRIC *rm, RRD_FLAGS reason) {
371 RRD_FLAGS old = rrd_flag_set_deleted(rm, reason);
372 if(old & RRD_FLAG_COLLECTED)
373 __atomic_sub_fetch(&rm->ri->rc->rrdhost->collected.metrics_count, 1, __ATOMIC_RELAXED);
374 }
375
376 static ALWAYS_INLINE void rrdmetric_set_deleted_overwrite(RRDMETRIC *rm, RRD_FLAGS replacement) {
377 replacement &= ~(RRD_FLAG_COLLECTED|RRD_FLAG_ARCHIVED|RRD_FLAG_DELETED);
378 replacement |= RRD_FLAG_DELETED;
379 RRD_FLAGS old = rrd_flags_replace_atomic(&rm->flags, replacement);
380 if(old & RRD_FLAG_COLLECTED)
381 __atomic_sub_fetch(&rm->ri->rc->rrdhost->collected.metrics_count, 1, __ATOMIC_RELAXED);
382 }
383
384 static ALWAYS_INLINE void rrdinstance_set_collected(RRDINSTANCE *ri) {
385 RRD_FLAGS old = rrd_flag_set_collected(ri);
386 if(!(old & RRD_FLAG_COLLECTED))
387 __atomic_add_fetch(&ri->rc->rrdhost->collected.instances_count, 1, __ATOMIC_RELAXED);
388 }
389
390 static ALWAYS_INLINE void rrdinstance_set_archived(RRDINSTANCE *ri) {
391 RRD_FLAGS old = rrd_flag_set_archived(ri);
392 if(old & RRD_FLAG_COLLECTED)
393 __atomic_sub_fetch(&ri->rc->rrdhost->collected.instances_count, 1, __ATOMIC_RELAXED);
394 }
395
396 static ALWAYS_INLINE void rrdinstance_set_deleted(RRDINSTANCE *ri, RRD_FLAGS reason) {
397 RRD_FLAGS old = rrd_flag_set_deleted(ri, reason);
398 if(old & RRD_FLAG_COLLECTED)
399 __atomic_sub_fetch(&ri->rc->rrdhost->collected.instances_count, 1, __ATOMIC_RELAXED);
400 }
401
402 static ALWAYS_INLINE void rrdinstance_set_deleted_overwrite(RRDINSTANCE *ri, RRD_FLAGS replacement) {
403 replacement &= ~(RRD_FLAG_COLLECTED|RRD_FLAG_ARCHIVED|RRD_FLAG_DELETED);
404 replacement |= RRD_FLAG_DELETED;
405 RRD_FLAGS old = rrd_flags_replace_atomic(&ri->flags, replacement);
406 if(old & RRD_FLAG_COLLECTED)
407 __atomic_sub_fetch(&ri->rc->rrdhost->collected.instances_count, 1, __ATOMIC_RELAXED);
408 }
409
410 static ALWAYS_INLINE void rrdcontext_set_collected(RRDCONTEXT *rc) {
411 RRD_FLAGS old = rrd_flag_set_collected(rc);
412 if(!(old & RRD_FLAG_COLLECTED))
413 __atomic_add_fetch(&rc->rrdhost->collected.contexts_count, 1, __ATOMIC_RELAXED);
414 }
415
416 static ALWAYS_INLINE void rrdcontext_set_archived(RRDCONTEXT *rc) {
417 RRD_FLAGS old = rrd_flag_set_archived(rc);
418 if(old & RRD_FLAG_COLLECTED)
419 __atomic_sub_fetch(&rc->rrdhost->collected.contexts_count, 1, __ATOMIC_RELAXED);
420 }
421
422 static ALWAYS_INLINE void rrdcontext_set_deleted(RRDCONTEXT *rc, RRD_FLAGS reason) {
423 RRD_FLAGS old = rrd_flag_set_deleted(rc, reason);
424 if(old & RRD_FLAG_COLLECTED)
425 __atomic_sub_fetch(&rc->rrdhost->collected.contexts_count, 1, __ATOMIC_RELAXED);
426 }
427
428 // ----------------------------------------------------------------------------
429 // helper one-liners for RRDMETRIC
430
431 bool rrdmetric_update_retention(RRDMETRIC *rm);
432
433 static ALWAYS_INLINE RRDMETRIC *rrdmetric_acquired_value(RRDMETRIC_ACQUIRED *rma) {
434 return dictionary_acquired_item_value((DICTIONARY_ITEM *)rma);
435 }
436
437 static ALWAYS_INLINE RRDMETRIC_ACQUIRED *rrdmetric_acquired_dup(RRDMETRIC_ACQUIRED *rma) {
438 RRDMETRIC *rm = rrdmetric_acquired_value(rma);
439 return (RRDMETRIC_ACQUIRED *)dictionary_acquired_item_dup(rm->ri->rrdmetrics, (DICTIONARY_ITEM *)rma);
440 }
441
442 static ALWAYS_INLINE void rrdmetric_release(RRDMETRIC_ACQUIRED *rma) {
443 RRDMETRIC *rm = rrdmetric_acquired_value(rma);
444 dictionary_acquired_item_release(rm->ri->rrdmetrics, (DICTIONARY_ITEM *)rma);
445 }
446
447 void rrdmetric_rrddim_is_freed(RRDDIM *rd);
448 void rrdmetric_updated_rrddim_flags(RRDDIM *rd);
449 void rrdmetric_updated_rrddim_algorithm(RRDDIM *rd);
450 void rrdmetric_collected_rrddim(RRDDIM *rd);
451 void rrdmetric_not_collected_rrddim(RRDDIM *rd);
452
453 // ----------------------------------------------------------------------------
454 // helper one-liners for RRDINSTANCE
455
456 static ALWAYS_INLINE RRDINSTANCE *rrdinstance_acquired_value(RRDINSTANCE_ACQUIRED *ria) {
457 return dictionary_acquired_item_value((DICTIONARY_ITEM *)ria);
458 }
459
460 static ALWAYS_INLINE RRDINSTANCE_ACQUIRED *rrdinstance_acquired_dup(RRDINSTANCE_ACQUIRED *ria) {
461 RRDINSTANCE *ri = rrdinstance_acquired_value(ria);
462 return (RRDINSTANCE_ACQUIRED *)dictionary_acquired_item_dup(ri->rc->rrdinstances, (DICTIONARY_ITEM *)ria);
463 }
464
465 static ALWAYS_INLINE void rrdinstance_release(RRDINSTANCE_ACQUIRED *ria) {
466 RRDINSTANCE *ri = rrdinstance_acquired_value(ria);
467 dictionary_acquired_item_release(ri->rc->rrdinstances, (DICTIONARY_ITEM *)ria);
468 }
469
470 void rrdinstance_from_rrdset(RRDSET *st);
471 void rrdinstance_rrdset_is_freed(RRDSET *st);
472 void rrdinstance_rrdset_has_updated_retention(RRDSET *st);
473 void rrdinstance_updated_rrdset_name(RRDSET *st);
474 void rrdinstance_updated_rrdset_flags_no_action(RRDINSTANCE *ri, RRDSET *st);
475 void rrdinstance_updated_rrdset_flags(RRDSET *st);
476 void rrdinstance_collected_rrdset(RRDSET *st);
477 void rrdinstance_rrdset_not_collected(RRDSET *st);
478
479 void rrdcontext_queue_for_post_processing(RRDCONTEXT *rc, const char *function, RRD_FLAGS flags);
480
481 // ----------------------------------------------------------------------------
482 // helper one-liners for RRDCONTEXT
483
484 static ALWAYS_INLINE RRDCONTEXT *rrdcontext_acquired_value(RRDCONTEXT_ACQUIRED *rca) {
485 return dictionary_acquired_item_value((DICTIONARY_ITEM *)rca);
486 }
487
488 static ALWAYS_INLINE RRDCONTEXT_ACQUIRED *rrdcontext_acquired_dup(RRDCONTEXT_ACQUIRED *rca) {
489 RRDCONTEXT *rc = rrdcontext_acquired_value(rca);
490 return (RRDCONTEXT_ACQUIRED *)dictionary_acquired_item_dup(rc->rrdhost->rrdctx.contexts, (DICTIONARY_ITEM *)rca);
491 }
492
493 static ALWAYS_INLINE void rrdcontext_release(RRDCONTEXT_ACQUIRED *rca) {
494 RRDCONTEXT *rc = rrdcontext_acquired_value(rca);
495 dictionary_acquired_item_release(rc->rrdhost->rrdctx.contexts, (DICTIONARY_ITEM *)rca);
496 }
497
498 // ----------------------------------------------------------------------------
499 // Forward definitions
500 void load_instance_labels_on_demand(nd_uuid_t *uuid, void *data);
501
502 void rrdcontext_recalculate_context_retention(RRDCONTEXT *rc, RRD_FLAGS reason, bool worker_jobs);
503 void rrdcontext_recalculate_host_retention(RRDHOST *host, RRD_FLAGS reason, bool worker_jobs);
504
505 #define rrdcontext_lock(rc) spinlock_lock(&((rc)->spinlock))
506 #define rrdcontext_unlock(rc) spinlock_unlock(&((rc)->spinlock))
507
508 void rrdmetric_trigger_updates(RRDMETRIC *rm, const char *function);
509 void rrdinstance_trigger_updates(RRDINSTANCE *ri, const char *function);
510 void rrdcontext_trigger_updates(RRDCONTEXT *rc, const char *function);
511
512 void rrdinstances_create_in_rrdcontext(RRDCONTEXT *rc);
513 void rrdinstances_destroy_from_rrdcontext(RRDCONTEXT *rc);
514
515 void rrdmetrics_destroy_from_rrdinstance(RRDINSTANCE *ri);
516 void rrdmetrics_create_in_rrdinstance(RRDINSTANCE *ri);
517
518 void rrdmetric_from_rrddim(RRDDIM *rd);
519
520 void rrd_reasons_to_buffer_json_array_items(RRD_FLAGS flags, BUFFER *wb);
521
522 #define rrdcontext_version_hash(host) rrdcontext_version_hash_with_callback(host, NULL, false, NULL)
523 uint64_t rrdcontext_version_hash_with_callback(
524 RRDHOST *host,
525 void (*callback)(RRDCONTEXT *, bool, void *),
526 bool snapshot,
527 void *bundle);
528
529 void rrdcontext_message_send_unsafe(RRDCONTEXT *rc, bool snapshot __maybe_unused, void *bundle __maybe_unused);
530
531 void rrdcontext_update_from_collected_rrdinstance(RRDINSTANCE *ri);
532
533 void rrdcontext_garbage_collect_single_host(RRDHOST *host, bool worker_jobs);
534
535 void get_metric_retention_by_id(RRDHOST *host, UUIDMAP_ID id, time_t *min_first_time_t, time_t *max_last_time_t, bool *tier0_retention);
536
537 void rrdcontext_delete_after_loading(RRDHOST *host, RRDCONTEXT *rc);
538 void rrdcontext_initial_processing_after_loading(RRDCONTEXT *rc);
539
540 RRDLABELS *rrdinstance_labels(RRDINSTANCE *ri);
541
542 // Bump the dbengine-rotations counter that gates extreme-cardinality
543 // protection. Called from rrdcontext_db_rotation(); the chart-cleanup
544 // trigger (rrdcontext_request_full_gc) deliberately does NOT bump it,
545 // so the guard activates only on real dbengine rotations as before.
546 void rrdcontext_count_db_rotation(void);
547
548 bool rrdcontext_post_process_updates(RRDCONTEXT *rc, bool force, RRD_FLAGS reason, bool worker_jobs);
549 void rrdcontext_post_process_queued_contexts(RRDHOST *host);
550 void rrdcontext_dispatch_queued_contexts_to_hub(RRDHOST *host, usec_t now_ut);
551 usec_t rrdcontext_calculate_queued_dispatch_time_ut(RRDCONTEXT *rc, usec_t now_ut);
552 bool check_if_cloud_version_changed_unsafe(RRDCONTEXT *rc, bool sending);
553 bool rrdcontext_should_be_deleted(RRDCONTEXT *rc);
554 void rrdcontext_delete_from_sql_unsafe(RRDCONTEXT *rc);
555 static inline void rrdcontext_dequeue_from_post_processing(RRDCONTEXT *rc) {
556 rrdcontext_del_from_pp_queue(rc, false);
557 }
558
559 #endif //NETDATA_RRDCONTEXT_INTERNAL_H