From 9e718fa4673df0ebef245a600feafaab3fcb09c4 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Fri, 6 May 2016 23:52:02 +0200 Subject: [PATCH] utils cache: Add an iterator interface. This may be used to query additional information from the cache. --- src/daemon/utils_cache.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++- src/daemon/utils_cache.h | 49 +++++++++++++++++++++ 2 files changed, 157 insertions(+), 1 deletion(-) diff --git a/src/daemon/utils_cache.c b/src/daemon/utils_cache.c index d5255700..321747de 100644 --- a/src/daemon/utils_cache.c +++ b/src/daemon/utils_cache.c @@ -1,6 +1,7 @@ /** * collectd - src/utils_cache.c * Copyright (C) 2007-2010 Florian octo Forster + * Copyright (C) 2016 Sebastian tokkee Harl * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -22,6 +23,7 @@ * * Authors: * Florian octo Forster + * Sebastian tokkee Harl **/ #include "collectd.h" @@ -47,7 +49,7 @@ typedef struct cache_entry_s * (for purging old entries) */ cdtime_t last_update; /* Interval in which the data is collected - * (for purding old entries) */ + * (for purging old entries) */ cdtime_t interval; int state; int hits; @@ -68,6 +70,13 @@ typedef struct cache_entry_s meta_data_t *meta; } cache_entry_t; +struct uc_iter_s { + c_avl_iterator_t *iter; + + char *name; + cache_entry_t *entry; +}; + static c_avl_tree_t *cache_tree = NULL; static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER; @@ -868,6 +877,104 @@ int uc_inc_hits (const data_set_t *ds, const value_list_t *vl, int step) } /* int uc_inc_hits */ /* + * Iterator interface + */ +uc_iter_t *uc_get_iterator () +{ + uc_iter_t *iter; + + iter = (uc_iter_t *) calloc(1, sizeof (*iter)); + if (iter == 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 (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); + + while ((status = c_avl_iterator_next (iter->iter, + (void *) &iter->name, (void *) &iter->entry)) == 0) + { + if (iter->entry->state == STATE_MISSING) + continue; + + break; + } + if (status != 0) { + iter->name = NULL; + iter->entry = NULL; + return (-1); + } + + if (ret_name != NULL) + *ret_name = iter->name; + + return (0); +} /* int uc_iterator_next */ + +void uc_iterator_destroy (uc_iter_t *iter) +{ + if (iter == NULL) + return; + + c_avl_iterator_destroy (iter->iter); + pthread_mutex_unlock (&cache_lock); + + free (iter); +} /* void uc_iterator_destroy */ + +int uc_iterator_get_time (uc_iter_t *iter, cdtime_t *ret_time) +{ + if ((iter == NULL) || (iter->entry == NULL) || (ret_time == NULL)) + return (-1); + + *ret_time = iter->entry->last_time; + return (0); +} /* int uc_iterator_get_name */ + +int uc_iterator_get_values (uc_iter_t *iter, value_t **ret_values, size_t *ret_num) +{ + size_t i; + + if ((iter == NULL) || (iter->entry == NULL) + || (ret_values == NULL) || (ret_num == NULL)) + return (-1); + + *ret_values = calloc (iter->entry->values_num, sizeof(*iter->entry->values_raw)); + if (*ret_values == NULL) + return (-1); + for (i = 0; i < iter->entry->values_num; ++i) + *ret_values[i] = iter->entry->values_raw[i]; + + *ret_num = iter->entry->values_num; + + 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); + + *ret_interval = iter->entry->interval; + return (0); +} /* int uc_iterator_get_name */ + +/* * Meta data interface */ /* XXX: This function will acquire `cache_lock' but will not free it! */ diff --git a/src/daemon/utils_cache.h b/src/daemon/utils_cache.h index 75bfc425..efef31e4 100644 --- a/src/daemon/utils_cache.h +++ b/src/daemon/utils_cache.h @@ -1,6 +1,7 @@ /** * collectd - src/utils_cache.h * Copyright (C) 2007 Florian octo Forster + * Copyright (C) 2016 Sebastian tokkee Harl * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -22,6 +23,7 @@ * * Authors: * Florian octo Forster + * Sebastian tokkee Harl **/ #ifndef UTILS_CACHE_H @@ -55,6 +57,53 @@ int uc_get_history_by_name (const char *name, gauge_t *ret_history, size_t num_steps, size_t num_ds); /* + * Iterator interface + */ +struct uc_iter_s; +typedef struct uc_iter_s uc_iter_t; + +/* + * NAME + * uc_get_iterator + * + * DESCRIPTION + * Create an iterator for the cache. It will hold the cache lock until it's + * destroyed. + * + * RETURN VALUE + * An iterator object on success or NULL else. + */ +uc_iter_t *uc_get_iterator (); + +/* + * NAME + * uc_iterator_next + * + * DESCRIPTION + * Advance the iterator to the next positiion and (optionally) returns the + * name of the entry. + * + * PARAMETERS + * `iter' The iterator object to advance. + * `ret_name' Pointer to a string where to store the name. The returned + * value is a copy of the value and has to be freed by the + * caller. + * + * RETURN VALUE + * Zero upon success or non-zero if the iterator ie NULL or no further + * values are available. + */ +int uc_iterator_next (uc_iter_t *iter, char **ret_name); +void uc_iterator_destroy (uc_iter_t *iter); + +/* Return the timestamp of the value at the current position. */ +int uc_iterator_get_time (uc_iter_t *iter, cdtime_t *ret_time); +/* Return the (raw) value at the current position. */ +int uc_iterator_get_values (uc_iter_t *iter, value_t **ret_values, size_t *ret_num); +/* Return the interval of the value at the current position. */ +int uc_iterator_get_interval (uc_iter_t *iter, cdtime_t *ret_interval); + +/* * Meta data interface */ int uc_meta_data_exists (const value_list_t *vl, const char *key); -- 2.11.0