]> arthur.barton.de Git - netdata.git/blobdiff - src/registry_person.c
added compile option NETDATA_VERIFY_LOCKS to enable the locks
[netdata.git] / src / registry_person.c
index 1ff8fc639ecc3b7ee26035e32a5f68238522c416..409c76925ba54719cff0fc85c4e75c0753331cbb 100644 (file)
@@ -1,7 +1,7 @@
 #include "registry_internals.h"
 
 // ----------------------------------------------------------------------------
-// PERSON_URL
+// PERSON_URL INDEX
 
 int person_url_compare(void *a, void *b) {
     register uint32_t hash1 = ((REGISTRY_PERSON_URL *)a)->url->hash;
@@ -12,11 +12,8 @@ int person_url_compare(void *a, void *b) {
     else return strcmp(((REGISTRY_PERSON_URL *)a)->url->url, ((REGISTRY_PERSON_URL *)b)->url->url);
 }
 
-#define registry_person_url_index_add(person, rc) (REGISTRY_PERSON_URL *)avl_insert(&((person)->person_urls), (avl *)(rc))
-#define registry_person_url_index_del(person, rc) (REGISTRY_PERSON_URL *)avl_remove(&((person)->person_urls), (avl *)(rc))
-
-REGISTRY_PERSON_URL *registry_person_url_find(REGISTRY_PERSON *p, const char *url) {
-    debug(D_REGISTRY, "Registry: registry_person_url_find('%s', '%s')", p->guid, url);
+inline REGISTRY_PERSON_URL *registry_person_url_index_find(REGISTRY_PERSON *p, const char *url) {
+    debug(D_REGISTRY, "Registry: registry_person_url_index_find('%s', '%s')", p->guid, url);
 
     char buf[sizeof(REGISTRY_URL) + strlen(url)];
 
@@ -30,6 +27,29 @@ REGISTRY_PERSON_URL *registry_person_url_find(REGISTRY_PERSON *p, const char *ur
     return pu;
 }
 
+inline REGISTRY_PERSON_URL *registry_person_url_index_add(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) {
+    debug(D_REGISTRY, "Registry: registry_person_url_index_add('%s', '%s')", p->guid, pu->url->url);
+    REGISTRY_PERSON_URL *tpu = (REGISTRY_PERSON_URL *)avl_insert(&(p->person_urls), (avl *)(pu));
+    if(tpu != pu)
+        error("Registry: registry_person_url_index_add('%s', '%s') already exists as '%s'", p->guid, pu->url->url, tpu->url->url);
+
+    return tpu;
+}
+
+inline REGISTRY_PERSON_URL *registry_person_url_index_del(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) {
+    debug(D_REGISTRY, "Registry: registry_person_url_index_del('%s', '%s')", p->guid, pu->url->url);
+    REGISTRY_PERSON_URL *tpu = (REGISTRY_PERSON_URL *)avl_remove(&(p->person_urls), (avl *)(pu));
+    if(!tpu)
+        error("Registry: registry_person_url_index_del('%s', '%s') deleted nothing", p->guid, pu->url->url);
+    else if(tpu != pu)
+        error("Registry: registry_person_url_index_del('%s', '%s') deleted wrong URL '%s'", p->guid, pu->url->url, tpu->url->url);
+
+    return tpu;
+}
+
+// ----------------------------------------------------------------------------
+// PERSON_URL
+
 REGISTRY_PERSON_URL *registry_person_url_allocate(REGISTRY_PERSON *p, REGISTRY_MACHINE *m, REGISTRY_URL *u, char *name, size_t namelen, time_t when) {
     debug(D_REGISTRY, "registry_person_url_allocate('%s', '%s', '%s'): allocating %zu bytes", p->guid, m->guid, u->url, sizeof(REGISTRY_PERSON_URL) + namelen);
 
@@ -53,22 +73,47 @@ REGISTRY_PERSON_URL *registry_person_url_allocate(REGISTRY_PERSON *p, REGISTRY_M
     registry.persons_urls_memory += sizeof(REGISTRY_PERSON_URL) + namelen;
 
     debug(D_REGISTRY, "registry_person_url_allocate('%s', '%s', '%s'): indexing URL in person", p->guid, m->guid, u->url);
-    registry_person_url_index_add(p, pu);
-
-    registry_url_link(u);
+    REGISTRY_PERSON_URL *tpu = registry_person_url_index_add(p, pu);
+    if(tpu != pu) {
+        error("Registry: Attempted to add duplicate person url '%s' with name '%s' to person '%s'", u->url, name, p->guid);
+        free(pu);
+        pu = tpu;
+    }
+    else
+        registry_url_link(u);
 
     return pu;
 }
 
+void registry_person_url_free(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) {
+    debug(D_REGISTRY, "registry_person_url_free('%s', '%s')", p->guid, pu->url->url);
+
+    REGISTRY_PERSON_URL *tpu = registry_person_url_index_del(p, pu);
+    if(tpu) {
+        registry_url_unlink(tpu->url);
+        tpu->machine->links--;
+        registry.persons_urls_memory -= sizeof(REGISTRY_PERSON_URL) + strlen(tpu->machine_name);
+        freez(tpu);
+    }
+}
+
 // this function is needed to change the name of a PERSON_URL
 REGISTRY_PERSON_URL *registry_person_url_reallocate(REGISTRY_PERSON *p, REGISTRY_MACHINE *m, REGISTRY_URL *u, char *name, size_t namelen, time_t when, REGISTRY_PERSON_URL *pu) {
     debug(D_REGISTRY, "registry_person_url_reallocate('%s', '%s', '%s'): allocating %zu bytes", p->guid, m->guid, u->url, sizeof(REGISTRY_PERSON_URL) + namelen);
 
+    // keep a backup
+    REGISTRY_PERSON_URL pu2 = {
+            .first_t = pu->first_t,
+            .last_t = pu->last_t,
+            .usages = pu->usages,
+            .flags = pu->flags,
+            .machine = pu->machine,
+            .machine_name = ""
+    };
+
     // remove the existing one from the index
-    registry_person_url_index_del(p, pu);
-    registry_url_unlink(pu->url);
-    pu->machine->links--;
-    registry.persons_urls_memory -= sizeof(REGISTRY_PERSON_URL) + strlen(pu->machine_name);
+    registry_person_url_free(p, pu);
+    pu = &pu2;
 
     // allocate a new one
     REGISTRY_PERSON_URL *tpu = registry_person_url_allocate(p, m, u, name, namelen, when);
@@ -77,16 +122,10 @@ REGISTRY_PERSON_URL *registry_person_url_reallocate(REGISTRY_PERSON *p, REGISTRY
     tpu->usages = pu->usages;
     tpu->flags = pu->flags;
 
-    freez(pu);
     return tpu;
 }
 
 
-void registry_person_url_del(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) {
-    debug(D_REGISTRY, "Registry: registry_person_url_del('%s', '%s')", p->guid, pu->url->url);
-    registry_person_url_index_del(p, pu);
-}
-
 // ----------------------------------------------------------------------------
 // PERSON
 
@@ -144,7 +183,7 @@ REGISTRY_PERSON *registry_person_get(const char *person_guid, time_t when) {
     if(person_guid && *person_guid) {
         char buf[GUID_LEN + 1];
         // validate it is a GUID
-        if(unlikely(registry_regenerate_guid(person_guid, buf) == -1))
+        if(unlikely(regenerate_guid(person_guid, buf) == -1))
             info("Registry: person guid '%s' is not a valid guid. Ignoring it.", person_guid);
         else {
             person_guid = buf;
@@ -157,13 +196,26 @@ REGISTRY_PERSON *registry_person_get(const char *person_guid, time_t when) {
     return p;
 }
 
+void registry_person_del(REGISTRY_PERSON *p) {
+    debug(D_REGISTRY, "Registry: registry_person_del('%s'): creating dictionary of urls", p->guid);
+
+    while(p->person_urls.root)
+        registry_person_unlink_from_url(p, (REGISTRY_PERSON_URL *)p->person_urls.root);
+
+    debug(D_REGISTRY, "Registry: deleting person '%s' from persons registry", p->guid);
+    dictionary_del(registry.persons, p->guid);
+
+    debug(D_REGISTRY, "Registry: freeing person '%s'", p->guid);
+    freez(p);
+}
+
 // ----------------------------------------------------------------------------
 // LINKING OF OBJECTS
 
 REGISTRY_PERSON_URL *registry_person_link_to_url(REGISTRY_PERSON *p, REGISTRY_MACHINE *m, REGISTRY_URL *u, char *name, size_t namelen, time_t when) {
     debug(D_REGISTRY, "registry_person_link_to_url('%s', '%s', '%s'): searching for URL in person", p->guid, m->guid, u->url);
 
-    REGISTRY_PERSON_URL *pu = registry_person_url_find(p, u->url);
+    REGISTRY_PERSON_URL *pu = registry_person_url_index_find(p, u->url);
     if(!pu) {
         debug(D_REGISTRY, "registry_person_link_to_url('%s', '%s', '%s'): not found", p->guid, m->guid, u->url);
         pu = registry_person_url_allocate(p, m, u, name, namelen, when);
@@ -207,3 +259,6 @@ REGISTRY_PERSON_URL *registry_person_link_to_url(REGISTRY_PERSON *p, REGISTRY_MA
     return pu;
 }
 
+void registry_person_unlink_from_url(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) {
+    registry_person_url_free(p, pu);
+}