]> arthur.barton.de Git - netdata.git/commitdiff
added context index (to be used for storing context scope variables for health monito...
authorCosta Tsaousis <costa@tsaousis.gr>
Fri, 5 Aug 2016 06:44:00 +0000 (09:44 +0300)
committerCosta Tsaousis <costa@tsaousis.gr>
Fri, 5 Aug 2016 06:44:00 +0000 (09:44 +0300)
src/rrd.c
src/rrd.h

index 5a46fb4e12a7781ca66201ea9f912aa360b0c35f..c7e4917bdbbb40feab9c8d13a4577f8c4b7ca493 100644 (file)
--- a/src/rrd.c
+++ b/src/rrd.c
@@ -37,6 +37,7 @@ int rrd_memory_mode = RRD_MEMORY_MODE_SAVE;
 
 static int rrdset_compare(void* a, void* b);
 static int rrdset_compare_name(void* a, void* b);
+static int rrdcontext_compare(void* a, void* b);
 
 RRDHOST localhost = {
                .hostname = "localhost",
@@ -49,27 +50,81 @@ RRDHOST localhost = {
         .rrdset_root_index_name = {
             { NULL, rrdset_compare_name },
             AVL_LOCK_INITIALIZER
+        },
+        .rrdcontext_root_index = {
+            { NULL, rrdcontext_compare },
+            AVL_LOCK_INITIALIZER
         }
 };
 
+// ----------------------------------------------------------------------------
+// RRDCONTEXT index
+
+static int rrdcontext_compare(void* a, void* b) {
+    if(((RRDCONTEXT *)a)->hash < ((RRDCONTEXT *)b)->hash) return -1;
+    else if(((RRDCONTEXT *)a)->hash > ((RRDCONTEXT *)b)->hash) return 1;
+    else return strcmp(((RRDCONTEXT *)a)->id, ((RRDCONTEXT *)b)->id);
+}
+
+#define rrdcontext_index_add(host, rc) (RRDCONTEXT *)avl_insert_lock(&((host)->rrdcontext_root_index), (avl *)(rc))
+#define rrdcontext_index_del(host, rc) (RRDCONTEXT *)avl_remove_lock(&((host)->rrdcontext_root_index), (avl *)(rc))
+
+static RRDCONTEXT *rrdcontext_index_find(RRDHOST *host, const char *id, uint32_t hash) {
+    RRDCONTEXT tmp;
+    tmp.id = id;
+    tmp.hash = (hash)?hash:simple_hash(tmp.id);
+
+    return (RRDCONTEXT *)avl_search_lock(&(host->rrdcontext_root_index), (avl *) &tmp);
+}
+
+RRDCONTEXT *rrdcontext_create(const char *id) {
+    RRDCONTEXT *rc = rrdcontext_index_find(&localhost, id, 0);
+    if(!rc) {
+        rc = calloc(1, sizeof(RRDCONTEXT));
+        if(!rc) fatal("Cannot allocate RRDCONTEXT memory");
+        rc->id = strdup(id);
+        if(!rc->id) fatal("Cannot allocate RRDCONTEXT.id memory");
+        rc->hash = simple_hash(rc->id);
+        // avl_init_lock(&rc->variables_root_index, compar);
+        RRDCONTEXT *ret = rrdcontext_index_add(&localhost, rc);
+        if(ret != rc)
+            fatal("INTERNAL ERROR: Expected to INSERT RRDCONTEXT '%s' into index, but inserted '%s'.", rc->id, (ret)?ret->id:"NONE");
+    }
+
+    rc->use_count++;
+    return rc;
+}
+
+void rrdcontext_free(RRDCONTEXT *rc) {
+    rc->use_count--;
+    if(!rc->use_count) {
+        RRDCONTEXT *ret = rrdcontext_index_del(&localhost, rc);
+        if(ret != rc)
+            fatal("INTERNAL ERROR: Expected to DELETE RRDCONTEXT '%s' from index, but deleted '%s'.", rc->id, (ret)?ret->id:"NONE");
+
+        free((void *)rc->id);
+        free(rc);
+    }
+}
+
 // ----------------------------------------------------------------------------
 // RRDSET index
 
 static int rrdset_compare(void* a, void* b) {
-       if(((RRDSET *)a)->hash < ((RRDSET *)b)->hash) return -1;
-       else if(((RRDSET *)a)->hash > ((RRDSET *)b)->hash) return 1;
-       else return strcmp(((RRDSET *)a)->id, ((RRDSET *)b)->id);
+    if(((RRDSET *)a)->hash < ((RRDSET *)b)->hash) return -1;
+    else if(((RRDSET *)a)->hash > ((RRDSET *)b)->hash) return 1;
+    else return strcmp(((RRDSET *)a)->id, ((RRDSET *)b)->id);
 }
 
-#define rrdset_index_add(host, st) avl_insert_lock(&((host)->rrdset_root_index), (avl *)(st))
-#define rrdset_index_del(host, st) avl_remove_lock(&((host)->rrdset_root_index), (avl *)(st))
+#define rrdset_index_add(host, st) (RRDSET *)avl_insert_lock(&((host)->rrdset_root_index), (avl *)(st))
+#define rrdset_index_del(host, st) (RRDSET *)avl_remove_lock(&((host)->rrdset_root_index), (avl *)(st))
 
 static RRDSET *rrdset_index_find(RRDHOST *host, const char *id, uint32_t hash) {
-       RRDSET tmp;
-       strncpyz(tmp.id, id, RRD_ID_LENGTH_MAX);
-       tmp.hash = (hash)?hash:simple_hash(tmp.id);
+    RRDSET tmp;
+    strncpyz(tmp.id, id, RRD_ID_LENGTH_MAX);
+    tmp.hash = (hash)?hash:simple_hash(tmp.id);
 
-       return (RRDSET *)avl_search_lock(&(host->rrdset_root_index), (avl *) &tmp);
+    return (RRDSET *)avl_search_lock(&(host->rrdset_root_index), (avl *) &tmp);
 }
 
 // ----------------------------------------------------------------------------
@@ -89,11 +144,20 @@ static int rrdset_compare_name(void* a, void* b) {
 }
 
 RRDSET *rrdset_index_add_name(RRDHOST *host, RRDSET *st) {
+    void *result;
        // fprintf(stderr, "ADDING: %s (name: %s)\n", st->id, st->name);
-       return (RRDSET *)avl_insert_lock(&host->rrdset_root_index_name, (avl *) (&st->avlname));
+       result = avl_insert_lock(&host->rrdset_root_index_name, (avl *) (&st->avlname));
+    if(result) return rrdset_from_avlname(result);
+    return NULL;
 }
 
-#define rrdset_index_del_name(host, st) avl_remove_lock(&((host)->rrdset_root_index_name), (avl *)(&st->avlname))
+RRDSET *rrdset_index_del_name(RRDHOST *host, RRDSET *st) {
+    void *result;
+    // fprintf(stderr, "DELETING: %s (name: %s)\n", st->id, st->name);
+    return (RRDSET *)avl_remove_lock(&((host)->rrdset_root_index_name), (avl *)(&st->avlname));
+    if(result) return rrdset_from_avlname(result);
+    return NULL;
+}
 
 static RRDSET *rrdset_index_find_name(RRDHOST *host, const char *name, uint32_t hash) {
        void *result = NULL;
@@ -465,6 +529,8 @@ RRDSET *rrdset_create(const char *type, const char *id, const char *name, const
 
        rrdset_index_add(&localhost, st);
 
+    st->rrdcontext = rrdcontext_create(st->context);
+
        pthread_rwlock_unlock(&localhost.rrdset_root_rwlock);
 
        return(st);
@@ -660,6 +726,10 @@ void rrdset_free_all(void)
 
                rrdset_index_del(&localhost, st);
 
+        st->rrdcontext->use_count--;
+        if(!st->rrdcontext->use_count)
+            rrdcontext_free(st->rrdcontext);
+
                if(st->mapped == RRD_MEMORY_MODE_SAVE) {
                        debug(D_RRD_CALLS, "Saving stats '%s' to '%s'.", st->name, st->cache_filename);
                        savememory(st->cache_filename, st, st->memsize);
index 78ad7e87c965f2123872604591f2dd6ca705c7c2..b291bdcac8a970ac959cc60bc2b0058c5e03667f 100644 (file)
--- a/src/rrd.h
+++ b/src/rrd.h
@@ -22,7 +22,7 @@ extern int rrd_delete_unupdated_dimensions;
 
 #define RRD_ID_LENGTH_MAX 1024
 
-#define RRDSET_MAGIC           "NETDATA RRD SET FILE V017"
+#define RRDSET_MAGIC           "NETDATA RRD SET FILE V018"
 #define RRDDIMENSION_MAGIC     "NETDATA RRD DIMENSION FILE V017"
 
 typedef long long total_number;
@@ -82,6 +82,21 @@ extern const char *rrddim_algorithm_name(int chart_type);
 #define RRDDIM_FLAG_HIDDEN 0x00000001 // this dimension will not be offered to callers
 #define RRDDIM_FLAG_DONT_DETECT_RESETS_OR_OVERFLOWS 0x00000002 // do not offer RESET or OVERFLOW info to callers
 
+// ----------------------------------------------------------------------------
+// RRD CONTEXT
+
+struct rrdcontext {
+    avl avl;
+
+    const char *id;
+    uint32_t hash;
+
+    size_t use_count;
+
+    // avl_tree_lock variables_root_index;
+};
+typedef struct rrdcontext RRDCONTEXT;
+
 // ----------------------------------------------------------------------------
 // RRD DIMENSION
 
@@ -237,6 +252,7 @@ struct rrdset {
        total_number collected_total;                                   // used internally to calculate percentages
        total_number last_collected_total;                              // used internally to calculate percentages
 
+    RRDCONTEXT *rrdcontext;
        struct rrdset *next;                                                    // linking of rrdsets
 
        // ------------------------------------------------------------------------
@@ -254,21 +270,12 @@ struct rrdset {
 };
 typedef struct rrdset RRDSET;
 
-// ----------------------------------------------------------------------------
-// RRD CONTEXT
-
-struct rrdcontext {
-    avl avl;
-
-    char *context;
-};
-typedef struct rrdcontext RRDCONTEXT;
-
-
 // ----------------------------------------------------------------------------
 // RRD HOST
 
 struct rrdhost {
+    avl avl;
+
     char *hostname;
 
     RRDSET *rrdset_root;
@@ -276,6 +283,9 @@ struct rrdhost {
 
     avl_tree_lock rrdset_root_index;
     avl_tree_lock rrdset_root_index_name;
+
+    avl_tree_lock rrdcontext_root_index;
+    // avl_tree_lock variables_root_index;
 };
 typedef struct rrdhost RRDHOST;