deleted file mode 100644
@@ -1,245 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * libtraceeval histogram interface.
- *
- * Copyright (C) 2023 Google Inc, Steven Rostedt <rostedt@goodmis.org>
- * Copyright (C) 2023 Google Inc, Stevie Alvarez <stevie.6strings@gmail.com>
- */
-#ifndef __LIBTRACEEVAL_HIST_H__
-#define __LIBTRACEEVAL_HIST_H__
-
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdbool.h>
-
-/* Data definition interfaces */
-
-/* Field name/descriptor for number of hits */
-#define TRACEEVAL_VAL_HITS ((const char *)(-1UL))
-
-#define TRACEEVAL_ARRAY_SIZE(data) (sizeof(data) / sizeof((data)[0]))
-
-/* Data type distinguishers */
-enum traceeval_data_type {
- TRACEEVAL_TYPE_NONE,
- TRACEEVAL_TYPE_NUMBER_8,
- TRACEEVAL_TYPE_NUMBER_16,
- TRACEEVAL_TYPE_NUMBER_32,
- TRACEEVAL_TYPE_NUMBER_64,
- TRACEEVAL_TYPE_NUMBER,
- TRACEEVAL_TYPE_POINTER,
- TRACEEVAL_TYPE_STRING,
-};
-
-/* Statistics specification flags */
-enum traceeval_flags {
- TRACEEVAL_FL_KEY = (1 << 0),
- TRACEEVAL_FL_VALUE = (1 << 1),
- TRACEEVAL_FL_SIGNED = (1 << 2),
- TRACEEVAL_FL_TIMESTAMP = (1 << 3),
- TRACEEVAL_FL_STAT = (1 << 4),
-};
-
-/*
- * Trace data entry for a traceeval histogram
- * Constitutes keys and values.
- */
-struct traceeval_data {
- enum traceeval_data_type type;
- union {
- char *string;
- const char *cstring;
- void *pointer;
- unsigned long number;
- unsigned long long number_64;
- unsigned int number_32;
- unsigned short number_16;
- unsigned char number_8;
- };
-};
-
-#define __TRACEEVAL_DATA(data_type, member, data) \
- { .type = TRACEEVAL_TYPE_##data_type, .member = (data) }
-
-#define DEFINE_TRACEEVAL_NUMBER(data) __TRACEEVAL_DATA(NUMBER, number, data)
-#define DEFINE_TRACEEVAL_NUMBER_8(data) __TRACEEVAL_DATA(NUMBER_8, number_8, data)
-#define DEFINE_TRACEEVAL_NUMBER_16(data) __TRACEEVAL_DATA(NUMBER_16, number_16, data)
-#define DEFINE_TRACEEVAL_NUMBER_32(data) __TRACEEVAL_DATA(NUMBER_32, number_32, data)
-#define DEFINE_TRACEEVAL_NUMBER_64(data) __TRACEEVAL_DATA(NUMBER_64, number_64, data)
-#define DEFINE_TRACEEVAL_STRING(data) __TRACEEVAL_DATA(STRING, string, data)
-#define DEFINE_TRACEEVAL_CSTRING(data) __TRACEEVAL_DATA(STRING, cstring, data)
-#define DEFINE_TRACEEVAL_POINTER(data) __TRACEEVAL_DATA(POINTER, pointer, data)
-
-#define __TRACEEVAL_SET(data, data_type, member, val) \
- do { \
- (data).type = TRACEEVAL_TYPE_##data_type; \
- (data).member = (val); \
- } while (0)
-
-#define TRACEEVAL_SET_NUMBER(data, val) __TRACEEVAL_SET(data, NUMBER, number, val)
-#define TRACEEVAL_SET_NUMBER_8(data, val) __TRACEEVAL_SET(data, NUMBER_8, number_8, val)
-#define TRACEEVAL_SET_NUMBER_16(data, val) __TRACEEVAL_SET(data, NUMBER_16, number_16, val)
-#define TRACEEVAL_SET_NUMBER_32(data, val) __TRACEEVAL_SET(data, NUMBER_32, number_32, val)
-#define TRACEEVAL_SET_NUMBER_64(data, val) __TRACEEVAL_SET(data, NUMBER_64, number_64, val)
-#define TRACEEVAL_SET_STRING(data, val) __TRACEEVAL_SET(data, STRING, string, val)
-#define TRACEEVAL_SET_CSTRING(data, val) __TRACEEVAL_SET(data, STRING, cstring, val)
-#define TRACEEVAL_SET_POINTER(data, val) __TRACEEVAL_SET(data, POINTER, pointer, val)
-
-struct traceeval_type;
-struct traceeval;
-
-/* release function callback on traceeval_data */
-typedef void (*traceeval_data_release_fn)(const struct traceeval_type *type,
- struct traceeval_data *data);
-
-/* compare function callback to compare traceeval_data */
-typedef int (*traceeval_data_cmp_fn)(struct traceeval *teval,
- const struct traceeval_type *type,
- const struct traceeval_data *A,
- const struct traceeval_data *B);
-
-/* make a unique value */
-typedef int (*traceeval_data_hash_fn)(struct traceeval *teval,
- const struct traceeval_type *type,
- const struct traceeval_data *data);
-
-typedef int (*traceeval_data_copy_fn)(const struct traceeval_type *type,
- struct traceeval_data *dst,
- const struct traceeval_data *src);
-
-typedef int (*traceeval_cmp_fn)(struct traceeval *teval,
- const struct traceeval_data *Akeys,
- const struct traceeval_data *Avals,
- const struct traceeval_data *Bkeys,
- const struct traceeval_data *Bvals,
- void *data);
-
-/*
- * struct traceeval_type - Describes the type of a traceevent_data instance
- * @type: The enum type that describes the traceeval_data
- * @name: The string name of the traceeval_data
- * @flags: flags to describe the traceeval_data
- * @id: User specified identifier
- * @release: An optional callback for when the data is being released
- * @cmp: An optional callback to specify a way to compare the type
- *
- * The traceeval_type structure defines expectations for a corresponding
- * traceeval_data instance for a traceeval histogram instance. Used to
- * describe both keys and values.
- *
- * The @id field is an optional value in case the user has multiple struct
- * traceeval_type instances and needs to distinguish between them into
- * 'sub-types'.
- *
- * For flexibility, @cmp() and @release() take a struct traceeval_type
- * instance. This allows the user to handle pointer types.
- * It may also be used for other types if the default cmp() or release()
- * need to be overridden. Note for string types, even if the release()
- * is called, the string freeing is still taken care of by the traceeval
- * infrastructure.
- *
- * The @id field is a user specified field that may allow the same callback
- * to be used by multiple types and not needing to do a strcmp() against the
- * name (could be used for switch statements).
- *
- * @cmp() is used to override the default compare of a type. This is
- * required to pointer types. It should return 0 on equality, 1 if the first
- * argument is greater than the second, -1 for the other way around,
- * and -2 on error.
- *
- * @release() is called when a data element is being released (or freed).
- */
-struct traceeval_type {
- char *name;
- enum traceeval_data_type type;
- size_t flags;
- size_t index;
- size_t id;
- traceeval_data_release_fn release;
- traceeval_data_cmp_fn cmp;
- traceeval_data_copy_fn copy;
- traceeval_data_hash_fn hash;
-};
-
-/* Statistics about a given entry element */
-struct traceeval_stat;
-
-/* Iterator over aggregated data */
-struct traceeval_iterator;
-
-struct traceeval;
-
-/* Histogram interfaces */
-
-#define traceeval_init(keys, vals) \
- traceeval_init_size(keys, vals, \
- TRACEEVAL_ARRAY_SIZE(keys), \
- (void *)vals == NULL ? 0 : TRACEEVAL_ARRAY_SIZE(vals))
-
-#define traceeval_init_size(keys, vals, nr_keys, nr_vals) \
- traceeval_init_data_size(keys, vals, nr_keys, nr_vals, \
- sizeof(struct traceeval_type), \
- sizeof(struct traceeval_data))
-
-struct traceeval *traceeval_init_data_size(struct traceeval_type *keys,
- struct traceeval_type *vals,
- size_t nr_keys, size_t nr_vals,
- size_t sizeof_type, size_t sizeof_data);
-
-void traceeval_release(struct traceeval *teval);
-
-int traceeval_insert_size(struct traceeval *teval,
- const struct traceeval_data *keys, size_t nr_keys,
- const struct traceeval_data *vals, size_t nr_vals);
-
-#define traceeval_insert(teval, keys, vals) \
- traceeval_insert_size(teval, keys, TRACEEVAL_ARRAY_SIZE(keys), \
- vals, (void *)vals == NULL ? 0 : TRACEEVAL_ARRAY_SIZE(vals))
-
-int traceeval_remove_size(struct traceeval *teval,
- const struct traceeval_data *keys, size_t nr_keys);
-
-#define traceeval_remove(teval, keys) \
- traceeval_remove_size(teval, keys, TRACEEVAL_ARRAY_SIZE(keys))
-
-int traceeval_query_size(struct traceeval *teval, const struct traceeval_data *keys,
- size_t nr_keys, const struct traceeval_data **results);
-
-#define traceeval_query(teval, keys, results) \
- traceeval_query_size(teval, keys, TRACEEVAL_ARRAY_SIZE(keys), results)
-
-void traceeval_results_release(struct traceeval *teval,
- const struct traceeval_data *results);
-
-size_t traceeval_count(struct traceeval *teval);
-
-#define traceeval_stat(teval, keys, type) \
- traceeval_stat_size(teval, keys, TRACEEVAL_ARRAY_SIZE(keys), type)
-
-struct traceeval_stat *traceeval_stat_size(struct traceeval *teval,
- const struct traceeval_data *keys,
- size_t nr_keys,
- struct traceeval_type *type);
-
-unsigned long long traceeval_stat_max(struct traceeval_stat *stat);
-unsigned long long traceeval_stat_min(struct traceeval_stat *stat);
-unsigned long long traceeval_stat_total(struct traceeval_stat *stat);
-unsigned long long traceeval_stat_count(struct traceeval_stat *stat);
-
-struct traceeval_iterator *traceeval_iterator_get(struct traceeval *teval);
-void traceeval_iterator_put(struct traceeval_iterator *iter);
-int traceeval_iterator_sort(struct traceeval_iterator *iter, const char *sort_field,
- int level, bool ascending);
-int traceeval_iterator_sort_custom(struct traceeval_iterator *iter,
- traceeval_cmp_fn sort_fn, void *data);
-int traceeval_iterator_next(struct traceeval_iterator *iter,
- const struct traceeval_data **keys);
-int traceeval_iterator_query(struct traceeval_iterator *iter,
- const struct traceeval_data **results);
-void traceeval_iterator_results_release(struct traceeval_iterator *iter,
- const struct traceeval_data *results);
-struct traceeval_stat *traceeval_iterator_stat(struct traceeval_iterator *iter,
- struct traceeval_type *type);
-int traceeval_iterator_remove(struct traceeval_iterator *iter);
-
-#endif /* __LIBTRACEEVAL_HIST_H__ */
@@ -1,120 +1,245 @@
/* SPDX-License-Identifier: MIT */
/*
- * Copyright (C) 2022 Google Inc, Steven Rostedt <rostedt@goodmis.org>
+ * libtraceeval histogram interface.
+ *
+ * Copyright (C) 2022-2023 Google Inc, Steven Rostedt <rostedt@goodmis.org>
+ * Copyright (C) 2023 Google Inc, Stevie Alvarez <stevie.6strings@gmail.com>
*/
-#ifndef __LIBTRACEEVAL_H__
-#define __LIBTRACEEVAL_H__
+#ifndef __LIBTRACEEVAL_HIST_H__
+#define __LIBTRACEEVAL_HIST_H__
#include <stdlib.h>
+#include <stddef.h>
#include <stdbool.h>
-typedef unsigned long long u64;
-typedef unsigned int u32;
+/* Data definition interfaces */
-struct traceeval;
-struct traceeval_key_array;
-struct traceeval_key_info_array;
-struct traceeval_outliers;
+/* Field name/descriptor for number of hits */
+#define TRACEEVAL_VAL_HITS ((const char *)(-1UL))
+
+#define TRACEEVAL_ARRAY_SIZE(data) (sizeof(data) / sizeof((data)[0]))
-enum traceeval_type {
+/* Data type distinguishers */
+enum traceeval_data_type {
TRACEEVAL_TYPE_NONE,
- TRACEEVAL_TYPE_STRING,
- TRACEEVAL_TYPE_POINTER,
- TRACEEVAL_TYPE_NUMBER,
- TRACEEVAL_TYPE_NUMBER_64,
- TRACEEVAL_TYPE_NUMBER_32,
- TRACEEVAL_TYPE_NUMBER_16,
TRACEEVAL_TYPE_NUMBER_8,
- TRACEEVAL_TYPE_ARRAY,
- TRACEEVAL_TYPE_MAX
+ TRACEEVAL_TYPE_NUMBER_16,
+ TRACEEVAL_TYPE_NUMBER_32,
+ TRACEEVAL_TYPE_NUMBER_64,
+ TRACEEVAL_TYPE_NUMBER,
+ TRACEEVAL_TYPE_POINTER,
+ TRACEEVAL_TYPE_STRING,
};
-struct traceeval_key_info {
- enum traceeval_type type;
- size_t size;
- ssize_t count;
- const char *name;
+/* Statistics specification flags */
+enum traceeval_flags {
+ TRACEEVAL_FL_KEY = (1 << 0),
+ TRACEEVAL_FL_VALUE = (1 << 1),
+ TRACEEVAL_FL_SIGNED = (1 << 2),
+ TRACEEVAL_FL_TIMESTAMP = (1 << 3),
+ TRACEEVAL_FL_STAT = (1 << 4),
};
-struct traceeval_key {
- enum traceeval_type type;
- ssize_t count;
+/*
+ * Trace data entry for a traceeval histogram
+ * Constitutes keys and values.
+ */
+struct traceeval_data {
+ enum traceeval_data_type type;
union {
- const char *string;
- void *pointer;
- long number;
- u64 number_64;
- u32 number_32;
- unsigned short number_16;
- unsigned char number_8;
- void *array;
+ char *string;
+ const char *cstring;
+ void *pointer;
+ unsigned long number;
+ unsigned long long number_64;
+ unsigned int number_32;
+ unsigned short number_16;
+ unsigned char number_8;
};
};
-struct traceeval_key_info_array *traceeval_key_info_array_alloc(void);
-void traceeval_key_info_array_free(struct traceeval_key_info_array *iarray);
-int traceeval_key_info_array_add(struct traceeval_key_info_array *iarray,
- const struct traceeval_key_info *key);
-
- struct traceeval *traceeval_n_alloc(const char *name,
- const struct traceeval_key_info_array *iarray);
- void traceeval_free(struct traceeval *teval);
-
- int traceeval_n_start(struct traceeval *teval, const struct traceeval_key *keys,
- unsigned long long start);
- int traceeval_n_stop(struct traceeval *teval, const struct traceeval_key *keys,
- unsigned long long stop);
- int traceeval_n_continue(struct traceeval *teval, const struct traceeval_key *keys,
- unsigned long long start);
-
- int traceeval_n_set_private(struct traceeval *teval, const struct traceeval_key *keys,
- void *data);
-
- void *traceeval_n_get_private(struct traceeval *teval, const struct traceeval_key *keys);
-
- struct traceeval_result_array *traceeval_results(struct traceeval *teval);
-
- size_t traceeval_result_nr(struct traceeval *teval);
-
- size_t traceeval_key_array_nr(struct traceeval_key_array *karray);
- const struct traceeval_key *traceeval_key_array_indx(const struct traceeval_key_array *karray,
- size_t index);
- struct traceeval_key_array *traceeval_result_indx_key_array(struct traceeval *teval,
- size_t index);
- ssize_t traceeval_result_indx_cnt(struct traceeval *teval, size_t index);
- ssize_t traceeval_result_indx_total(struct traceeval *teval, size_t index);
- ssize_t traceeval_result_indx_max(struct traceeval *teval, size_t index);
- ssize_t traceeval_result_indx_min(struct traceeval *teval, size_t index);
-
- ssize_t traceeval_result_keys_cnt(struct traceeval *teval, const struct traceeval_key *keys);
- ssize_t traceeval_result_keys_total(struct traceeval *teval, const struct traceeval_key *keys);
- ssize_t traceeval_result_keys_max(struct traceeval *teval, const struct traceeval_key *keys);
- ssize_t traceeval_result_keys_min(struct traceeval *teval, const struct traceeval_key *keys);
-
- struct traceeval *traceeval_1_alloc(const char *name, const struct traceeval_key_info info[1]);
-int traceeval_1_start(struct traceeval *teval, struct traceeval_key key,
- unsigned long long start);
-int traceeval_1_set_private(struct traceeval *teval, struct traceeval_key key,
- void *data);
-void *traceeval_1_get_private(struct traceeval *teval, struct traceeval_key key);
-int traceeval_1_stop(struct traceeval *teval, struct traceeval_key key,
- unsigned long long stop);
-int traceeval_1_continue(struct traceeval *teval, struct traceeval_key key,
- unsigned long long start);
-
-struct traceeval *traceeval_2_alloc(const char *name, const struct traceeval_key_info kinfo[2]);
-
-int traceeval_sort_totals(struct traceeval *teval, bool ascending);
-int traceeval_sort_max(struct traceeval *teval, bool ascending);
-int traceeval_sort_min(struct traceeval *teval, bool ascending);
-int traceeval_sort_cnt(struct traceeval *teval, bool ascending);
-int traceeval_sort_keys(struct traceeval *teval, bool ascending);
-
-typedef int (*traceeval_cmp_func)(struct traceeval *teval,
- const struct traceeval_key_array *A,
- const struct traceeval_key_array *B,
- void *data);
-
-int traceeval_sort_custom(struct traceeval *teval, traceeval_cmp_func cmp, void *data);
-
-#endif /* __LIBTRACEEVAL_H__ */
+#define __TRACEEVAL_DATA(data_type, member, data) \
+ { .type = TRACEEVAL_TYPE_##data_type, .member = (data) }
+
+#define DEFINE_TRACEEVAL_NUMBER(data) __TRACEEVAL_DATA(NUMBER, number, data)
+#define DEFINE_TRACEEVAL_NUMBER_8(data) __TRACEEVAL_DATA(NUMBER_8, number_8, data)
+#define DEFINE_TRACEEVAL_NUMBER_16(data) __TRACEEVAL_DATA(NUMBER_16, number_16, data)
+#define DEFINE_TRACEEVAL_NUMBER_32(data) __TRACEEVAL_DATA(NUMBER_32, number_32, data)
+#define DEFINE_TRACEEVAL_NUMBER_64(data) __TRACEEVAL_DATA(NUMBER_64, number_64, data)
+#define DEFINE_TRACEEVAL_STRING(data) __TRACEEVAL_DATA(STRING, string, data)
+#define DEFINE_TRACEEVAL_CSTRING(data) __TRACEEVAL_DATA(STRING, cstring, data)
+#define DEFINE_TRACEEVAL_POINTER(data) __TRACEEVAL_DATA(POINTER, pointer, data)
+
+#define __TRACEEVAL_SET(data, data_type, member, val) \
+ do { \
+ (data).type = TRACEEVAL_TYPE_##data_type; \
+ (data).member = (val); \
+ } while (0)
+
+#define TRACEEVAL_SET_NUMBER(data, val) __TRACEEVAL_SET(data, NUMBER, number, val)
+#define TRACEEVAL_SET_NUMBER_8(data, val) __TRACEEVAL_SET(data, NUMBER_8, number_8, val)
+#define TRACEEVAL_SET_NUMBER_16(data, val) __TRACEEVAL_SET(data, NUMBER_16, number_16, val)
+#define TRACEEVAL_SET_NUMBER_32(data, val) __TRACEEVAL_SET(data, NUMBER_32, number_32, val)
+#define TRACEEVAL_SET_NUMBER_64(data, val) __TRACEEVAL_SET(data, NUMBER_64, number_64, val)
+#define TRACEEVAL_SET_STRING(data, val) __TRACEEVAL_SET(data, STRING, string, val)
+#define TRACEEVAL_SET_CSTRING(data, val) __TRACEEVAL_SET(data, STRING, cstring, val)
+#define TRACEEVAL_SET_POINTER(data, val) __TRACEEVAL_SET(data, POINTER, pointer, val)
+
+struct traceeval_type;
+struct traceeval;
+
+/* release function callback on traceeval_data */
+typedef void (*traceeval_data_release_fn)(const struct traceeval_type *type,
+ struct traceeval_data *data);
+
+/* compare function callback to compare traceeval_data */
+typedef int (*traceeval_data_cmp_fn)(struct traceeval *teval,
+ const struct traceeval_type *type,
+ const struct traceeval_data *A,
+ const struct traceeval_data *B);
+
+/* make a unique value */
+typedef int (*traceeval_data_hash_fn)(struct traceeval *teval,
+ const struct traceeval_type *type,
+ const struct traceeval_data *data);
+
+typedef int (*traceeval_data_copy_fn)(const struct traceeval_type *type,
+ struct traceeval_data *dst,
+ const struct traceeval_data *src);
+
+typedef int (*traceeval_cmp_fn)(struct traceeval *teval,
+ const struct traceeval_data *Akeys,
+ const struct traceeval_data *Avals,
+ const struct traceeval_data *Bkeys,
+ const struct traceeval_data *Bvals,
+ void *data);
+
+/*
+ * struct traceeval_type - Describes the type of a traceevent_data instance
+ * @type: The enum type that describes the traceeval_data
+ * @name: The string name of the traceeval_data
+ * @flags: flags to describe the traceeval_data
+ * @id: User specified identifier
+ * @release: An optional callback for when the data is being released
+ * @cmp: An optional callback to specify a way to compare the type
+ *
+ * The traceeval_type structure defines expectations for a corresponding
+ * traceeval_data instance for a traceeval histogram instance. Used to
+ * describe both keys and values.
+ *
+ * The @id field is an optional value in case the user has multiple struct
+ * traceeval_type instances and needs to distinguish between them into
+ * 'sub-types'.
+ *
+ * For flexibility, @cmp() and @release() take a struct traceeval_type
+ * instance. This allows the user to handle pointer types.
+ * It may also be used for other types if the default cmp() or release()
+ * need to be overridden. Note for string types, even if the release()
+ * is called, the string freeing is still taken care of by the traceeval
+ * infrastructure.
+ *
+ * The @id field is a user specified field that may allow the same callback
+ * to be used by multiple types and not needing to do a strcmp() against the
+ * name (could be used for switch statements).
+ *
+ * @cmp() is used to override the default compare of a type. This is
+ * required to pointer types. It should return 0 on equality, 1 if the first
+ * argument is greater than the second, -1 for the other way around,
+ * and -2 on error.
+ *
+ * @release() is called when a data element is being released (or freed).
+ */
+struct traceeval_type {
+ char *name;
+ enum traceeval_data_type type;
+ size_t flags;
+ size_t index;
+ size_t id;
+ traceeval_data_release_fn release;
+ traceeval_data_cmp_fn cmp;
+ traceeval_data_copy_fn copy;
+ traceeval_data_hash_fn hash;
+};
+
+/* Statistics about a given entry element */
+struct traceeval_stat;
+
+/* Iterator over aggregated data */
+struct traceeval_iterator;
+
+struct traceeval;
+
+/* Histogram interfaces */
+
+#define traceeval_init(keys, vals) \
+ traceeval_init_size(keys, vals, \
+ TRACEEVAL_ARRAY_SIZE(keys), \
+ (void *)vals == NULL ? 0 : TRACEEVAL_ARRAY_SIZE(vals))
+
+#define traceeval_init_size(keys, vals, nr_keys, nr_vals) \
+ traceeval_init_data_size(keys, vals, nr_keys, nr_vals, \
+ sizeof(struct traceeval_type), \
+ sizeof(struct traceeval_data))
+
+struct traceeval *traceeval_init_data_size(struct traceeval_type *keys,
+ struct traceeval_type *vals,
+ size_t nr_keys, size_t nr_vals,
+ size_t sizeof_type, size_t sizeof_data);
+
+void traceeval_release(struct traceeval *teval);
+
+int traceeval_insert_size(struct traceeval *teval,
+ const struct traceeval_data *keys, size_t nr_keys,
+ const struct traceeval_data *vals, size_t nr_vals);
+
+#define traceeval_insert(teval, keys, vals) \
+ traceeval_insert_size(teval, keys, TRACEEVAL_ARRAY_SIZE(keys), \
+ vals, (void *)vals == NULL ? 0 : TRACEEVAL_ARRAY_SIZE(vals))
+
+int traceeval_remove_size(struct traceeval *teval,
+ const struct traceeval_data *keys, size_t nr_keys);
+
+#define traceeval_remove(teval, keys) \
+ traceeval_remove_size(teval, keys, TRACEEVAL_ARRAY_SIZE(keys))
+
+int traceeval_query_size(struct traceeval *teval, const struct traceeval_data *keys,
+ size_t nr_keys, const struct traceeval_data **results);
+
+#define traceeval_query(teval, keys, results) \
+ traceeval_query_size(teval, keys, TRACEEVAL_ARRAY_SIZE(keys), results)
+
+void traceeval_results_release(struct traceeval *teval,
+ const struct traceeval_data *results);
+
+size_t traceeval_count(struct traceeval *teval);
+
+#define traceeval_stat(teval, keys, type) \
+ traceeval_stat_size(teval, keys, TRACEEVAL_ARRAY_SIZE(keys), type)
+
+struct traceeval_stat *traceeval_stat_size(struct traceeval *teval,
+ const struct traceeval_data *keys,
+ size_t nr_keys,
+ struct traceeval_type *type);
+
+unsigned long long traceeval_stat_max(struct traceeval_stat *stat);
+unsigned long long traceeval_stat_min(struct traceeval_stat *stat);
+unsigned long long traceeval_stat_total(struct traceeval_stat *stat);
+unsigned long long traceeval_stat_count(struct traceeval_stat *stat);
+
+struct traceeval_iterator *traceeval_iterator_get(struct traceeval *teval);
+void traceeval_iterator_put(struct traceeval_iterator *iter);
+int traceeval_iterator_sort(struct traceeval_iterator *iter, const char *sort_field,
+ int level, bool ascending);
+int traceeval_iterator_sort_custom(struct traceeval_iterator *iter,
+ traceeval_cmp_fn sort_fn, void *data);
+int traceeval_iterator_next(struct traceeval_iterator *iter,
+ const struct traceeval_data **keys);
+int traceeval_iterator_query(struct traceeval_iterator *iter,
+ const struct traceeval_data **results);
+void traceeval_iterator_results_release(struct traceeval_iterator *iter,
+ const struct traceeval_data *results);
+struct traceeval_stat *traceeval_iterator_stat(struct traceeval_iterator *iter,
+ struct traceeval_type *type);
+int traceeval_iterator_remove(struct traceeval_iterator *iter);
+
+#endif /* __LIBTRACEEVAL_HIST_H__ */
deleted file mode 100644
@@ -1,805 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright (C) 2022 Google Inc, Steven Rostedt <rostedt@goodmis.org>
- */
-#include <string.h>
-#include <errno.h>
-#include <traceeval.h>
-
-#define HASH_BITS 10
-#define HASH_SIZE (1 << HASH_BITS)
-#define HASH_MASK (HASH_SIZE - 1)
-
-enum sort_type {
- NONE,
- KEYS,
- TOTALS,
- MAX,
- MIN,
- CNT,
-};
-
-struct traceeval_key_info_array {
- size_t nr_keys;
- struct traceeval_key_info *keys;
-};
-
-struct eval_instance {
- unsigned long long total;
- unsigned long long last;
- unsigned long long max;
- unsigned long long min;
- unsigned long long cnt;
- size_t nr_keys;
- struct traceeval_key *keys;
- void *private;
-};
-
-struct eval_hash {
- struct eval_hash *next;
- struct eval_instance eval;
-};
-
-struct traceeval {
- struct traceeval_key_info_array array;
- struct eval_instance *evals;
- struct eval_hash *eval_hash[HASH_SIZE];
- size_t nr_evals;
- struct eval_instance *results;
- enum sort_type sort_type;
-};
-
-struct traceeval_result_array {
- int nr_results;
- struct traceeval_result *results;
-};
-
-struct traceeval_key_info_array *traceeval_key_info_array_alloc(void)
-{
- struct traceeval_key_info_array *tarray;
-
- tarray = calloc(1, sizeof(*tarray));
- return tarray;
-}
-
-void traceeval_key_info_array_free(struct traceeval_key_info_array *tarray)
-{
- if (!tarray)
- return;
-
- free(tarray->keys);
- free(tarray);
-}
-
-int traceeval_key_info_array_add(struct traceeval_key_info_array *tarray,
- const struct traceeval_key_info *key)
-{
- size_t nr = tarray->nr_keys;
- struct traceeval_key_info *kinfo;
-
- kinfo = realloc(tarray->keys, sizeof(*kinfo) * (nr + 1));
- if (!kinfo)
- return -1;
-
- tarray->keys = kinfo;
- tarray->nr_keys++;
- tarray->keys[nr] = *key;
-
- return 0;
-}
-
-struct traceeval *
-traceeval_n_alloc(const char *name, const struct traceeval_key_info_array *keys)
-{
- struct traceeval *teval;
- int i;
-
- teval = calloc(1, sizeof(*teval));
- if (!teval)
- return NULL;
-
- teval->array.keys = calloc(keys->nr_keys, sizeof(*keys->keys));
- if (!teval->array.keys)
- goto fail;
-
- teval->array.nr_keys = keys->nr_keys;
-
- for (i = 0; i < keys->nr_keys; i++)
- teval->array.keys[i] = keys->keys[i];
-
- return teval;
- fail:
- free(teval);
- return NULL;
-}
-
-void traceeval_free(struct traceeval *teval)
-{
- struct eval_hash *ehash;
- int i;
- if (!teval)
- return;
-
- for (i = 0; i < HASH_SIZE; i++) {
- for (ehash = teval->eval_hash[i]; ehash; ) {
- struct eval_hash *tmp = ehash;
- ehash = ehash->next;
- free(tmp);
- }
- }
-
- free(teval->array.keys);
- free(teval->evals);
- free(teval);
-}
-
-static int cmp_keys(struct traceeval_key_info_array *tarray,
- const struct traceeval_key *A, const struct traceeval_key *B,
- int *err)
-{
- const struct traceeval_key_info *kinfo;
- unsigned long long A_val, B_val;
- int ret;
- int i;
-
- for (i = 0; i < tarray->nr_keys; i++) {
- kinfo = &tarray->keys[i];
-
- /* TBD arrays */
- if (kinfo->count) {
- *err = 1;
- return -1;
- }
-
- if (A[i].type != kinfo->type ||
- B[i].type != kinfo->type) {
- *err = 1;
- return -1;
- }
-
- switch (kinfo->type) {
- case TRACEEVAL_TYPE_STRING:
- ret = strcmp(A[i].string, B[i].string);
- if (ret)
- return ret;
- continue;
-
- case TRACEEVAL_TYPE_NUMBER:
- A_val = A[i].number;
- B_val = B[i].number;
- break;
- case TRACEEVAL_TYPE_NUMBER_64:
- A_val = A[i].number_64;
- B_val = B[i].number_64;
- break;
- case TRACEEVAL_TYPE_NUMBER_32:
- A_val = A[i].number_32;
- B_val = B[i].number_32;
- break;
- case TRACEEVAL_TYPE_NUMBER_16:
- A_val = A[i].number_16;
- B_val = B[i].number_16;
- break;
- case TRACEEVAL_TYPE_NUMBER_8:
- A_val = A[i].number_8;
- B_val = B[i].number_8;
- break;
- case TRACEEVAL_TYPE_ARRAY:
- default:
- *err = 1;
- return -1;
- }
- if (A_val > B_val)
- return 1;
- if (A_val < B_val)
- return -1;
- }
- return 0;
-}
-
-static int make_key(struct traceeval *teval, const struct traceeval_key *keys, int *err)
-{
- struct traceeval_key_info *kinfo;
- bool calc;
- int len, l;
- int ret = 0;
- int i;
-
- for (i = 0; i < teval->array.nr_keys; i++) {
- kinfo = &teval->array.keys[i];
-
- /* TBD arrays */
- if (kinfo->count) {
- *err = 1;
- return -1;
- }
-
- if (keys[i].type != kinfo->type) {
- *err = 1;
- return -1;
- }
-
- calc = false;
-
- switch (kinfo->type) {
- case TRACEEVAL_TYPE_STRING:
- len = strlen(keys[i].string);
-
- for (l = 0; l < len; l++) {
- unsigned int c = keys[i].string[l];
-
- ret += c << ((l & 3) * 8);
- }
-
- continue;
-
- case TRACEEVAL_TYPE_NUMBER_32:
- calc = true;
- /* fall though */
- case TRACEEVAL_TYPE_NUMBER:
- if (calc || sizeof(keys[i].number) == 4) {
- ret += keys[i].number;
- continue;
- }
- /* fall through */
- case TRACEEVAL_TYPE_NUMBER_64:
- ret += keys[i].number_64 >> 32;
- ret += keys[i].number_64 & ((1ULL << 32) - 1);
- break;
- break;
- case TRACEEVAL_TYPE_NUMBER_16:
- ret += keys[i].number_16;
- break;
- case TRACEEVAL_TYPE_NUMBER_8:
- ret += keys[i].number_8;
- break;
- case TRACEEVAL_TYPE_ARRAY:
- default:
- *err = 1;
- return -1;
- }
- }
- return ret & HASH_MASK;
-}
-
-static struct eval_hash *find_eval(struct traceeval *teval, const struct traceeval_key *keys,
- int *err, int *pkey)
-{
- struct eval_hash *ehash;
- int key = make_key(teval, keys, err);
-
- if (key < 0)
- return NULL;
-
- if (pkey)
- *pkey = key;
-
- for (ehash = teval->eval_hash[key]; ehash; ehash = ehash->next) {
- if (cmp_keys(&teval->array, keys, ehash->eval.keys, err) == 0)
- return ehash;
- }
- return NULL;
-}
-
-static struct eval_hash *
-insert_eval(struct traceeval *teval, const struct traceeval_key *keys, int key)
-{
- struct eval_instance *eval;
- struct eval_hash *ehash;
- int i;
-
- ehash = calloc(1, sizeof(*ehash));
- if (!ehash)
- return NULL;
-
- eval = &ehash->eval;
-
- eval->keys = calloc(teval->array.nr_keys, sizeof(*eval->keys));
- if (!eval->keys)
- return NULL;
- for (i = 0; i < teval->array.nr_keys; i++)
- eval->keys[i] = keys[i];
- eval->nr_keys = teval->array.nr_keys;
- teval->nr_evals++;
-
- ehash->next = teval->eval_hash[key];
- teval->eval_hash[key] = ehash;
-
- return ehash;
-}
-
-static struct eval_instance *
-get_eval_instance(struct traceeval *teval, const struct traceeval_key *keys)
-{
- struct eval_hash *ehash;
- int err = 0;
- int key = -1;
-
- ehash = find_eval(teval, keys, &err, &key);
- if (!ehash) {
- ehash = insert_eval(teval, keys, key);
- if (!ehash)
- return NULL;
- }
- return &ehash->eval;
-}
-
-int traceeval_n_start(struct traceeval *teval, const struct traceeval_key *keys,
- unsigned long long start)
-{
- struct eval_instance *eval;
-
- eval = get_eval_instance(teval, keys);
- if (!eval)
- return -1;
-
- eval->last = start;
- return 0;
-}
-
-int traceeval_n_continue(struct traceeval *teval, const struct traceeval_key *keys,
- unsigned long long start)
-{
- struct eval_instance *eval;
-
- eval = get_eval_instance(teval, keys);
- if (!eval)
- return -1;
-
- if (eval->last)
- return 0;
-
- eval->last = start;
- return 0;
-}
-
-int traceeval_n_set_private(struct traceeval *teval, const struct traceeval_key *keys,
- void *data)
-{
- struct eval_instance *eval;
-
- /* Setting an instance forces a creation of it */
- eval = get_eval_instance(teval, keys);
- if (!eval)
- return -1;
-
- eval->private = data;
- return 0;
-}
-
-void *traceeval_n_get_private(struct traceeval *teval, const struct traceeval_key *keys)
-{
- struct eval_hash *ehash;
- int err = 0;
-
- ehash = find_eval(teval, keys, &err, NULL);
- if (!ehash)
- return NULL;
- return ehash->eval.private;
-}
-
-int traceeval_n_stop(struct traceeval *teval, const struct traceeval_key *keys,
- unsigned long long stop)
-{
- struct eval_instance *eval;
- unsigned long long delta;
-
- eval = get_eval_instance(teval, keys);
- if (!eval)
- return -1;
-
- if (!eval->last)
- return 1;
-
- delta = stop - eval->last;
- eval->total += delta;
- if (!eval->min || eval->min > delta)
- eval->min = delta;
- if (eval->max < delta)
- eval->max = delta;
- eval->cnt++;
-
- eval->last = 0;
-
- return 0;
-}
-
-size_t traceeval_result_nr(struct traceeval *teval)
-{
- return teval->nr_evals;
-}
-
-size_t traceeval_key_array_nr(struct traceeval_key_array *karray)
-{
- struct eval_instance *eval = (struct eval_instance *)karray;
-
- if (!karray)
- return 0;
-
- return eval->nr_keys;
-}
-
-const struct traceeval_key *
-traceeval_key_array_indx(const struct traceeval_key_array *karray, size_t index)
-{
- struct eval_instance *eval = (struct eval_instance *)karray;
-
- if (!karray || index >= eval->nr_keys)
- return NULL;
-
- return &eval->keys[index];
-}
-
-static int create_results(struct traceeval *teval)
-{
- struct eval_hash *ehash;
- int r = 0;
- int i;
-
- if (teval->results)
- return 0;
-
- teval->results = calloc(teval->nr_evals, sizeof(*teval->results));
- if (!teval->results)
- return -1;
-
- for (i = 0; i < HASH_SIZE; i++) {
- for (ehash = teval->eval_hash[i]; ehash; ehash = ehash->next) {
- teval->results[r++] = ehash->eval;
- }
- }
- return 0;
-}
-
-static int eval_sort(struct traceeval *teval, enum sort_type sort_type, bool ascending);
-
-static struct eval_instance *get_result(struct traceeval *teval, size_t index)
-{
- if (index >= teval->nr_evals)
- return NULL;
-
- if (!teval->results) {
- create_results(teval);
- if (!teval->results)
- return NULL;
- eval_sort(teval, KEYS, true);
- }
-
- if (teval->results)
- return &teval->results[index];
-
- return &teval->evals[index];
-}
-
-struct traceeval_key_array *
-traceeval_result_indx_key_array(struct traceeval *teval, size_t index)
-{
- struct eval_instance *eval = get_result(teval, index);
-
- if (!eval)
- return NULL;
-
- return (struct traceeval_key_array *)eval;
-}
-
-ssize_t
-traceeval_result_indx_cnt(struct traceeval *teval, size_t index)
-{
- struct eval_instance *eval = get_result(teval, index);
-
- if (!eval)
- return -1;
-
- return eval->cnt;
-}
-
-ssize_t
-traceeval_result_indx_total(struct traceeval *teval, size_t index)
-{
- struct eval_instance *eval = get_result(teval, index);
-
- if (!eval)
- return -1;
-
- return eval->total;
-}
-
-ssize_t
-traceeval_result_indx_max(struct traceeval *teval, size_t index)
-{
- struct eval_instance *eval = get_result(teval, index);
-
- if (!eval)
- return -1;
-
- return eval->max;
-}
-
-ssize_t
-traceeval_result_indx_min(struct traceeval *teval, size_t index)
-{
- struct eval_instance *eval = get_result(teval, index);
-
- if (!eval)
- return -1;
-
- return eval->min;
-}
-
-
-ssize_t
-traceeval_result_keys_cnt(struct traceeval *teval, const struct traceeval_key *keys)
-{
- struct eval_hash *ehash;
- int err = 0;
-
- ehash = find_eval(teval, keys, &err, NULL);
- if (!ehash)
- return -1;
- return ehash->eval.cnt;
-}
-
-ssize_t
-traceeval_result_keys_total(struct traceeval *teval, const struct traceeval_key *keys)
-{
- struct eval_hash *ehash;
- int err = 0;
-
- ehash = find_eval(teval, keys, &err, NULL);
- if (!ehash)
- return -1;
- return ehash->eval.total;
-}
-
-ssize_t
-traceeval_result_keys_max(struct traceeval *teval, const struct traceeval_key *keys)
-{
- struct eval_hash *ehash;
- int err = 0;
-
- ehash = find_eval(teval, keys, &err, NULL);
- if (!ehash)
- return -1;
- return ehash->eval.max;
-}
-
-ssize_t
-traceeval_result_keys_min(struct traceeval *teval, const struct traceeval_key *keys)
-{
- struct eval_hash *ehash;
- int err = 0;
-
- ehash = find_eval(teval, keys, &err, NULL);
- if (!ehash)
- return -1;
- return ehash->eval.min;
-}
-
-struct traceeval *
-traceeval_1_alloc(const char *name, const struct traceeval_key_info kinfo[1])
-{
- struct traceeval_key_info key[1] = { kinfo[0] };
- struct traceeval_key_info_array karray = {
- .nr_keys = 1,
- .keys = key,
- };
-
- return traceeval_n_alloc(name, &karray);
-}
-
-int traceeval_1_start(struct traceeval *teval, struct traceeval_key key,
- unsigned long long start)
-{
- struct traceeval_key keys[1] = { key };
-
- return traceeval_n_start(teval, keys, start);
-}
-
-int traceeval_1_continue(struct traceeval *teval, struct traceeval_key key,
- unsigned long long start)
-{
- struct traceeval_key keys[1] = { key };
-
- return traceeval_n_continue(teval, keys, start);
-}
-
-int traceeval_1_set_private(struct traceeval *teval, struct traceeval_key key,
- void *data)
-{
- struct traceeval_key keys[1] = { key };
-
- return traceeval_n_set_private(teval, keys, data);
-}
-
-void *traceeval_1_get_private(struct traceeval *teval, struct traceeval_key key)
-{
- struct traceeval_key keys[1] = { key };
-
- return traceeval_n_get_private(teval, keys);
-}
-
-int traceeval_1_stop(struct traceeval *teval, struct traceeval_key key,
- unsigned long long stop)
-{
- struct traceeval_key keys[1] = { key };
-
- return traceeval_n_stop(teval, keys, stop);
-}
-
-struct traceeval *
-traceeval_2_alloc(const char *name, const struct traceeval_key_info kinfo[2])
-{
- struct traceeval_key_info key[2] = { kinfo[0], kinfo[1] };
- struct traceeval_key_info_array karray = {
- .nr_keys = 2,
- .keys = key,
- };
-
- return traceeval_n_alloc(name, &karray);
-}
-
-static int cmp_totals(const void *A, const void *B)
-{
- const struct eval_instance *a = A;
- const struct eval_instance *b = B;
-
- if (a->total < b->total)
- return -1;
- return a->total > b->total;
-}
-
-static int cmp_max(const void *A, const void *B)
-{
- const struct eval_instance *a = A;
- const struct eval_instance *b = B;
-
- if (a->max < b->max)
- return -1;
- return a->max > b->max;
-}
-
-static int cmp_min(const void *A, const void *B)
-{
- const struct eval_instance *a = A;
- const struct eval_instance *b = B;
-
- if (a->min < b->min)
- return -1;
- return a->min > b->min;
-}
-
-static int cmp_cnt(const void *A, const void *B)
-{
- const struct eval_instance *a = A;
- const struct eval_instance *b = B;
-
- if (a->cnt < b->cnt)
- return -1;
- return a->cnt > b->cnt;
-}
-
-static int cmp_inverse(const void *A, const void *B, void *cmp)
-{
- int (*cmp_func)(const void *, const void *) = cmp;
-
- return cmp_func(B, A);
-}
-
-static int cmp_evals(const void *A, const void *B, void *data)
-{
- const struct eval_instance *a = A;
- const struct eval_instance *b = B;
- struct traceeval *teval = data;
- int err;
-
- return cmp_keys(&teval->array, a->keys, b->keys, &err);
-}
-
-static int cmp_evals_dec(const void *A, const void *B, void *data)
-{
- struct traceeval *teval = data;
- int err;
-
- return cmp_keys(&teval->array, B, A, &err);
-}
-
-static int eval_sort(struct traceeval *teval, enum sort_type sort_type, bool ascending)
-{
- int (*cmp_func)(const void *, const void *);
-
- if (create_results(teval) < 0)
- return -1;
-
- if (teval->sort_type == sort_type)
- return 0;
-
- switch (sort_type) {
- case TOTALS:
- cmp_func = cmp_totals;
- break;
- case MAX:
- cmp_func = cmp_max;
- break;
- case MIN:
- cmp_func = cmp_min;
- break;
- case CNT:
- cmp_func = cmp_cnt;
- break;
- case NONE:
- case KEYS:
- if (ascending) {
- qsort_r(teval->results, teval->nr_evals,
- sizeof(*teval->results), cmp_evals, teval);
- } else {
- qsort_r(teval->results, teval->nr_evals,
- sizeof(*teval->results), cmp_evals_dec, teval);
- }
- return 0;
- }
-
- if (ascending)
- qsort(teval->results, teval->nr_evals, sizeof(*teval->results), cmp_func);
- else
- qsort_r(teval->results, teval->nr_evals, sizeof(*teval->results),
- cmp_inverse, cmp_func);
- teval->sort_type = sort_type;
- return 0;
-}
-
-int traceeval_sort_totals(struct traceeval *teval, bool ascending)
-{
- return eval_sort(teval, TOTALS, ascending);
-}
-
-int traceeval_sort_max(struct traceeval *teval, bool ascending)
-{
- return eval_sort(teval, MAX, ascending);
-}
-
-int traceeval_sort_min(struct traceeval *teval, bool ascending)
-{
- return eval_sort(teval, MIN, ascending);
-}
-
-int traceeval_sort_cnt(struct traceeval *teval, bool ascending)
-{
- return eval_sort(teval, CNT, ascending);
-}
-
-struct cmp_data {
- struct traceeval *teval;
- traceeval_cmp_func func;
- void *data;
-};
-
-static int cmp_custom(const void *A, const void *B, void *data)
-{
- const struct traceeval_key_array *a = A;
- const struct traceeval_key_array *b = B;
- struct cmp_data *cdata = data;
-
- return cdata->func(cdata->teval, a, b, cdata->data);
-}
-
-int traceeval_sort_custom(struct traceeval *teval, traceeval_cmp_func cmp, void *data)
-{
- struct cmp_data cdata;
-
- if (create_results(teval) < 0)
- return -1;
-
- cdata.teval = teval;
- cdata.func = cmp;
- cdata.data = data;
-
- qsort_r(teval->results, teval->nr_evals,
- sizeof(*teval->results), cmp_custom, &cdata);
-
- return 0;
-}
-
-int traceeval_sort_keys(struct traceeval *teval, bool ascending)
-{
- return eval_sort(teval, KEYS, ascending);
-}