All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stevie Alvarez <stevie.6strings@gmail.com>
To: linux-trace-devel@vger.kernel.org
Cc: "Stevie Alvarez (Google)" <stevie.6strings@gmail.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	Ross Zwisler <zwisler@google.com>
Subject: [PATCH 4/5] histograms: traceeval compare
Date: Fri, 28 Jul 2023 15:04:39 -0400	[thread overview]
Message-ID: <20230728190515.23088-4-stevie.6strings@gmail.com> (raw)
In-Reply-To: <20230728190515.23088-1-stevie.6strings@gmail.com>

From: "Stevie Alvarez (Google)" <stevie.6strings@gmail.com>

traceeval_compare() compares two struct traceeval instances for
equality. This suite of comparitors was made for testing purposes.

Signed-off-by: Stevie Alvarez (Google) <stevie.6strings@gmail.com>
---
 src/histograms.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 176 insertions(+), 2 deletions(-)

diff --git a/src/histograms.c b/src/histograms.c
index f46a0e0..5f1c7ef 100644
--- a/src/histograms.c
+++ b/src/histograms.c
@@ -20,6 +20,19 @@
 #define for_each_key(i, keys)	\
 	for (i = 0; (keys)[(i)].type != TRACEEVAL_TYPE_NONE; (i)++)
 
+/**
+ * Compare two integers of variable length.
+ *
+ * Return 0 if @a and @b are the same, 1 if @a is greater than @b, and -1
+ * if @b is greater than @a.
+ */
+#define compare_numbers_return(a, b)	\
+do {					\
+	if ((a) < (b))			\
+		return -1;		\
+	return (a) != (b);		\
+} while (0)				\
+
 /** A key-value pair */
 struct entry {
 	union traceeval_data	*keys;
@@ -56,10 +69,171 @@ static void print_err(const char *fmt, ...)
 	fprintf(stderr, "\n");
 }
 
