summaryrefslogtreecommitdiffstats
path: root/src/rrdfamily.c
blob: fc203e915b3d7b57c74333a4787644a3431dc20f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#define NETDATA_RRD_INTERNALS 1
#include "common.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->variables_root_index, rrdvar_compare);

        RRDFAMILY *ret = rrdfamily_index_add(host, rc);
        if(ret != rc)
            fatal("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)
            fatal("RRDFAMILY: INTERNAL ERROR: Expected to DELETE RRDFAMILY '%s' from index, but deleted '%s'.", rc->family, (ret)?ret->family:"NONE");

        if(rc->variables_root_index.avl_tree.root != NULL)
            fatal("RRDFAMILY: INTERNAL ERROR: Variables index of RRDFAMILY '%s' that is freed, is not empty.", rc->family);

        freez((void *)rc->family);
        freez(rc);
    }
}