utils cache: Add an iterator interface.
authorSebastian Harl <sh@tokkee.org>
Fri, 6 May 2016 21:52:02 +0000 (23:52 +0200)
committerSebastian Harl <sh@tokkee.org>
Mon, 30 May 2016 21:43:13 +0000 (23:43 +0200)
This may be used to query additional information from the cache.

src/daemon/utils_cache.c
src/daemon/utils_cache.h

index d525570..321747d 100644 (file)
@@ -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 <octo at collectd.org>
+ *   Sebastian tokkee Harl <sh at tokkee.org>
  **/
 
 #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! */
index 75bfc42..efef31e 100644 (file)
@@ -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 <octo at collectd.org>
+ *   Sebastian tokkee Harl <sh at tokkee.org>
  **/
 
 #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);