From: Sebastian Harl Date: Thu, 18 Jul 2013 01:50:27 +0000 (-0700) Subject: Let objects be named. X-Git-Tag: sysdb-0.1.0~403 X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=commitdiff_plain;h=1fee763a36a0c9af761244bbce8cd6c233ddbe2a Let objects be named. This allows to move common code into helper functions. The objects module now provides a function to compare two objects by name and linked-lists support to lookup objects by name now. This removes the need for various custom and somewhat ugly helper functions and data-types. --- diff --git a/src/backend/collectd/unixsock.c b/src/backend/collectd/unixsock.c index 9457739..c9b46db 100644 --- a/src/backend/collectd/unixsock.c +++ b/src/backend/collectd/unixsock.c @@ -69,7 +69,7 @@ sdb_collectd_add_host(const char *hostname, sdb_time_t last_update) strncpy(name, hostname, sizeof(name)); - host._name = name; + SDB_OBJ(&host)->name = name; host._last_update = last_update; status = sdb_store_host(&host); @@ -102,7 +102,7 @@ sdb_collectd_add_svc(const char *hostname, const char *plugin, snprintf(name, sizeof(name), "%s/%s", plugin, type); svc.hostname = host; - svc._name = name; + SDB_OBJ(&svc)->name = name; svc._last_update = last_update; status = sdb_store_service(&svc); @@ -341,7 +341,7 @@ sdb_collectd_config_instance(oconfig_item_t *ci) return -1; } - user_data = sdb_object_create_wrapper(client, + user_data = sdb_object_create_wrapper("unixsock-client", client, (void (*)(void *))sdb_unixsock_client_destroy); if (! user_data) { sdb_unixsock_client_destroy(client); diff --git a/src/backend/mk-livestatus.c b/src/backend/mk-livestatus.c index e151b52..dea6794 100644 --- a/src/backend/mk-livestatus.c +++ b/src/backend/mk-livestatus.c @@ -66,7 +66,7 @@ sdb_livestatus_get_host(sdb_unixsock_client_t __attribute__((unused)) *client, hostname = strdup(data[0].data.string); timestamp = data[1].data.datetime; - host._name = hostname; + SDB_OBJ(&host)->name = hostname; host._last_update = timestamp; status = sdb_store_host(&host); @@ -110,7 +110,7 @@ sdb_livestatus_get_svc(sdb_unixsock_client_t __attribute__((unused)) *client, timestamp = data[2].data.datetime; svc.hostname = hostname; - svc._name = svcname; + SDB_OBJ(&svc)->name = svcname; svc._last_update = timestamp; status = sdb_store_service(&svc); @@ -282,7 +282,7 @@ sdb_livestatus_config_instance(oconfig_item_t *ci) return -1; } - user_data = sdb_object_create_wrapper(client, + user_data = sdb_object_create_wrapper("unixsock-client", client, (void (*)(void *))sdb_unixsock_client_destroy); if (! user_data) { sdb_unixsock_client_destroy(client); diff --git a/src/backend/puppet/store-configs.c b/src/backend/puppet/store-configs.c index 8b3804b..bde8a0a 100644 --- a/src/backend/puppet/store-configs.c +++ b/src/backend/puppet/store-configs.c @@ -60,22 +60,22 @@ sdb_puppet_stcfg_get_hosts(sdb_dbi_client_t __attribute__((unused)) *client, assert((data[0].type == SDB_TYPE_STRING) && (data[1].type == SDB_TYPE_DATETIME)); - host._name = strdup(data[0].data.string); + SDB_OBJ(&host)->name = strdup(data[0].data.string); host._last_update = data[1].data.datetime; status = sdb_store_host(&host); if (status < 0) { sdb_log(SDB_LOG_ERR, "puppet::store-configs backend: Failed to " - "store/update host '%s'.", host._name); - free(host._name); + "store/update host '%s'.", SDB_OBJ(&host)->name); + free(SDB_OBJ(&host)->name); return -1; } else if (! status) sdb_log(SDB_LOG_DEBUG, "puppet::store-configs backend: " "Added/updated host '%s' (last update timestamp = " - "%"PRIscTIME").", host._name, host._last_update); - free(host._name); + "%"PRIscTIME").", SDB_OBJ(&host)->name, host._last_update); + free(SDB_OBJ(&host)->name); return 0; } /* sdb_puppet_stcfg_get_hosts */ @@ -95,7 +95,7 @@ sdb_puppet_stcfg_get_attrs(sdb_dbi_client_t __attribute__((unused)) *client, && (data[3].type == SDB_TYPE_DATETIME)); attr.hostname = strdup(data[0].data.string); - attr._name = strdup(data[1].data.string); + SDB_OBJ(&attr)->name = strdup(data[1].data.string); attr.attr_value = strdup(data[2].data.string); attr._last_update = data[3].data.datetime; @@ -104,15 +104,15 @@ sdb_puppet_stcfg_get_attrs(sdb_dbi_client_t __attribute__((unused)) *client, if (status < 0) { sdb_log(SDB_LOG_ERR, "puppet::store-configs backend: Failed to " "store/update host attribute '%s' for host '%s'.", - attr._name, attr.hostname); + SDB_OBJ(&attr)->name, attr.hostname); free(attr.hostname); - free(attr._name); + free(SDB_OBJ(&attr)->name); free(attr.attr_value); return -1; } free(attr.hostname); - free(attr._name); + free(SDB_OBJ(&attr)->name); free(attr.attr_value); return 0; } /* sdb_puppet_stcfg_get_attrs */ @@ -323,7 +323,7 @@ sdb_puppet_stcfg_config_conn(oconfig_item_t *ci) sdb_dbi_client_set_options(client, options); - user_data = sdb_object_create_wrapper(client, + user_data = sdb_object_create_wrapper("dbi-client", client, (void (*)(void *))sdb_dbi_client_destroy); if (! user_data) { sdb_dbi_client_destroy(client); diff --git a/src/core/object.c b/src/core/object.c index 65b256f..7fbd5f0 100644 --- a/src/core/object.c +++ b/src/core/object.c @@ -75,17 +75,26 @@ static sdb_type_t sdb_object_wrapper_type = { */ sdb_object_t * -sdb_object_create(sdb_type_t type, ...) +sdb_object_create(const char *name, sdb_type_t type, ...) { sdb_object_t *obj; - if (type.size <= 0) + if (type.size <= sizeof(sdb_object_t)) return NULL; obj = malloc(type.size); if (! obj) return NULL; - memset(obj, 0, sizeof(*obj)); + memset(obj, 0, type.size); + + if (name) { + obj->name = strdup(name); + if (! obj->name) { + obj->ref_cnt = 1; + sdb_object_deref(obj); + return NULL; + } + } if (type.init) { va_list ap; @@ -107,9 +116,10 @@ sdb_object_create(sdb_type_t type, ...) } /* sdb_object_create */ sdb_object_t * -sdb_object_create_wrapper(void *data, void (*destructor)(void *)) +sdb_object_create_wrapper(const char *name, + void *data, void (*destructor)(void *)) { - return sdb_object_create(sdb_object_wrapper_type, data, destructor); + return sdb_object_create(name, sdb_object_wrapper_type, data, destructor); } /* sdb_object_create_wrapper */ void @@ -125,6 +135,8 @@ sdb_object_deref(sdb_object_t *obj) if (obj->type.destroy) obj->type.destroy(obj); + if (obj->name) + free(obj->name); free(obj); } /* sdb_object_deref */ @@ -145,5 +157,18 @@ sdb_object_clone(const sdb_object_t *obj) return obj->type.clone(obj); } /* sdb_object_clone */ +int +sdb_object_cmp_by_name(const sdb_object_t *o1, const sdb_object_t *o2) +{ + if ((! o1) && (! o2)) + return 0; + else if (! o1) + return -1; + else if (! o2) + return 1; + + return strcasecmp(o1->name, o2->name); +} /* sdb_object_cmp_by_name */ + /* vim: set tw=78 sw=4 ts=4 noexpandtab : */ diff --git a/src/core/plugin.c b/src/core/plugin.c index f502582..f771d70 100644 --- a/src/core/plugin.c +++ b/src/core/plugin.c @@ -65,18 +65,16 @@ struct sdb_plugin_info { typedef struct { sdb_object_t super; - char cb_name[64]; void *cb_callback; sdb_object_t *cb_user_data; sdb_plugin_ctx_t cb_ctx; } sdb_plugin_cb_t; -#define SDB_PLUGIN_CB_INIT { SDB_OBJECT_INIT, /* name = */ "", \ +#define SDB_PLUGIN_CB_INIT { SDB_OBJECT_INIT, \ /* callback = */ NULL, /* user_data = */ NULL, \ SDB_PLUGIN_CTX_INIT } typedef struct { sdb_plugin_cb_t super; -#define ccb_name super.cb_name #define ccb_callback super.cb_callback #define ccb_user_data super.cb_user_data #define ccb_ctx super.cb_ctx @@ -141,16 +139,6 @@ sdb_plugin_ctx_create(void) return ctx; } /* sdb_plugin_ctx_create */ -static int -sdb_plugin_cmp_name(const sdb_object_t *a, const sdb_object_t *b) -{ - const sdb_plugin_cb_t *cb1 = (const sdb_plugin_cb_t *)a; - const sdb_plugin_cb_t *cb2 = (const sdb_plugin_cb_t *)b; - - assert(cb1 && cb2); - return strcasecmp(cb1->cb_name, cb2->cb_name); -} /* sdb_plugin_cmp_name */ - static int sdb_plugin_cmp_next_update(const sdb_object_t *a, const sdb_object_t *b) { @@ -169,7 +157,7 @@ sdb_plugin_cmp_next_update(const sdb_object_t *a, const sdb_object_t *b) static sdb_plugin_cb_t * sdb_plugin_find_by_name(sdb_llist_t *list, const char *name) { - sdb_plugin_cb_t tmp = SDB_PLUGIN_CB_INIT; + sdb_object_t tmp = SDB_OBJECT_INIT; sdb_object_t *obj; assert(name); @@ -177,9 +165,11 @@ sdb_plugin_find_by_name(sdb_llist_t *list, const char *name) if (! list) return NULL; - snprintf(tmp.cb_name, sizeof(tmp.cb_name), "%s", name); - tmp.cb_name[sizeof(tmp.cb_name) - 1] = '\0'; - obj = sdb_llist_search(list, SDB_OBJ(&tmp), sdb_plugin_cmp_name); + tmp.name = strdup(name); + if (! tmp.name) + return NULL; + obj = sdb_llist_search(list, &tmp, sdb_object_cmp_by_name); + free(tmp.name); if (! obj) return NULL; return SDB_PLUGIN_CB(obj); @@ -193,26 +183,21 @@ static int sdb_plugin_cb_init(sdb_object_t *obj, va_list ap) { sdb_llist_t **list = va_arg(ap, sdb_llist_t **); - const char *type = va_arg(ap, const char *); - const char *name = va_arg(ap, const char *); - void *callback = va_arg(ap, void *); + const char *type = va_arg(ap, const char *); + void *callback = va_arg(ap, void *); sdb_object_t *ud = va_arg(ap, sdb_object_t *); assert(list); assert(type); assert(obj); - if (sdb_plugin_find_by_name(*list, name)) { + if (sdb_plugin_find_by_name(*list, obj->name)) { sdb_log(SDB_LOG_WARNING, "plugin: %s callback '%s' " "has already been registered. Ignoring newly " - "registered version.", type, name); + "registered version.", type, obj->name); return -1; } - snprintf(SDB_PLUGIN_CB(obj)->cb_name, - sizeof(SDB_PLUGIN_CB(obj)->cb_name), - "%s", name); - SDB_PLUGIN_CB(obj)->cb_name[sizeof(SDB_PLUGIN_CB(obj)->cb_name) - 1] = '\0'; SDB_PLUGIN_CB(obj)->cb_callback = callback; SDB_PLUGIN_CB(obj)->cb_ctx = sdb_plugin_get_ctx(); @@ -260,8 +245,8 @@ sdb_plugin_add_callback(sdb_llist_t **list, const char *type, if (! *list) return -1; - obj = sdb_object_create(sdb_plugin_cb_type, - list, type, name, callback, user_data); + obj = sdb_object_create(name, sdb_plugin_cb_type, + list, type, callback, user_data); if (! obj) return -1; @@ -464,8 +449,8 @@ sdb_plugin_register_collector(const char *name, sdb_plugin_collector_cb callback if (! collector_list) return -1; - obj = sdb_object_create(sdb_plugin_collector_cb_type, - &collector_list, "collector", name, callback, user_data); + obj = sdb_object_create(name, sdb_plugin_collector_cb_type, + &collector_list, "collector", callback, user_data); if (! obj) return -1; @@ -654,7 +639,7 @@ sdb_plugin_collector_loop(sdb_plugin_loop_t *loop) if (! interval) { sdb_log(SDB_LOG_WARNING, "plugin: No interval configured " "for plugin '%s'; skipping any further " - "iterations.", SDB_PLUGIN_CCB(obj)->ccb_name); + "iterations.", obj->name); sdb_object_deref(obj); continue; } @@ -671,7 +656,7 @@ sdb_plugin_collector_loop(sdb_plugin_loop_t *loop) if (now > SDB_PLUGIN_CCB(obj)->ccb_next_update) { sdb_log(SDB_LOG_WARNING, "plugin: Plugin '%s' took too " "long; skipping iterations to keep up.", - SDB_PLUGIN_CCB(obj)->ccb_name); + obj->name); SDB_PLUGIN_CCB(obj)->ccb_next_update = now; } @@ -680,7 +665,7 @@ sdb_plugin_collector_loop(sdb_plugin_loop_t *loop) sdb_log(SDB_LOG_ERR, "plugin: Failed to re-insert " "plugin '%s' into collector list. Unable to further " "use the plugin.", - SDB_PLUGIN_CCB(obj)->ccb_name); + obj->name); sdb_object_deref(obj); return -1; } diff --git a/src/core/store.c b/src/core/store.c index 4ec9f44..c66b523 100644 --- a/src/core/store.c +++ b/src/core/store.c @@ -40,17 +40,6 @@ #include -/* - * private data types - */ - -/* type used for looking up named objects */ -typedef struct { - sdb_object_t parent; - const char *obj_name; -} sdb_store_lookup_obj_t; -#define SDB_STORE_LOOKUP_OBJ_INIT { SDB_OBJECT_INIT, NULL } - /* * private variables */ @@ -58,43 +47,13 @@ typedef struct { static sdb_llist_t *host_list = NULL; static pthread_rwlock_t host_lock = PTHREAD_RWLOCK_INITIALIZER; -/* - * private helper functions - */ - -static int -sdb_store_obj_cmp_by_name(const sdb_object_t *a, const sdb_object_t *b) -{ - const sdb_store_obj_t *h1 = (const sdb_store_obj_t *)a; - const sdb_store_obj_t *h2 = (const sdb_store_obj_t *)b; - - assert(h1 && h2); - return strcasecmp(h1->name, h2->name); -} /* sdb_store_obj_cmp_by_name */ - -static int -sdb_cmp_store_obj_with_name(const sdb_object_t *a, const sdb_object_t *b) -{ - const sdb_store_obj_t *obj = (const sdb_store_obj_t *)a; - const sdb_store_lookup_obj_t *lookup = (const sdb_store_lookup_obj_t *)b; - - assert(obj && lookup); - return strcasecmp(obj->name, lookup->obj_name); -} /* sdb_cmp_store_obj_with_name */ - /* * public types */ static int -sdb_host_init(sdb_object_t *obj, va_list ap) +sdb_host_init(sdb_object_t *obj, va_list __attribute__((unused)) ap) { - const char *name = va_arg(ap, const char *); - - SDB_HOST(obj)->_name = strdup(name); - if (! SDB_HOST(obj)->_name) - return -1; - SDB_HOST(obj)->_last_update = sdb_gettime(); /* ignore errors -> last_update will be updated later */ @@ -112,9 +71,6 @@ sdb_host_destroy(sdb_object_t *obj) { assert(obj); - if (SDB_HOST(obj)->_name) - free(SDB_HOST(obj)->_name); - if (SDB_HOST(obj)->attributes) sdb_llist_destroy(SDB_HOST(obj)->attributes); if (SDB_HOST(obj)->services) @@ -127,7 +83,7 @@ sdb_host_do_clone(const sdb_object_t *obj) const sdb_host_t *host = (const sdb_host_t *)obj; sdb_host_t *new; - new = sdb_host_create(host->_name); + new = sdb_host_create(obj->name); if (! new) return NULL; @@ -158,14 +114,11 @@ static int sdb_attr_init(sdb_object_t *obj, va_list ap) { const char *hostname = va_arg(ap, const char *); - const char *name = va_arg(ap, const char *); const char *value = va_arg(ap, const char *); SDB_ATTR(obj)->hostname = strdup(hostname); - SDB_ATTR(obj)->_name = strdup(name); SDB_ATTR(obj)->attr_value = strdup(value); - if ((! SDB_ATTR(obj)->hostname) - || (! SDB_ATTR(obj)->_name) || (! SDB_ATTR(obj)->attr_value)) + if ((! SDB_ATTR(obj)->hostname) || (! SDB_ATTR(obj)->attr_value)) return -1; SDB_ATTR(obj)->_last_update = sdb_gettime(); @@ -179,8 +132,6 @@ sdb_attr_destroy(sdb_object_t *obj) if (SDB_ATTR(obj)->hostname) free(SDB_ATTR(obj)->hostname); - if (SDB_ATTR(obj)->_name) - free(SDB_ATTR(obj)->_name); if (SDB_ATTR(obj)->attr_value) free(SDB_ATTR(obj)->attr_value); } /* sdb_attr_destroy */ @@ -192,7 +143,7 @@ sdb_attr_clone(const sdb_object_t *obj) sdb_attribute_t *new; new = sdb_attribute_create(attr->hostname, - attr->_name, attr->attr_value); + obj->name, attr->attr_value); if (! new) return NULL; @@ -204,11 +155,9 @@ static int sdb_svc_init(sdb_object_t *obj, va_list ap) { const char *hostname = va_arg(ap, const char *); - const char *name = va_arg(ap, const char *); SDB_SVC(obj)->hostname = strdup(hostname); - SDB_SVC(obj)->_name = strdup(name); - if ((! SDB_SVC(obj)->hostname) || (! SDB_SVC(obj)->_name)) + if (! SDB_SVC(obj)->hostname) return -1; SDB_SVC(obj)->_last_update = sdb_gettime(); @@ -223,8 +172,6 @@ sdb_svc_destroy(sdb_object_t *obj) if (SDB_SVC(obj)->hostname) free(SDB_SVC(obj)->hostname); - if (SDB_SVC(obj)->_name) - free(SDB_SVC(obj)->_name); } /* sdb_svc_destroy */ static sdb_object_t * @@ -233,7 +180,7 @@ sdb_svc_clone(const sdb_object_t *obj) const sdb_service_t *svc = (const sdb_service_t *)obj; sdb_service_t *new; - new = sdb_service_create(svc->hostname, svc->_name); + new = sdb_service_create(svc->hostname, obj->name); if (! new) return NULL; @@ -277,7 +224,7 @@ sdb_host_create(const char *name) if (! name) return NULL; - obj = sdb_object_create(sdb_host_type, name); + obj = sdb_object_create(name, sdb_host_type); if (! obj) return NULL; return SDB_HOST(obj); @@ -286,13 +233,11 @@ sdb_host_create(const char *name) int sdb_store_host(const sdb_host_t *host) { - sdb_store_lookup_obj_t lookup = SDB_STORE_LOOKUP_OBJ_INIT; sdb_time_t last_update; - sdb_host_t *old; int status = 0; - if ((! host) || (! host->_name)) + if ((! host) || (! SDB_CONST_OBJ(host)->name)) return -1; last_update = host->_last_update; @@ -308,15 +253,14 @@ sdb_store_host(const sdb_host_t *host) } } - lookup.obj_name = host->_name; - old = SDB_HOST(sdb_llist_search(host_list, (const sdb_object_t *)&lookup, - sdb_cmp_store_obj_with_name)); + old = SDB_HOST(sdb_llist_search_by_name(host_list, + SDB_CONST_OBJ(host)->name)); if (old) { if (old->_last_update > last_update) { sdb_log(SDB_LOG_DEBUG, "store: Cannot update host '%s' - " "value too old (%"PRIscTIME" < %"PRIscTIME")", - host->_name, last_update, old->_last_update); + SDB_CONST_OBJ(host)->name, last_update, old->_last_update); /* don't report an error; the host may be updated by multiple * backends */ status = 1; @@ -339,7 +283,7 @@ sdb_store_host(const sdb_host_t *host) if (! (new->attributes = sdb_llist_create())) { char errbuf[1024]; sdb_log(SDB_LOG_ERR, "store: Failed to initialize " - "host object '%s': %s", host->_name, + "host object '%s': %s", SDB_CONST_OBJ(host)->name, sdb_strerror(errno, errbuf, sizeof(errbuf))); sdb_object_deref(SDB_OBJ(new)); pthread_rwlock_unlock(&host_lock); @@ -351,7 +295,7 @@ sdb_store_host(const sdb_host_t *host) if (! (new->services = sdb_llist_create())) { char errbuf[1024]; sdb_log(SDB_LOG_ERR, "store: Failed to initialize " - "host object '%s': %s", host->_name, + "host object '%s': %s", SDB_CONST_OBJ(host)->name, sdb_strerror(errno, errbuf, sizeof(errbuf))); sdb_object_deref(SDB_OBJ(new)); pthread_rwlock_unlock(&host_lock); @@ -360,7 +304,7 @@ sdb_store_host(const sdb_host_t *host) } status = sdb_llist_insert_sorted(host_list, SDB_OBJ(new), - sdb_store_obj_cmp_by_name); + sdb_object_cmp_by_name); /* pass control to the list or destroy in case of an error */ sdb_object_deref(SDB_OBJ(new)); @@ -373,16 +317,12 @@ sdb_store_host(const sdb_host_t *host) const sdb_host_t * sdb_store_get_host(const char *name) { - sdb_store_lookup_obj_t lookup = SDB_STORE_LOOKUP_OBJ_INIT; sdb_host_t *host; if (! name) return NULL; - lookup.obj_name = name; - host = SDB_HOST(sdb_llist_search(host_list, (const sdb_object_t *)&lookup, - sdb_cmp_store_obj_with_name)); - + host = SDB_HOST(sdb_llist_search_by_name(host_list, name)); if (! host) return NULL; return host; @@ -397,7 +337,7 @@ sdb_attribute_create(const char *hostname, if ((! hostname) || (! name) || (! value)) return NULL; - obj = sdb_object_create(sdb_attribute_type, hostname, name, value); + obj = sdb_object_create(name, sdb_attribute_type, hostname, value); if (! obj) return NULL; return SDB_ATTR(obj); @@ -406,11 +346,8 @@ sdb_attribute_create(const char *hostname, int sdb_store_attribute(const sdb_attribute_t *attr) { - sdb_store_lookup_obj_t lookup = SDB_STORE_LOOKUP_OBJ_INIT; sdb_host_t *host; - sdb_attribute_t *old; - sdb_time_t last_update; int status = 0; @@ -427,25 +364,19 @@ sdb_store_attribute(const sdb_attribute_t *attr) pthread_rwlock_wrlock(&host_lock); - lookup.obj_name = attr->hostname; - host = SDB_HOST(sdb_llist_search(host_list, (const sdb_object_t *)&lookup, - sdb_cmp_store_obj_with_name)); - + host = SDB_HOST(sdb_llist_search_by_name(host_list, attr->hostname)); if (! host) { pthread_rwlock_unlock(&host_lock); return -1; } - lookup.obj_name = attr->_name; - old = SDB_ATTR(sdb_llist_search(host->attributes, - (const sdb_object_t *)&lookup, - sdb_cmp_store_obj_with_name)); - + old = SDB_ATTR(sdb_llist_search_by_name(host->attributes, + SDB_CONST_OBJ(attr)->name)); if (old) { if (old->_last_update > last_update) { sdb_log(SDB_LOG_DEBUG, "store: Cannot update attribute " "'%s/%s' - value too old (%"PRIscTIME" < %"PRIscTIME")", - attr->hostname, attr->_name, last_update, + attr->hostname, SDB_CONST_OBJ(attr)->name, last_update, old->_last_update); status = 1; } @@ -464,7 +395,7 @@ sdb_store_attribute(const sdb_attribute_t *attr) } status = sdb_llist_insert_sorted(host->attributes, SDB_OBJ(new), - sdb_store_obj_cmp_by_name); + sdb_object_cmp_by_name); /* pass control to the list or destroy in case of an error */ sdb_object_deref(SDB_OBJ(new)); @@ -482,7 +413,7 @@ sdb_service_create(const char *hostname, const char *name) if ((! hostname) || (! name)) return NULL; - obj = sdb_object_create(sdb_service_type, hostname, name); + obj = sdb_object_create(name, sdb_service_type, hostname); if (! obj) return NULL; return SDB_SVC(obj); @@ -491,11 +422,8 @@ sdb_service_create(const char *hostname, const char *name) int sdb_store_service(const sdb_service_t *svc) { - sdb_store_lookup_obj_t lookup = SDB_STORE_LOOKUP_OBJ_INIT; sdb_host_t *host; - sdb_service_t *old; - sdb_time_t last_update; int status = 0; @@ -512,24 +440,19 @@ sdb_store_service(const sdb_service_t *svc) pthread_rwlock_wrlock(&host_lock); - lookup.obj_name = svc->hostname; - host = SDB_HOST(sdb_llist_search(host_list, (const sdb_object_t *)&lookup, - sdb_cmp_store_obj_with_name)); - + host = SDB_HOST(sdb_llist_search_by_name(host_list, svc->hostname)); if (! host) { pthread_rwlock_unlock(&host_lock); return -1; } - lookup.obj_name = svc->_name; - old = SDB_SVC(sdb_llist_search(host->services, (const sdb_object_t *)&lookup, - sdb_cmp_store_obj_with_name)); - + old = SDB_SVC(sdb_llist_search_by_name(host->services, + SDB_CONST_OBJ(svc)->name)); if (old) { if (old->_last_update > last_update) { sdb_log(SDB_LOG_DEBUG, "store: Cannot update service " "'%s/%s' - value too old (%"PRIscTIME" < %"PRIscTIME")", - svc->hostname, svc->_name, last_update, + svc->hostname, SDB_CONST_OBJ(svc)->name, last_update, old->_last_update); status = 1; } @@ -548,7 +471,7 @@ sdb_store_service(const sdb_service_t *svc) } status = sdb_llist_insert_sorted(host->services, SDB_OBJ(new), - sdb_store_obj_cmp_by_name); + sdb_object_cmp_by_name); /* pass control to the list or destroy in case of an error */ sdb_object_deref(SDB_OBJ(new)); @@ -561,17 +484,12 @@ sdb_store_service(const sdb_service_t *svc) const sdb_service_t * sdb_store_get_service(const sdb_host_t *host, const char *name) { - sdb_store_lookup_obj_t lookup = SDB_STORE_LOOKUP_OBJ_INIT; sdb_service_t *svc; if ((! host) || (! name)) return NULL; - lookup.obj_name = name; - svc = SDB_SVC(sdb_llist_search(host->services, - (const sdb_object_t *)&lookup, - sdb_cmp_store_obj_with_name)); - + svc = SDB_SVC(sdb_llist_search_by_name(host->services, name)); if (! svc) return NULL; return svc; @@ -608,7 +526,7 @@ sdb_store_dump(FILE *fh) time_str[sizeof(time_str) - 1] = '\0'; fprintf(fh, "Host '%s' (last updated: %s):\n", - host->_name, time_str); + SDB_OBJ(host)->name, time_str); attr_iter = sdb_llist_get_iter(host->attributes); if (! attr_iter) { @@ -628,7 +546,7 @@ sdb_store_dump(FILE *fh) time_str[sizeof(time_str) - 1] = '\0'; fprintf(fh, "\tAttribute '%s' -> '%s' (last updated: %s)\n", - attr->_name, attr->attr_value, time_str); + SDB_OBJ(attr)->name, attr->attr_value, time_str); } sdb_llist_iter_destroy(attr_iter); @@ -651,7 +569,7 @@ sdb_store_dump(FILE *fh) time_str[sizeof(time_str) - 1] = '\0'; fprintf(fh, "\tService '%s' (last updated: %s)\n", - svc->_name, time_str); + SDB_OBJ(svc)->name, time_str); } sdb_llist_iter_destroy(svc_iter); diff --git a/src/include/core/object.h b/src/include/core/object.h index 2f46610..016e718 100644 --- a/src/include/core/object.h +++ b/src/include/core/object.h @@ -53,9 +53,10 @@ struct sdb_type { struct sdb_object { sdb_type_t type; int ref_cnt; + char *name; }; -#define SDB_OBJECT_INIT { SDB_TYPE_INIT, 1 } -#define SDB_OBJECT_TYPED_INIT(t) { (t), 1 } +#define SDB_OBJECT_INIT { SDB_TYPE_INIT, 1, NULL } +#define SDB_OBJECT_TYPED_INIT(t) { (t), 1, NULL } typedef struct { sdb_object_t super; @@ -70,8 +71,8 @@ typedef struct { /* * sdb_object_create: - * Allocates a new sdb_object_t of the specified 'type'. The object will be - * initialized to zero and then passed on to the 'init' function (if + * Allocates a new sdb_object_t of the specified 'name' and 'type'. The object + * will be initialized to zero and then passed on to the 'init' function (if * specified). If specified, the 'destroy' callback will be called, when the * reference count drops to zero and before freeing the memory allocated by * the object itself. @@ -87,7 +88,7 @@ typedef struct { * - NULL on error */ sdb_object_t * -sdb_object_create(sdb_type_t type, ...); +sdb_object_create(const char *name, sdb_type_t type, ...); /* * sdb_object_create_wrapper: @@ -97,7 +98,8 @@ sdb_object_create(sdb_type_t type, ...); * of the SysDB object system. */ sdb_object_t * -sdb_object_create_wrapper(void *data, void (*destructor)(void *)); +sdb_object_create_wrapper(const char *name, + void *data, void (*destructor)(void *)); #define SDB_OBJECT_WRAPPER_STATIC(obj, destructor) \ { SDB_OBJECT_INIT, (obj), (destructor) } @@ -132,6 +134,18 @@ sdb_object_ref(sdb_object_t *obj); sdb_object_t * sdb_object_clone(const sdb_object_t *obj); +/* + * sdb_object_cmp_by_name: + * Compare two objects by their name ignoring the case of the characters. + * + * Returns: + * - a negative value if o1 compares less than o2 + * - zero if o1 matches o2 + * - a positive value if o1 compares greater than o2 + */ +int +sdb_object_cmp_by_name(const sdb_object_t *o1, const sdb_object_t *o2); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/include/core/store.h b/src/include/core/store.h index 7cdfbf0..b17fb21 100644 --- a/src/include/core/store.h +++ b/src/include/core/store.h @@ -45,11 +45,9 @@ extern const sdb_type_t sdb_service_type; typedef struct { sdb_object_t parent; - sdb_time_t last_update; - char *name; } sdb_store_obj_t; -#define SDB_STORE_OBJ_INIT(t) { SDB_OBJECT_TYPED_INIT(t), 0, NULL } +#define SDB_STORE_OBJ_INIT(t) { SDB_OBJECT_TYPED_INIT(t), 0 } #define SDB_STORE_OBJ(obj) ((sdb_store_obj_t *)(obj)) #define SDB_CONST_STORE_OBJ(obj) ((const sdb_store_obj_t *)(obj)) @@ -85,7 +83,6 @@ typedef struct { /* shortcuts for accessing the sdb_store_obj_t attributes of inheriting * objects */ #define _last_update parent.last_update -#define _name parent.name sdb_host_t * sdb_host_create(const char *name); diff --git a/src/include/utils/llist.h b/src/include/utils/llist.h index 354e976..c37c271 100644 --- a/src/include/utils/llist.h +++ b/src/include/utils/llist.h @@ -93,7 +93,7 @@ sdb_llist_append(sdb_llist_t *list, sdb_object_t *obj); * - a negative value on failure */ int -sdb_llist_insert(sdb_llist_t *list, sdb_object_t *obj, size_t index); +sdb_llist_insert(sdb_llist_t *list, sdb_object_t *obj, size_t idx); /* * sdb_llist_insert_sorted: @@ -116,24 +116,38 @@ int sdb_llist_insert_sorted(sdb_llist_t *list, sdb_object_t *obj, int (*compare)(const sdb_object_t *, const sdb_object_t *)); -/* sdb_llist_search: +/* + * sdb_llist_search: * Search for a 'key' in the given 'list'. The function will return the first * entry that matches the specified 'key'. For that purpose, the 'compare' * function is used. It should return 0 iff the two arguments compare equal. * * Returns: - * - a pointer the sdb_object_t containing the matching entry + * - a pointer to the first matching object * - NULL else */ sdb_object_t * sdb_llist_search(sdb_llist_t *list, const sdb_object_t *key, int (*compare)(const sdb_object_t *, const sdb_object_t *)); +/* + * sdb_llist_search_by_name: + * Search for an object named 'key' in the given 'list'. The function will + * return the first entry whose name matches the specified 'key' ignoring the + * case of the characters. + * + * Returns: + * - a pointer to the first matching object + * - NULL else + */ +sdb_object_t * +sdb_llist_search_by_name(sdb_llist_t *list, const char *key); + /* * sdb_llist_shift: * Removes and returns the first element of the list. The ref-count of the * item will not be changed, that is, if the element will not be used any - * further, it should be re-referenced by the caller. + * further, it should be de-referenced by the caller. * * Returns: * - the former first element of the list diff --git a/src/utils/llist.c b/src/utils/llist.c index 7d573cf..b606324 100644 --- a/src/utils/llist.c +++ b/src/utils/llist.c @@ -29,6 +29,7 @@ #include #include +#include #include @@ -234,7 +235,7 @@ sdb_llist_append(sdb_llist_t *list, sdb_object_t *obj) } /* sdb_llist_append */ int -sdb_llist_insert(sdb_llist_t *list, sdb_object_t *obj, size_t index) +sdb_llist_insert(sdb_llist_t *list, sdb_object_t *obj, size_t idx) { sdb_llist_elem_t *prev; sdb_llist_elem_t *next; @@ -243,7 +244,7 @@ sdb_llist_insert(sdb_llist_t *list, sdb_object_t *obj, size_t index) size_t i; - if ((! list) || (! obj) || (index > list->length)) + if ((! list) || (! obj) || (idx > list->length)) return -1; pthread_rwlock_wrlock(&list->lock); @@ -251,7 +252,7 @@ sdb_llist_insert(sdb_llist_t *list, sdb_object_t *obj, size_t index) prev = NULL; next = list->head; - for (i = 0; i < index; ++i) { + for (i = 0; i < idx; ++i) { prev = next; next = next->next; } @@ -311,6 +312,27 @@ sdb_llist_search(sdb_llist_t *list, const sdb_object_t *key, return NULL; } /* sdb_llist_search */ +sdb_object_t * +sdb_llist_search_by_name(sdb_llist_t *list, const char *key) +{ + sdb_llist_elem_t *elem; + + if (! list) + return NULL; + + pthread_rwlock_rdlock(&list->lock); + + for (elem = list->head; elem; elem = elem->next) + if (! strcasecmp(elem->obj->name, key)) + break; + + pthread_rwlock_unlock(&list->lock); + + if (elem) + return elem->obj; + return NULL; +} /* sdb_llist_search_by_name */ + sdb_object_t * sdb_llist_shift(sdb_llist_t *list) {