X-Git-Url: https://git.octo.it/?p=collectd.git;a=blobdiff_plain;f=src%2Fdaemon%2Futils_cache.c;h=e63a20e548e0369ae0ec3faa9c2ee10144ba1adb;hp=aa8ce9efbc29e78ffc36c4966fe1134bed5f24b3;hb=9f8dc5668faf5432dcb1430017bd7a1c383c2453;hpb=55ffaf9ad7c8b180ac0192adb1a6ff6adc72c5a3 diff --git a/src/daemon/utils_cache.c b/src/daemon/utils_cache.c index aa8ce9ef..e63a20e5 100644 --- a/src/daemon/utils_cache.c +++ b/src/daemon/utils_cache.c @@ -28,10 +28,10 @@ #include "collectd.h" -#include "common.h" -#include "meta_data.h" #include "plugin.h" -#include "utils_avltree.h" +#include "utils/avltree/avltree.h" +#include "utils/common/common.h" +#include "utils/metadata/meta_data.h" #include "utils_cache.h" #include @@ -76,14 +76,14 @@ struct uc_iter_s { cache_entry_t *entry; }; -static c_avl_tree_t *cache_tree = NULL; +static c_avl_tree_t *cache_tree; static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER; static int cache_compare(const cache_entry_t *a, const cache_entry_t *b) { #if COLLECT_DEBUG assert((a != NULL) && (b != NULL)); #endif - return (strcmp(a->name, b->name)); + return strcmp(a->name, b->name); } /* int cache_compare */ static cache_entry_t *cache_alloc(size_t values_num) { @@ -92,7 +92,7 @@ static cache_entry_t *cache_alloc(size_t values_num) { ce = calloc(1, sizeof(*ce)); if (ce == NULL) { ERROR("utils_cache: cache_alloc: calloc failed."); - return (NULL); + return NULL; } ce->values_num = values_num; @@ -103,14 +103,14 @@ static cache_entry_t *cache_alloc(size_t values_num) { sfree(ce->values_raw); sfree(ce); ERROR("utils_cache: cache_alloc: calloc failed."); - return (NULL); + return NULL; } ce->history = NULL; ce->history_length = 0; ce->meta = NULL; - return (ce); + return ce; } /* cache_entry_t *cache_alloc */ static void cache_free(cache_entry_t *ce) { @@ -148,14 +148,14 @@ static int uc_insert(const data_set_t *ds, const value_list_t *vl, key_copy = strdup(key); if (key_copy == NULL) { ERROR("uc_insert: strdup failed."); - return (-1); + return -1; } ce = cache_alloc(ds->ds_num); if (ce == NULL) { sfree(key_copy); - ERROR("uc_insert: cache_alloc (%zu) failed.", ds->ds_num); - return (-1); + ERROR("uc_insert: cache_alloc (%" PRIsz ") failed.", ds->ds_num); + return -1; } sstrncpy(ce->name, key, sizeof(ce->name)); @@ -191,7 +191,7 @@ static int uc_insert(const data_set_t *ds, const value_list_t *vl, ds->ds[i].type); sfree(key_copy); cache_free(ce); - return (-1); + return -1; } /* switch (ds->ds[i].type) */ } /* for (i) */ @@ -201,16 +201,20 @@ static int uc_insert(const data_set_t *ds, const value_list_t *vl, ce->last_time = vl->time; ce->last_update = cdtime(); ce->interval = vl->interval; - ce->state = STATE_OKAY; + ce->state = STATE_UNKNOWN; + + if (vl->meta != NULL) { + ce->meta = meta_data_clone(vl->meta); + } if (c_avl_insert(cache_tree, key_copy, ce) != 0) { sfree(key_copy); ERROR("uc_insert: c_avl_insert failed."); - return (-1); + return -1; } DEBUG("uc_insert: Added %s to the cache.", key); - return (0); + return 0; } /* int uc_insert */ int uc_init(void) { @@ -218,7 +222,7 @@ int uc_init(void) { cache_tree = c_avl_create((int (*)(const void *, const void *))cache_compare); - return (0); + return 0; } /* int uc_init */ int uc_check_timeout(void) { @@ -265,7 +269,7 @@ int uc_check_timeout(void) { if (expired_num == 0) { sfree(expired); - return (0); + return 0; } /* Call the "missing" callback for each value. Do this before removing the @@ -309,7 +313,7 @@ int uc_check_timeout(void) { pthread_mutex_unlock(&cache_lock); sfree(expired); - return (0); + return 0; } /* int uc_check_timeout */ int uc_update(const data_set_t *ds, const value_list_t *vl) { @@ -319,7 +323,7 @@ int uc_update(const data_set_t *ds, const value_list_t *vl) { if (FORMAT_VL(name, sizeof(name), vl) != 0) { ERROR("uc_update: FORMAT_VL failed."); - return (-1); + return -1; } pthread_mutex_lock(&cache_lock); @@ -329,7 +333,7 @@ int uc_update(const data_set_t *ds, const value_list_t *vl) { { status = uc_insert(ds, vl, name); pthread_mutex_unlock(&cache_lock); - return (status); + return status; } assert(ce != NULL); @@ -341,7 +345,7 @@ int uc_update(const data_set_t *ds, const value_list_t *vl) { "last cache update = %.3f;", name, CDTIME_T_TO_DOUBLE(vl->time), CDTIME_T_TO_DOUBLE(ce->last_time)); - return (-1); + return -1; } for (size_t i = 0; i < ds->ds_num; i++) { @@ -378,10 +382,10 @@ int uc_update(const data_set_t *ds, const value_list_t *vl) { pthread_mutex_unlock(&cache_lock); ERROR("uc_update: Don't know how to handle data source type %i.", ds->ds[i].type); - return (-1); + return -1; } /* switch (ds->ds[i].type) */ - DEBUG("uc_update: %s: ds[%zu] = %lf", name, i, ce->values_gauge[i]); + DEBUG("uc_update: %s: ds[%" PRIsz "] = %lf", name, i, ce->values_gauge[i]); } /* for (i) */ /* Update the history if it exists. */ @@ -405,7 +409,7 @@ int uc_update(const data_set_t *ds, const value_list_t *vl) { pthread_mutex_unlock(&cache_lock); - return (0); + return 0; } /* int uc_update */ int uc_get_rate_by_name(const char *name, gauge_t **ret_values, @@ -448,7 +452,7 @@ int uc_get_rate_by_name(const char *name, gauge_t **ret_values, *ret_values_num = ret_num; } - return (status); + return status; } /* gauge_t *uc_get_rate_by_name */ gauge_t *uc_get_rate(const data_set_t *ds, const value_list_t *vl) { @@ -459,25 +463,93 @@ gauge_t *uc_get_rate(const data_set_t *ds, const value_list_t *vl) { if (FORMAT_VL(name, sizeof(name), vl) != 0) { ERROR("utils_cache: uc_get_rate: FORMAT_VL failed."); - return (NULL); + return NULL; } status = uc_get_rate_by_name(name, &ret, &ret_num); if (status != 0) - return (NULL); + return NULL; /* This is important - the caller has no other way of knowing how many * values are returned. */ if (ret_num != ds->ds_num) { - ERROR("utils_cache: uc_get_rate: ds[%s] has %zu values, " - "but uc_get_rate_by_name returned %zu.", + ERROR("utils_cache: uc_get_rate: ds[%s] has %" PRIsz " values, " + "but uc_get_rate_by_name returned %" PRIsz ".", + ds->type, ds->ds_num, ret_num); + sfree(ret); + return NULL; + } + + return ret; +} /* gauge_t *uc_get_rate */ + +int uc_get_value_by_name(const char *name, value_t **ret_values, + size_t *ret_values_num) { + value_t *ret = NULL; + size_t ret_num = 0; + cache_entry_t *ce = NULL; + int status = 0; + + pthread_mutex_lock(&cache_lock); + + if (c_avl_get(cache_tree, name, (void *)&ce) == 0) { + assert(ce != NULL); + + /* remove missing values from getval */ + if (ce->state == STATE_MISSING) { + status = -1; + } else { + ret_num = ce->values_num; + ret = malloc(ret_num * sizeof(*ret)); + if (ret == NULL) { + ERROR("utils_cache: uc_get_value_by_name: malloc failed."); + status = -1; + } else { + memcpy(ret, ce->values_raw, ret_num * sizeof(value_t)); + } + } + } else { + DEBUG("utils_cache: uc_get_value_by_name: No such value: %s", name); + status = -1; + } + + pthread_mutex_unlock(&cache_lock); + + if (status == 0) { + *ret_values = ret; + *ret_values_num = ret_num; + } + + return (status); +} /* int uc_get_value_by_name */ + +value_t *uc_get_value(const data_set_t *ds, const value_list_t *vl) { + char name[6 * DATA_MAX_NAME_LEN]; + value_t *ret = NULL; + size_t ret_num = 0; + int status; + + if (FORMAT_VL(name, sizeof(name), vl) != 0) { + ERROR("utils_cache: uc_get_value: FORMAT_VL failed."); + return (NULL); + } + + status = uc_get_value_by_name(name, &ret, &ret_num); + if (status != 0) + return (NULL); + + /* This is important - the caller has no other way of knowing how many + * values are returned. */ + if (ret_num != (size_t)ds->ds_num) { + ERROR("utils_cache: uc_get_value: ds[%s] has %" PRIsz " values, " + "but uc_get_value_by_name returned %" PRIsz ".", ds->type, ds->ds_num, ret_num); sfree(ret); return (NULL); } return (ret); -} /* gauge_t *uc_get_rate */ +} /* value_t *uc_get_value */ size_t uc_get_size(void) { size_t size_arrays = 0; @@ -486,7 +558,7 @@ size_t uc_get_size(void) { size_arrays = (size_t)c_avl_size(cache_tree); pthread_mutex_unlock(&cache_lock); - return (size_arrays); + return size_arrays; } int uc_get_names(char ***ret_names, cdtime_t **ret_times, size_t *ret_number) { @@ -502,7 +574,7 @@ int uc_get_names(char ***ret_names, cdtime_t **ret_times, size_t *ret_number) { int status = 0; if ((ret_names == NULL) || (ret_number == NULL)) - return (-1); + return -1; pthread_mutex_lock(&cache_lock); @@ -511,7 +583,7 @@ int uc_get_names(char ***ret_names, cdtime_t **ret_times, size_t *ret_number) { /* Handle the "no values" case here, to avoid the error message when * calloc() returns NULL. */ pthread_mutex_unlock(&cache_lock); - return (0); + return 0; } names = calloc(size_arrays, sizeof(*names)); @@ -521,7 +593,7 @@ int uc_get_names(char ***ret_names, cdtime_t **ret_times, size_t *ret_number) { sfree(names); sfree(times); pthread_mutex_unlock(&cache_lock); - return (ENOMEM); + return ENOMEM; } iter = c_avl_get_iterator(cache_tree); @@ -556,7 +628,7 @@ int uc_get_names(char ***ret_names, cdtime_t **ret_times, size_t *ret_number) { sfree(names); sfree(times); - return (-1); + return -1; } *ret_names = names; @@ -566,7 +638,7 @@ int uc_get_names(char ***ret_names, cdtime_t **ret_times, size_t *ret_number) { sfree(times); *ret_number = number; - return (0); + return 0; } /* int uc_get_names */ int uc_get_state(const data_set_t *ds, const value_list_t *vl) { @@ -576,7 +648,7 @@ int uc_get_state(const data_set_t *ds, const value_list_t *vl) { if (FORMAT_VL(name, sizeof(name), vl) != 0) { ERROR("uc_get_state: FORMAT_VL failed."); - return (STATE_ERROR); + return STATE_ERROR; } pthread_mutex_lock(&cache_lock); @@ -588,7 +660,7 @@ int uc_get_state(const data_set_t *ds, const value_list_t *vl) { pthread_mutex_unlock(&cache_lock); - return (ret); + return ret; } /* int uc_get_state */ int uc_set_state(const data_set_t *ds, const value_list_t *vl, int state) { @@ -598,7 +670,7 @@ int uc_set_state(const data_set_t *ds, const value_list_t *vl, int state) { if (FORMAT_VL(name, sizeof(name), vl) != 0) { ERROR("uc_set_state: FORMAT_VL failed."); - return (STATE_ERROR); + return STATE_ERROR; } pthread_mutex_lock(&cache_lock); @@ -611,7 +683,7 @@ int uc_set_state(const data_set_t *ds, const value_list_t *vl, int state) { pthread_mutex_unlock(&cache_lock); - return (ret); + return ret; } /* int uc_set_state */ int uc_get_history_by_name(const char *name, gauge_t *ret_history, @@ -624,12 +696,12 @@ int uc_get_history_by_name(const char *name, gauge_t *ret_history, status = c_avl_get(cache_tree, name, (void *)&ce); if (status != 0) { pthread_mutex_unlock(&cache_lock); - return (-ENOENT); + return -ENOENT; } if (((size_t)ce->values_num) != num_ds) { pthread_mutex_unlock(&cache_lock); - return (-EINVAL); + return -EINVAL; } /* Check if there are enough values available. If not, increase the buffer @@ -641,7 +713,7 @@ int uc_get_history_by_name(const char *name, gauge_t *ret_history, realloc(ce->history, sizeof(*ce->history) * num_steps * ce->values_num); if (tmp == NULL) { pthread_mutex_unlock(&cache_lock); - return (-ENOMEM); + return -ENOMEM; } for (size_t i = ce->history_length * ce->values_num; @@ -671,7 +743,7 @@ int uc_get_history_by_name(const char *name, gauge_t *ret_history, pthread_mutex_unlock(&cache_lock); - return (0); + return 0; } /* int uc_get_history_by_name */ int uc_get_history(const data_set_t *ds, const value_list_t *vl, @@ -680,10 +752,10 @@ int uc_get_history(const data_set_t *ds, const value_list_t *vl, if (FORMAT_VL(name, sizeof(name), vl) != 0) { ERROR("utils_cache: uc_get_history: FORMAT_VL failed."); - return (-1); + return -1; } - return (uc_get_history_by_name(name, ret_history, num_steps, num_ds)); + return uc_get_history_by_name(name, ret_history, num_steps, num_ds); } /* int uc_get_history */ int uc_get_hits(const data_set_t *ds, const value_list_t *vl) { @@ -693,7 +765,7 @@ int uc_get_hits(const data_set_t *ds, const value_list_t *vl) { if (FORMAT_VL(name, sizeof(name), vl) != 0) { ERROR("uc_get_hits: FORMAT_VL failed."); - return (STATE_ERROR); + return STATE_ERROR; } pthread_mutex_lock(&cache_lock); @@ -705,7 +777,7 @@ int uc_get_hits(const data_set_t *ds, const value_list_t *vl) { pthread_mutex_unlock(&cache_lock); - return (ret); + return ret; } /* int uc_get_hits */ int uc_set_hits(const data_set_t *ds, const value_list_t *vl, int hits) { @@ -715,7 +787,7 @@ int uc_set_hits(const data_set_t *ds, const value_list_t *vl, int hits) { if (FORMAT_VL(name, sizeof(name), vl) != 0) { ERROR("uc_set_hits: FORMAT_VL failed."); - return (STATE_ERROR); + return STATE_ERROR; } pthread_mutex_lock(&cache_lock); @@ -728,7 +800,7 @@ int uc_set_hits(const data_set_t *ds, const value_list_t *vl, int hits) { pthread_mutex_unlock(&cache_lock); - return (ret); + return ret; } /* int uc_set_hits */ int uc_inc_hits(const data_set_t *ds, const value_list_t *vl, int step) { @@ -738,7 +810,7 @@ int uc_inc_hits(const data_set_t *ds, const value_list_t *vl, int step) { if (FORMAT_VL(name, sizeof(name), vl) != 0) { ERROR("uc_inc_hits: FORMAT_VL failed."); - return (STATE_ERROR); + return STATE_ERROR; } pthread_mutex_lock(&cache_lock); @@ -751,35 +823,33 @@ int uc_inc_hits(const data_set_t *ds, const value_list_t *vl, int step) { pthread_mutex_unlock(&cache_lock); - return (ret); + return ret; } /* int uc_inc_hits */ /* * Iterator interface */ uc_iter_t *uc_get_iterator(void) { - uc_iter_t *iter; - - iter = (uc_iter_t *)calloc(1, sizeof(*iter)); + uc_iter_t *iter = calloc(1, sizeof(*iter)); if (iter == NULL) - return (NULL); + return NULL; pthread_mutex_lock(&cache_lock); iter->iter = c_avl_get_iterator(cache_tree); if (iter->iter == NULL) { free(iter); - return (NULL); + return NULL; } - return (iter); + return iter; } /* uc_iter_t *uc_get_iterator */ int uc_iterator_next(uc_iter_t *iter, char **ret_name) { int status; if (iter == NULL) - return (-1); + return -1; while ((status = c_avl_iterator_next(iter->iter, (void *)&iter->name, (void *)&iter->entry)) == 0) { @@ -791,13 +861,13 @@ int uc_iterator_next(uc_iter_t *iter, char **ret_name) { if (status != 0) { iter->name = NULL; iter->entry = NULL; - return (-1); + return -1; } if (ret_name != NULL) *ret_name = iter->name; - return (0); + return 0; } /* int uc_iterator_next */ void uc_iterator_destroy(uc_iter_t *iter) { @@ -812,38 +882,46 @@ void uc_iterator_destroy(uc_iter_t *iter) { int uc_iterator_get_time(uc_iter_t *iter, cdtime_t *ret_time) { if ((iter == NULL) || (iter->entry == NULL) || (ret_time == NULL)) - return (-1); + return -1; *ret_time = iter->entry->last_time; - return (0); + return 0; } /* int uc_iterator_get_name */ int uc_iterator_get_values(uc_iter_t *iter, value_t **ret_values, size_t *ret_num) { if ((iter == NULL) || (iter->entry == NULL) || (ret_values == NULL) || (ret_num == NULL)) - return (-1); - + return -1; *ret_values = calloc(iter->entry->values_num, sizeof(*iter->entry->values_raw)); if (*ret_values == NULL) - return (-1); + return -1; for (size_t i = 0; i < iter->entry->values_num; ++i) - *ret_values[i] = iter->entry->values_raw[i]; + (*ret_values)[i] = iter->entry->values_raw[i]; *ret_num = iter->entry->values_num; - return (0); + return 0; } /* int uc_iterator_get_values */ int uc_iterator_get_interval(uc_iter_t *iter, cdtime_t *ret_interval) { if ((iter == NULL) || (iter->entry == NULL) || (ret_interval == NULL)) - return (-1); + return -1; *ret_interval = iter->entry->interval; - return (0); + return 0; } /* int uc_iterator_get_name */ +int uc_iterator_get_meta(uc_iter_t *iter, meta_data_t **ret_meta) { + if ((iter == NULL) || (iter->entry == NULL) || (ret_meta == NULL)) + return -1; + + *ret_meta = meta_data_clone(iter->entry->meta); + + return 0; +} /* int uc_iterator_get_meta */ + /* * Meta data interface */ @@ -857,7 +935,7 @@ static meta_data_t *uc_get_meta(const value_list_t *vl) /* {{{ */ status = FORMAT_VL(name, sizeof(name), vl); if (status != 0) { ERROR("utils_cache: uc_get_meta: FORMAT_VL failed."); - return (NULL); + return NULL; } pthread_mutex_lock(&cache_lock); @@ -865,7 +943,7 @@ static meta_data_t *uc_get_meta(const value_list_t *vl) /* {{{ */ status = c_avl_get(cache_tree, name, (void *)&ce); if (status != 0) { pthread_mutex_unlock(&cache_lock); - return (NULL); + return NULL; } assert(ce != NULL); @@ -875,7 +953,7 @@ static meta_data_t *uc_get_meta(const value_list_t *vl) /* {{{ */ if (ce->meta == NULL) pthread_mutex_unlock(&cache_lock); - return (ce->meta); + return ce->meta; } /* }}} meta_data_t *uc_get_meta */ /* Sorry about this preprocessor magic, but it really makes this file much @@ -886,10 +964,10 @@ static meta_data_t *uc_get_meta(const value_list_t *vl) /* {{{ */ int status; \ meta = uc_get_meta(vl); \ if (meta == NULL) \ - return (-1); \ + return -1; \ status = wrap_function(meta, key); \ pthread_mutex_unlock(&cache_lock); \ - return (status); \ + return status; \ } int uc_meta_data_exists(const value_list_t *vl, const char *key) UC_WRAP(meta_data_exists) @@ -906,10 +984,10 @@ int uc_meta_data_exists(const value_list_t *vl, int status; \ meta = uc_get_meta(vl); \ if (meta == NULL) \ - return (-1); \ + return -1; \ status = wrap_function(meta, key, value); \ pthread_mutex_unlock(&cache_lock); \ - return (status); \ + return status; \ } int uc_meta_data_add_string(const value_list_t *vl, const char *key, const char *value) @@ -921,7 +999,7 @@ int uc_meta_data_exists(const value_list_t *vl, const value_list_t *vl, const char *key, double value) UC_WRAP(meta_data_add_double) int uc_meta_data_add_boolean( const value_list_t *vl, const char *key, - _Bool value) UC_WRAP(meta_data_add_boolean) + bool value) UC_WRAP(meta_data_add_boolean) int uc_meta_data_get_string(const value_list_t *vl, const char *key, @@ -937,8 +1015,6 @@ int uc_meta_data_exists(const value_list_t *vl, const char *key, double *value) UC_WRAP(meta_data_get_double) int uc_meta_data_get_boolean( const value_list_t *vl, - const char *key, _Bool *value) + const char *key, bool *value) UC_WRAP(meta_data_get_boolean) #undef UC_WRAP - - /* vim: set sw=2 ts=8 sts=2 tw=78 : */