summaryrefslogtreecommitdiffstats
path: root/database/rrdfamily.c
diff options
context:
space:
mode:
Diffstat (limited to 'database/rrdfamily.c')
-rw-r--r--database/rrdfamily.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/database/rrdfamily.c b/database/rrdfamily.c
new file mode 100644
index 0000000..f75f0ad
--- /dev/null
+++ b/database/rrdfamily.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#define NETDATA_RRD_INTERNALS
+#include "rrd.h"
+
+// ----------------------------------------------------------------------------
+// RRDFAMILY index
+
+int rrdfamily_compare(void *a, void *b) {
+ if(((RRDFAMILY *)a)->hash_family < ((RRDFAMILY *)b)->hash_family) return -1;
+ else if(((RRDFAMILY *)a)->hash_family > ((RRDFAMILY *)b)->hash_family) return 1;
+ else return strcmp(((RRDFAMILY *)a)->family, ((RRDFAMILY *)b)->family);
+}
+
+#define rrdfamily_index_add(host, rc) (RRDFAMILY *)avl_insert_lock(&((host)->rrdfamily_root_index), (avl *)(rc))
+#define rrdfamily_index_del(host, rc) (RRDFAMILY *)avl_remove_lock(&((host)->rrdfamily_root_index), (avl *)(rc))
+
+static RRDFAMILY *rrdfamily_index_find(RRDHOST *host, const char *id, uint32_t hash) {
+ RRDFAMILY tmp;
+ tmp.family = id;
+ tmp.hash_family = (hash)?hash:simple_hash(tmp.family);
+
+ return (RRDFAMILY *)avl_search_lock(&(host->rrdfamily_root_index), (avl *) &tmp);
+}
+
+RRDFAMILY *rrdfamily_create(RRDHOST *host, const char *id) {
+ RRDFAMILY *rc = rrdfamily_index_find(host, id, 0);
+ if(!rc) {
+ rc = callocz(1, sizeof(RRDFAMILY));
+
+ rc->family = strdupz(id);
+ rc->hash_family = simple_hash(rc->family);
+
+ // initialize the variables index
+ avl_init_lock(&rc->rrdvar_root_index, rrdvar_compare);
+
+ RRDFAMILY *ret = rrdfamily_index_add(host, rc);
+ if(ret != rc)
+ error("RRDFAMILY: INTERNAL ERROR: Expected to INSERT RRDFAMILY '%s' into index, but inserted '%s'.", rc->family, (ret)?ret->family:"NONE");
+ }
+
+ rc->use_count++;
+ return rc;
+}
+
+void rrdfamily_free(RRDHOST *host, RRDFAMILY *rc) {
+ rc->use_count--;
+ if(!rc->use_count) {
+ RRDFAMILY *ret = rrdfamily_index_del(host, rc);
+ if(ret != rc)
+ error("RRDFAMILY: INTERNAL ERROR: Expected to DELETE RRDFAMILY '%s' from index, but deleted '%s'.", rc->family, (ret)?ret->family:"NONE");
+ else {
+ debug(D_RRD_CALLS, "RRDFAMILY: Cleaning up remaining family variables for host '%s', family '%s'", host->hostname, rc->family);
+ rrdvar_free_remaining_variables(host, &rc->rrdvar_root_index);
+
+ freez((void *) rc->family);
+ freez(rc);
+ }
+ }
+}
+