]> arthur.barton.de Git - netdata.git/blob - src/registry_url.c
Merge pull request #1998 from ktsaou/master
[netdata.git] / src / registry_url.c
1 #include "registry_internals.h"
2
3 // ----------------------------------------------------------------------------
4 // REGISTRY_URL
5
6 int registry_url_compare(void *a, void *b) {
7     if(((REGISTRY_URL *)a)->hash < ((REGISTRY_URL *)b)->hash) return -1;
8     else if(((REGISTRY_URL *)a)->hash > ((REGISTRY_URL *)b)->hash) return 1;
9     else return strcmp(((REGISTRY_URL *)a)->url, ((REGISTRY_URL *)b)->url);
10 }
11
12 inline REGISTRY_URL *registry_url_index_add(REGISTRY_URL *u) {
13     return (REGISTRY_URL *)avl_insert(&(registry.registry_urls_root_index), (avl *)(u));
14 }
15
16 inline REGISTRY_URL *registry_url_index_del(REGISTRY_URL *u) {
17     return (REGISTRY_URL *)avl_remove(&(registry.registry_urls_root_index), (avl *)(u));
18 }
19
20 REGISTRY_URL *registry_url_get(const char *url, size_t urllen) {
21     // protection from too big URLs
22     if(urllen > registry.max_url_length)
23         urllen = registry.max_url_length;
24
25     debug(D_REGISTRY, "Registry: registry_url_get('%s', %zu)", url, urllen);
26
27     char buf[sizeof(REGISTRY_URL) + urllen]; // no need for +1, 1 is already in REGISTRY_URL
28     REGISTRY_URL *n = (REGISTRY_URL *)&buf[0];
29     n->len = (uint16_t)urllen;
30     strncpyz(n->url, url, n->len);
31     n->hash = simple_hash(n->url);
32
33     REGISTRY_URL *u = (REGISTRY_URL *)avl_search(&(registry.registry_urls_root_index), (avl *)n);
34     if(!u) {
35         debug(D_REGISTRY, "Registry: registry_url_get('%s', %zu): allocating %zu bytes", url, urllen, sizeof(REGISTRY_URL) + urllen);
36         u = callocz(1, sizeof(REGISTRY_URL) + urllen); // no need for +1, 1 is already in REGISTRY_URL
37
38         // a simple strcpy() should do the job
39         // but I prefer to be safe, since the caller specified urllen
40         u->len = (uint16_t)urllen;
41         strncpyz(u->url, url, u->len);
42         u->links = 0;
43         u->hash = simple_hash(u->url);
44
45         registry.urls_memory += sizeof(REGISTRY_URL) + urllen; // no need for +1, 1 is already in REGISTRY_URL
46
47         debug(D_REGISTRY, "Registry: registry_url_get('%s'): indexing it", url);
48         n = registry_url_index_add(u);
49         if(n != u) {
50             error("INTERNAL ERROR: registry_url_get(): url '%s' already exists in the registry as '%s'", u->url, n->url);
51             free(u);
52             u = n;
53         }
54         else
55             registry.urls_count++;
56     }
57
58     return u;
59 }
60
61 void registry_url_link(REGISTRY_URL *u) {
62     u->links++;
63     debug(D_REGISTRY, "Registry: registry_url_link('%s'): URL has now %u links", u->url, u->links);
64 }
65
66 void registry_url_unlink(REGISTRY_URL *u) {
67     u->links--;
68     if(!u->links) {
69         debug(D_REGISTRY, "Registry: registry_url_unlink('%s'): No more links for this URL", u->url);
70         REGISTRY_URL *n = registry_url_index_del(u);
71         if(!n) {
72             error("INTERNAL ERROR: registry_url_unlink('%s'): cannot find url in index", u->url);
73         }
74         else {
75             if(n != u) {
76                 error("INTERNAL ERROR: registry_url_unlink('%s'): deleted different url '%s'", u->url, n->url);
77             }
78
79             registry.urls_memory -= sizeof(REGISTRY_URL) + n->len; // no need for +1, 1 is already in REGISTRY_URL
80             freez(n);
81         }
82     }
83     else
84         debug(D_REGISTRY, "Registry: registry_url_unlink('%s'): URL has %u links left", u->url, u->links);
85 }