]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
stats: Add helper to append category names without duplicates
authorJosef 'Jeff' Sipek <jeff.sipek@open-xchange.com>
Fri, 21 Aug 2020 18:23:14 +0000 (14:23 -0400)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Fri, 11 Sep 2020 13:35:56 +0000 (13:35 +0000)
src/stats/event-exporter-fmt.c
src/stats/event-exporter.h

index 992d2b403c4c99139589c6606087ce9ed49c5e29..a4ec5a83f946e95645b55360fcbb11cdb9e6216d 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "lib.h"
 #include "str.h"
+#include "hash.h"
 #include "ioloop.h"
 #include "event-exporter.h"
 
@@ -24,3 +25,54 @@ void event_export_helper_fmt_rfc3339_time(string_t *dest,
                    tm->tm_hour, tm->tm_min, tm->tm_sec,
                    time->tv_usec);
 }
+
+HASH_TABLE_DEFINE_TYPE(category_set, void *, const struct event_category *);
+
+static void insert_category(HASH_TABLE_TYPE(category_set) hash,
+                           const struct event_category * const cat)
+{
+       /* insert this category (key == the unique internal pointer) */
+       hash_table_update(hash, cat->internal, cat);
+
+       /* insert parent's categories */
+       if (cat->parent != NULL)
+               insert_category(hash, cat->parent);
+}
+
+void event_export_helper_fmt_categories(string_t *dest,
+                                       struct event_category * const *cats,
+                                       unsigned int count,
+                                       void (*append)(string_t *, const char *),
+                                       const char *separator)
+{
+       HASH_TABLE_TYPE(category_set) hash;
+       struct hash_iterate_context *iter;
+       const struct event_category *cat;
+       void *key ATTR_UNUSED;
+       unsigned int i;
+       bool first = TRUE;
+
+       if (count == 0)
+               return;
+
+       hash_table_create_direct(&hash, pool_datastack_create(),
+                                3 * count /* estimate */);
+
+       /* insert all the categories into the hash table */
+       for (i = 0; i < count; i++)
+               insert_category(hash, cats[i]);
+
+       /* output each category from hash table */
+       iter = hash_table_iterate_init(hash);
+       while (hash_table_iterate(iter, hash, &key, &cat)) {
+               if (!first)
+                       str_append(dest, separator);
+
+               append(dest, cat->name);
+
+               first = FALSE;
+       }
+       hash_table_iterate_deinit(&iter);
+
+       hash_table_destroy(&hash);
+}
index 7ec0590656c503ec65030f5fcf9a7639b1489a95..64bb70844c080e6445eb1b4776054bd1e0ce6c20 100644 (file)
@@ -18,5 +18,14 @@ void event_export_transport_log(const struct exporter *exporter, const buffer_t
 void event_export_helper_fmt_rfc3339_time(string_t *dest, const struct timeval *time);
 /* append a microsecond resolution unix timestamp in seconds (i.e., %u.%06u) */
 void event_export_helper_fmt_unix_time(string_t *dest, const struct timeval *time);
+/* append category names using 'append' function pointer, separated by 'separator' arg
+
+   The result has no duplicates regardless of if the array has any or if any
+   of the categories' ancestors are implictly or explicitly duplicated. */
+void event_export_helper_fmt_categories(string_t *dest,
+                                       struct event_category *const *cats,
+                                       unsigned int count,
+                                       void (*append)(string_t *, const char *),
+                                       const char *separator);
 
 #endif