Merge branch 'collectd-5.7' into collectd-5.8
[collectd.git] / src / daemon / utils_cache.c
index 5e111e6..ea7c3e3 100644 (file)
@@ -222,8 +222,6 @@ int uc_init(void) {
 } /* int uc_init */
 
 int uc_check_timeout(void) {
-  cdtime_t now = cdtime();
-
   struct {
     char *key;
     cdtime_t time;
@@ -232,6 +230,7 @@ int uc_check_timeout(void) {
   size_t expired_num = 0;
 
   pthread_mutex_lock(&cache_lock);
+  cdtime_t now = cdtime();
 
   /* Build a list of entries to be flushed */
   c_avl_iterator_t *iter = c_avl_get_iterator(cache_tree);
@@ -423,6 +422,9 @@ int uc_get_rate_by_name(const char *name, gauge_t **ret_values,
 
     /* remove missing values from getval */
     if (ce->state == STATE_MISSING) {
+      DEBUG("utils_cache: uc_get_rate_by_name: requested metric \"%s\" is in "
+            "state \"missing\".",
+            name);
       status = -1;
     } else {
       ret_num = ce->values_num;
@@ -466,7 +468,7 @@ gauge_t *uc_get_rate(const data_set_t *ds, const value_list_t *vl) {
 
   /* This is important - the caller has no other way of knowing how many
    * values are returned. */
-  if (ret_num != (size_t)ds->ds_num) {
+  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.",
           ds->type, ds->ds_num, ret_num);
@@ -477,6 +479,75 @@ gauge_t *uc_get_rate(const data_set_t *ds, const value_list_t *vl) {
   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 %zu values, "
+          "but uc_get_value_by_name returned %zu.", ds->type, ds->ds_num,
+          ret_num);
+    sfree(ret);
+    return (NULL);
+  }
+
+  return (ret);
+} /* value_t *uc_get_value */
+
 size_t uc_get_size(void) {
   size_t size_arrays = 0;
 
@@ -842,6 +913,15 @@ int uc_iterator_get_interval(uc_iter_t *iter, cdtime_t *ret_interval) {
   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
  */