-// TODO
+/**
+ * Return 0 if @orig and @copy are the same, 1 otherwise.
+ */
+static int compare_traceeval_type(struct traceeval_type *orig,
+		struct traceeval_type *copy)
+{
+	int o_name_null;
+	int c_name_null;
+
+	// same memory/null
+	if (orig == copy)
+		return 0;
+
+	size_t i = 0;
+	do {
+		if (orig[i].type != copy[i].type)
+			return 1;
+		if (orig[i].type == TRACEEVAL_TYPE_NONE)
+			return 0;
+		if (orig[i].flags != copy[i].flags)
+			return 1;
+		if (orig[i].id != copy[i].id)
+			return 1;
+		if (orig[i].dyn_release != copy[i].dyn_release)
+			return 1;
+		if (orig[i].dyn_cmp != copy[i].dyn_cmp)
+			return 1;
+
+		// make sure both names are same type
+		o_name_null = !orig[i].name;
+		c_name_null = !copy[i].name;
+		if (o_name_null != c_name_null)
+			return 1;
+		if (o_name_null)
+			continue;
+		if (strcmp(orig[i].name, copy[i].name) != 0)
+			return 1;
+	} while (orig[i++].type != TRACEEVAL_TYPE_NONE);
+
+	return 0;
+}
+
+/**
+ * Return 0 if @orig and @copy are the same, 1 if @orig is greater than @copy,
+ * -1 for the other way around, and -2 on error.
+ */
+static int compare_traceeval_data(union traceeval_data *orig,
+		const union traceeval_data *copy, struct traceeval_type *type)
+{
+	if (!orig || !copy)
+		return 1;
+
+	switch (type->type) {
+	case TRACEEVAL_TYPE_NONE:
+		/* There is no corresponding traceeval_data for TRACEEVAL_TYPE_NONE */
+		return -2;
+
+	case TRACEEVAL_TYPE_STRING:
+		int i = strcmp(orig->string, copy->string);
+		if (!i)
+			return 0;
+		if (i > 0)
+			return 1;
+		return -1;
+
+	case TRACEEVAL_TYPE_NUMBER:
+		compare_numbers_return(orig->number, copy->number);
+
+	case TRACEEVAL_TYPE_NUMBER_64:
+		compare_numbers_return(orig->number_64, copy->number_64);
+
+	case TRACEEVAL_TYPE_NUMBER_32:
+		compare_numbers_return(orig->number_32, copy->number_32);
+
+	case TRACEEVAL_TYPE_NUMBER_16:
+		compare_numbers_return(orig->number_16, copy->number_16);
+
+	case TRACEEVAL_TYPE_NUMBER_8:
+		compare_numbers_return(orig->number_8, copy->number_8);
+
+	case TRACEEVAL_TYPE_DYNAMIC:
+		return type->dyn_cmp(orig->dyn_data, copy->dyn_data, type);
+
+	default:
+		print_err("%d is out of range of enum traceeval_data_type", type->type);
+		return -2;
+	}
+}
+
+/**
+ * Compare arrays fo union traceeval_data's with respect to @def.
+ *
+ * Return 0 if @orig and @copy are the same, 1 if not, and -1 on error.
+ */
+static int compare_traceeval_data_set(union traceeval_data *orig,
+		const union traceeval_data *copy, struct traceeval_type *def)
+{
+	int i = 0;
+	int check;
+
+	// compare data arrays
+	for_each_key(i, def) {
+		if ((check = compare_traceeval_data(&orig[i], &copy[i], &def[i])))
+			goto fail_compare_data_set;
+	}
+
+	return 0;
+fail_compare_data_set:
+	if (check == -2)
+		return -1;
+	return 1;
+}
+
+/**
+ * Return 0 if @orig and @copy are the same, 1 if not, and -1 on error.
+ */
+static int compare_entries(struct entry *orig, struct entry *copy,
+		struct traceeval *teval)
+{
+	int check;
+
+	// compare keys
+	check = compare_traceeval_data_set(orig->keys, copy->keys,
+			teval->def_keys);
+	if (check)
+		return check;
+
+	// compare values
+	check = compare_traceeval_data_set(orig->vals, copy->vals,
+			teval->def_vals);
+	return check;
+}
+
+/**
+ * Return 0 if struct hist_table of @orig and @copy are the same, 1 if not,
+ * and -1 on error.
+ */
+static int compare_hist(struct traceeval *orig, struct traceeval *copy)
+{
+	struct hist_table *o_hist = orig->hist;
+	struct hist_table *c_hist = copy->hist;
+	int cnt = !(o_hist->nr_entries == c_hist->nr_entries);
+	if (cnt)
+		return 1;
+
+	for (size_t i = 0; i < o_hist->nr_entries; i++) {
+		// cmp each entry
+		compare_entries(&o_hist->map[i], &c_hist->map[i], orig);
+	}
+	return 0;	
+}
+
+/**
+ * Return 0 if @orig and @copy are the same, 1 if not, -1 if error.
+ */
 int traceeval_compare(struct traceeval *orig, struct traceeval *copy)
 {
-	return -1;
+	if ((!orig) || (!copy))
+		return -1;
+
+	int keys = compare_traceeval_type(orig->def_keys, copy->def_keys);
+	int vals = compare_traceeval_type(orig->def_vals, copy->def_vals);
+	int hists = compare_hist(orig, copy);
+
+	return (keys || vals || hists);
 }
 
 /**
-- 
2.41.0


  parent reply	other threads:[~2023-07-28 19:05 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-28 19:04 [PATCH 1/5] histograms: initial histograms interface Stevie Alvarez
2023-07-28 19:04 ` [PATCH 2/5] histograms: traceeval initialize Stevie Alvarez
2023-07-28 22:03   ` Steven Rostedt
2023-08-02 21:07   ` Ross Zwisler
2023-08-02 21:39     ` Steven Rostedt
2023-07-28 19:04 ` [PATCH 3/5] histograms: traceeval release Stevie Alvarez
2023-07-28 22:07   ` Steven Rostedt
2023-08-02 21:54   ` Ross Zwisler
2023-08-02 22:20     ` Steven Rostedt
2023-08-02 22:21   ` Steven Rostedt
2023-07-28 19:04 ` Stevie Alvarez [this message]
2023-07-28 22:25   ` [PATCH 4/5] histograms: traceeval compare Steven Rostedt
2023-08-02 22:51   ` Ross Zwisler
2023-07-28 19:04 ` [PATCH 5/5] histograms: Add struct traceeval unit tests Stevie Alvarez
2023-07-28 22:30   ` Steven Rostedt
2023-08-03 16:27   ` Ross Zwisler
2023-07-28 20:25 ` [PATCH 1/5] histograms: initial histograms interface Steven Rostedt
2023-07-31 20:53   ` Stevie Alvarez
2023-07-31 21:04     ` Steven Rostedt
2023-08-01 19:08   ` Stevie Alvarez
2023-08-01 19:29     ` Steven Rostedt
2023-08-01  0:36 ` Ross Zwisler
2023-08-01  1:25   ` Steven Rostedt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230728190515.23088-4-stevie.6strings@gmail.com \
    --to=stevie.6strings@gmail.com \
    --cc=linux-trace-devel@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=zwisler@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.