+/**
+ * @brief Representation of all (testbed) nodes.
+ */
+static struct Node {
+ /**
+ * @brief Index of the node in this array.
+ */
+ unsigned index_node;
+
+ /**
+ * @brief Configuration handle for this node
+ */
+ struct GNUNET_CONFIGURATION_Handle *conf;
+
+ /**
+ * Handle for pending GET operation.
+ */
+ struct GNUNET_STATISTICS_GetHandle *gh;
+
+ /**
+ * @brief Statistics handle nodes.
+ */
+ struct GNUNET_STATISTICS_Handle *handle;
+ /**
+ * @brief Identifier for shutdown task for this node.
+ */
+ struct GNUNET_SCHEDULER_Task *shutdown_task;
+} *nodes;
+
+/**
+ * @brief Number of configurations of all (testbed) nodes.
+ */
+static unsigned num_nodes;
+
+/**
+ * @brief Set of values for a combination of subsystem and name.
+ */
+struct ValueSet
+{
+ /**
+ * @brief Subsystem of the valueset.
+ */
+ char *subsystem;
+
+ /**
+ * @brief Name of the valueset.
+ */
+ char *name;
+
+ /**
+ * @brief The values.
+ */
+ uint64_t *values;
+
+ /**
+ * @brief Persistence of the values.
+ */
+ int is_persistent;
+};
+
+/**
+ * @brief Collection of all values (represented with #ValueSet).
+ */
+static struct GNUNET_CONTAINER_MultiHashMap *values;
+
+/**
+ * @brief Number of nodes that have their values ready.
+ */
+static int num_nodes_ready;
+
+/**
+ * @brief Number of nodes that have their values ready.
+ */
+static int num_nodes_ready_shutdown;
+
+/**
+ * @brief Create a new #ValueSet
+ *
+ * @param subsystem Subsystem of the valueset.
+ * @param name Name of the valueset.
+ * @param num_values Number of values in valueset - number of peers.
+ * @param is_persistent Persistence status of values.
+ *
+ * @return Newly allocated #ValueSet.
+ */
+static struct ValueSet *
+new_value_set (const char *subsystem,
+ const char *name,
+ unsigned num_values,
+ int is_persistent)
+{
+ struct ValueSet *value_set;
+
+ value_set = GNUNET_new (struct ValueSet);
+ value_set->subsystem = GNUNET_strdup (subsystem);
+ value_set->name = GNUNET_strdup (name);
+ value_set->values = GNUNET_new_array (num_values, uint64_t);
+ value_set->is_persistent = persistent;
+ return value_set;
+}
+
+/**
+ * @brief Print the (collected) values.
+ *
+ * Implements #GNUNET_CONTAINER_HashMapIterator.
+ *
+ * @param cls Closure - unused
+ * @param key #GNUNET_HashCode key of #GNUNET_CONTAINER_MultiHashMap iterator -
+ * unused
+ * @param value Values represented as #ValueSet.
+ *
+ * @return GNUNET_YES - continue iteration.
+ */
+static int
+printer (void *cls,
+ const struct GNUNET_HashCode *key,
+ void *value)
+{
+ struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get();
+ const char *now_str;
+ struct ValueSet *value_set = value;
+
+ if (quiet == GNUNET_NO)
+ {
+ if (GNUNET_YES == watch)
+ {
+ now_str = GNUNET_STRINGS_absolute_time_to_string (now);
+ FPRINTF (stdout,
+ "%24s%s %s%s%12s%s %s%50s%s%s ",
+ now_str,
+ csv_separator,
+ value_set->is_persistent ? "!" : " ",
+ csv_separator,
+ value_set->subsystem,
+ csv_separator,
+ (0 == strlen (csv_separator) ? "": "\""), /* quotes if csv */
+ _(value_set->name),
+ (0 == strlen (csv_separator) ? "": "\""), /* quotes if csv */
+ (0 == strlen (csv_separator) ? ":": csv_separator));
+ }
+ else
+ {
+ FPRINTF (stdout,
+ "%s%s%12s%s %s%50s%s%s ",
+ value_set->is_persistent ? "!" : " ",
+ csv_separator,
+ value_set->subsystem,
+ csv_separator,
+ (0 == strlen (csv_separator) ? "": "\""), /* quotes if csv */
+ _(value_set->name),
+ (0 == strlen (csv_separator) ? "": "\""), /* quotes if csv */
+ (0 == strlen (csv_separator) ? ":": csv_separator));
+ }
+ }
+ for (unsigned i = 0; i < num_nodes; i++)
+ {
+ FPRINTF (stdout,
+ "%16llu%s",
+ (unsigned long long) value_set->values[i],
+ csv_separator);
+ }
+ FPRINTF (stdout, "\n");
+ GNUNET_free (value_set->subsystem);
+ GNUNET_free (value_set->name);
+ GNUNET_free (value_set->values);
+ GNUNET_free (value_set);
+ return GNUNET_YES;
+}
+