From: "Steven Rostedt (Google)" <rostedt@xxxxxxxxxxx> Add an iterator where the application can supply the sort algorithm where it gets the teval descriptor along with the keys and values of both of the entries to compare against. Also, allow it to submit its own data to the compare function: int traceeval_iterator_sort_custom(struct traceeval_iterator *iter, traceeval_cmp_fn sort_fn, void *data); with typedef int (*traceeval_cmp_fn)(struct traceeval *teval, const union traceeval_data *Akeys, const union traceeval_data *Avals, const union traceeval_data *Bkeys, const union traceeval_data *Bvals, void *data); Signed-off-by: Steven Rostedt (Google) <rostedt@xxxxxxxxxxx> --- include/traceeval-hist.h | 9 +++++++++ src/histograms.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/include/traceeval-hist.h b/include/traceeval-hist.h index a87f39afc050..490cfd2a51a2 100644 --- a/include/traceeval-hist.h +++ b/include/traceeval-hist.h @@ -86,6 +86,13 @@ typedef int (*traceeval_data_copy_fn)(const struct traceeval_type *type, union traceeval_data *dst, const union traceeval_data *src); +typedef int (*traceeval_cmp_fn)(struct traceeval *teval, + const union traceeval_data *Akeys, + const union traceeval_data *Avals, + const union traceeval_data *Bkeys, + const union 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 @@ -172,6 +179,8 @@ 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 union traceeval_data **keys); diff --git a/src/histograms.c b/src/histograms.c index e6a15a25bba0..f9c52684b7dc 100644 --- a/src/histograms.c +++ b/src/histograms.c @@ -1160,6 +1160,41 @@ static int sort_iter(struct traceeval_iterator *iter) return 0; } +struct iter_custom_data { + struct traceeval_iterator *iter; + traceeval_cmp_fn sort_fn; + void *data; +}; + +static int iter_custom_cmp(const void *A, const void *B, void *data) +{ + struct iter_custom_data *cust_data = data; + struct traceeval_iterator *iter = cust_data->iter; + struct traceeval *teval = iter->teval; + const struct entry *a = *((const struct entry **)A); + const struct entry *b = *((const struct entry **)B); + + return cust_data->sort_fn(teval, a->keys, a->vals, b->keys, b->vals, + cust_data->data); +} + +int traceeval_iterator_sort_custom(struct traceeval_iterator *iter, + traceeval_cmp_fn sort_fn, void *data) +{ + struct iter_custom_data cust_data = { + .iter = iter, + .sort_fn = sort_fn, + .data = data + }; + + qsort_r(iter->entries, iter->nr_entries, sizeof(*iter->entries), + iter_custom_cmp, &cust_data); + + iter->needs_sort = false; + iter->next = 0; + return 0; +} + /** * traceeval_iterator_next - retrieve the next entry from an iterator * @iter: The iterator to retrieve the next entry from -- 2.40.1