@cryptotaxi247 / netdata-1 / commits / f3ce8bcde

RRDCALC management completed

Costa Tsaousis committed Aug 12, 2016 at 14:04 UTC f3ce8bcde83d2e2fc9c22ab7e49ddf0fb7c0c396
4 files changed +99 -16
src/health.c
+61 -10
@@ -47,7 +47,6 @@ static inline RRDVAR *rrdvar_create(const char *name, uint32_t hash, int type, c
47 static inline void rrdvar_free(RRDHOST *host, RRDVAR *rv) {
48 if(host) {
49 // FIXME: we may need some kind of locking here
50 - // to have mutually exclusive access with eval()
50 EVAL_VARIABLE *rf;
51 for (rf = host->references; rf; rf = rf->next)
52 if (rf->rrdvar == rv) rf->rrdvar = NULL;
@@ -436,7 +435,9 @@ void rrddimvar_free(RRDDIMVAR *rs) {
435
436 // this has to be called while the caller has locked
437 // the RRDHOST
439 -static inline void rrdhostcalc_linked(RRDHOST *host, RRDCALC *rc) {
438 +static inline void rrdset_linked_optimize_rrdhost(RRDHOST *host, RRDCALC *rc) {
439 + rrdhost_check_wrlock(host);
440 +
441 // move it to be last
442
443 if(!rc->next)
@@ -474,7 +475,9 @@ static inline void rrdhostcalc_linked(RRDHOST *host, RRDCALC *rc) {
475
476 // this has to be called while the caller has locked
477 // the RRDHOST
477 -static inline void rrdhostcalc_unlinked(RRDHOST *host, RRDCALC *rc) {
478 +static inline void rrdcalc_unlinked_optimize_rrdhost(RRDHOST *host, RRDCALC *rc) {
479 + rrdhost_check_wrlock(host);
480 +
481 // move it to be first
482
483 if(host->calculations == rc) {
@@ -502,7 +505,15 @@ static void rrdsetcalc_link(RRDSET *st, RRDCALC *rc) {
505 rc->context = rrdvar_create_and_index("context", &st->rrdcontext->variables_root_index, rc->name, rc->hash, RRDVAR_TYPE_CALCULATED, &rc->value);
506 rc->host = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rc->name, rc->hash, RRDVAR_TYPE_CALCULATED, &rc->value);
507
505 - rrdhostcalc_linked(st->rrdhost, rc);
508 + rrdset_linked_optimize_rrdhost(st->rrdhost, rc);
509 +}
510 +
511 +static inline int rrdcalc_is_matching_this_rrdset(RRDCALC *rc, RRDSET *st) {
512 + if((rc->hash_chart == st->hash && !strcmp(rc->name, st->id)) ||
513 + (rc->hash_chart == st->hash_name && !strcmp(rc->name, st->name)))
514 + return 1;
515 +
516 + return 0;
517 }
518
519 // this has to be called while the RRDHOST is locked
@@ -514,10 +525,8 @@ void rrdsetcalc_link_matching(RRDSET *st) {
525 // we stop on the first linked RRDCALC
526 if(rc->rrdset != NULL) break;
527
517 - if((rc->hash_chart == st->hash && !strcmp(rc->name, st->id)) ||
518 - (rc->hash_chart == st->hash_name && !strcmp(rc->name, st->name))) {
528 + if(rrdcalc_is_matching_this_rrdset(rc, st))
529 rrdsetcalc_link(st, rc);
520 - }
530 }
531 }
532
@@ -566,7 +575,7 @@ void rrdsetcalc_unlink(RRDCALC *rc) {
575 // so that if the matching chart is found in the future
576 // it will be applied automatically
577
569 - rrdhostcalc_unlinked(host, rc);
578 + rrdcalc_unlinked_optimize_rrdhost(host, rc);
579 }
580
581 RRDCALC *rrdcalc_create(RRDHOST *host, const char *name, const char *chart, const char *dimensions, int group_method, uint32_t after, uint32_t before, int update_every, uint32_t options) {
@@ -595,13 +604,55 @@ RRDCALC *rrdcalc_create(RRDHOST *host, const char *name, const char *chart, cons
604 rc->hash_chart = simple_hash(rc->chart);
605 }
606
607 + rc->group = group_method;
608 + rc->after = after;
609 + rc->before = before;
610 + rc->update_every = update_every;
611 + rc->options = options;
612 +
613 + // link it to the host
614 + rc->next = host->calculations;
615 + host->calculations = rc;
616 +
617 + // link it to its chart
618 + RRDSET *st;
619 + for(st = host->rrdset_root; st ; st = st->next) {
620 + if(rrdcalc_is_matching_this_rrdset(rc, st)) {
621 + rrdsetcalc_link(st, rc);
622 + break;
623 + }
624 + }
625 +
626 return NULL;
627 }
628
601 -void rrdcalc_free(RRDCALC *rc) {
629 +void rrdcalc_free(RRDHOST *host, RRDCALC *rc) {
630 if(!rc) return;
631
632 + // unlink it from RRDSET
633 if(rc->rrdset) rrdsetcalc_unlink(rc);
634
635 + // unlink it from RRDHOST
636 + if(rc == host->calculations)
637 + host->calculations = rc->next;
638 +
639 + else if(host->calculations) {
640 + RRDCALC *t, *last = host->calculations;
641 +
642 + for(t = last->next; t ; last = t, t = t->next)
643 + if(t == rc) break;
644 +
645 + if(last)
646 + last->next = rc->next;
647 + else
648 + error("Cannot unlink RRDCALC '%s' from RRDHOST '%s': not found", rc->name, host->hostname);
649 + }
650 + else
651 + error("Cannot unlink RRDCALC '%s' from RRDHOST '%s': RRDHOST does not have any calculations", rc->name, host->hostname);
652 +
653 + freez(rc->name);
654 + freez(rc->chart);
655 + freez(rc->dimensions);
656 +
657 freez(rc);
607 -}
\ No newline at end of file
658 +}
src/health.h
+10 -5
@@ -31,6 +31,10 @@ extern int rrdvar_compare(void *a, void *b);
31 #define RRDVAR_TYPE_TOTAL 4
32
33 // the variables as stored in the variables indexes
34 +// there are 3 indexes:
35 +// 1. at each chart (RRDSET.variables_root_index)
36 +// 2. at each context (RRDCONTEXT.variables_root_index)
37 +// 3. at each host (RRDHOST.variables_root_index)
38 typedef struct rrdvar {
39 avl avl;
40
@@ -44,7 +48,7 @@ typedef struct rrdvar {
48 } RRDVAR;
49
50 // variables linked to charts
47 -// We link variables to point the values that are already
51 +// We link variables to point to the values that are already
52 // calculated / processed by the normal data collection process
53 // This means, there will be no speed penalty for using
54 // these variables
@@ -75,7 +79,7 @@ typedef struct rrdsetvar {
79 } RRDSETVAR;
80
81
78 -// variables linked to dimensions
82 +// variables linked to individual dimensions
83 // We link variables to point the values that are already
84 // calculated / processed by the normal data collection process
85 // This means, there will be no speed penalty for using
@@ -125,17 +129,17 @@ typedef struct rrddimvar {
129 struct rrddimvar *next;
130 } RRDDIMVAR;
131
128 -// additional calculated variables
132 +// calculated variables (defined in health configuration)
133 // These aggregate time-series data at fixed intervals
134 // (defined in their update_every member below)
135 // These increase the overhead of netdata.
136 //
137 // These calculations are allocated and linked (->next)
134 -// to RRDHOST.
138 +// under RRDHOST.
139 // Then are also linked to RRDSET (of course only when the
140 // chart is found, via ->rrdset_next and ->rrdset_prev).
141 // This double-linked list is maintained sorted at all times
138 -// having as RRDSET->calculations the RRDCALC to be processed
142 +// having as RRDSET.calculations the RRDCALC to be processed
143 // next.
144 typedef struct rrdcalc {
145 char *name;
@@ -192,6 +196,7 @@ typedef struct rrdcalctemplate {
196 struct rrdcalctemplate *next;
197 } RRDCALCTEMPLATE;
198
199 +
200 #include "rrd.h"
201
202 extern void rrdsetvar_rename_all(RRDSET *st);
src/rrd.c
+21
@@ -18,6 +18,9 @@ static int rrdset_compare(void* a, void* b);
18 static int rrdset_compare_name(void* a, void* b);
19 static int rrdcontext_compare(void* a, void* b);
20
21 +// ----------------------------------------------------------------------------
22 +// RRDHOST
23 +
24 RRDHOST localhost = {
25 .hostname = "localhost",
26 .rrdset_root = NULL,
@@ -40,6 +43,24 @@ RRDHOST localhost = {
43 }
44 };
45
46 +void rrdhost_rwlock(RRDHOST *host) {
47 + pthread_rwlock_wrlock(&host->rrdset_root_rwlock);
48 +}
49 +
50 +void rrdhost_rdlock(RRDHOST *host) {
51 + pthread_rwlock_rdlock(&host->rrdset_root_rwlock);
52 +}
53 +
54 +void rrdhost_unlock(RRDHOST *host) {
55 + pthread_rwlock_unlock(&host->rrdset_root_rwlock);
56 +}
57 +
58 +void rrdhost_check_wrlock_int(RRDHOST *host, const char *file, const char *function, const unsigned long line) {
59 + if(pthread_rwlock_tryrdlock(&host->rrdset_root_rwlock) == 0) {
60 + fatal("RRDHOST '%s' should be write-locked, but it is not, at function %s() at line %lu of file '%s'", host->hostname, function, line, file);
61 + }
62 +}
63 +
64 // ----------------------------------------------------------------------------
65 // RRDCONTEXT index
66
src/rrd.h
+7 -1
@@ -304,9 +304,15 @@ struct rrdhost {
304 EVAL_VARIABLE *references;
305 };
306 typedef struct rrdhost RRDHOST;
307 -
307 extern RRDHOST localhost;
308
309 +#ifdef NETDATA_INTERNAL_CHECKS
310 +#define rrdhost_check_wrlock(host) rrdhost_check_wrlock_int(host, __FILE__, __FUNCTION__, __LINE__)
311 +#else
312 +#define rrdhost_check_wrlock(host) (void)0
313 +#endif
314 +extern void rrdhost_check_wrlock_int(RRDHOST *host, const char *file, const char *function, const unsigned long line);
315 +
316 // ----------------------------------------------------------------------------
317 // RRD SET functions
318