dovecot-2.2: lib-storage: mail_search_args_simplify() handles no...

dovecot at dovecot.org dovecot at dovecot.org
Sun Dec 6 16:12:42 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/8749308aad53
changeset: 19472:8749308aad53
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Dec 06 18:12:24 2015 +0200
description:
lib-storage: mail_search_args_simplify() handles now "a OR (a AND b)" -> "a"

diffstat:

 src/lib-storage/mail-search-args-simplify.c      |  80 ++++++++++++++++++++++++
 src/lib-storage/test-mail-search-args-simplify.c |   6 +
 2 files changed, 86 insertions(+), 0 deletions(-)

diffs (113 lines):

diff -r 91509e171e4b -r 8749308aad53 src/lib-storage/mail-search-args-simplify.c
--- a/src/lib-storage/mail-search-args-simplify.c	Sun Dec 06 18:09:17 2015 +0200
+++ b/src/lib-storage/mail-search-args-simplify.c	Sun Dec 06 18:12:24 2015 +0200
@@ -265,6 +265,82 @@
 }
 
 static bool
+mail_search_args_have_equal(const struct mail_search_arg *args,
+			    const struct mail_search_arg *wanted_arg)
+{
+	const struct mail_search_arg *arg;
+
+	for (arg = args; arg != NULL; arg = arg->next) {
+		if (mail_search_arg_one_equals(arg, wanted_arg))
+			return TRUE;
+	}
+	return FALSE;
+}
+
+static bool
+mail_search_args_have_all_equal(struct mail_search_arg *parent_arg,
+				const struct mail_search_arg *wanted_args)
+{
+	const struct mail_search_arg *arg;
+
+	i_assert(parent_arg->type == SEARCH_SUB);
+
+	for (arg = wanted_args; arg != NULL; arg = arg->next) {
+		if (!mail_search_args_have_equal(parent_arg->value.subargs, arg))
+			return FALSE;
+	}
+	return TRUE;
+}
+
+static unsigned int
+mail_search_args_count(const struct mail_search_arg *args)
+{
+	unsigned int count;
+
+	for (count = 0; args != NULL; count++)
+		args = args->next;
+	return count;
+}
+
+static bool
+mail_search_args_simplify_or_drop_redundent_args(struct mail_search_arg *parent_arg)
+{
+	struct mail_search_arg *arg, **argp, one_arg, *lowest_arg = NULL;
+	unsigned int count, lowest_count = UINT_MAX;
+	bool ret = FALSE;
+
+	/* find the arg which has the lowest number of child args */
+	for (arg = parent_arg->value.subargs; arg != NULL; arg = arg->next) {
+		if (arg->type != SEARCH_SUB) {
+			one_arg = *arg;
+			one_arg.next = NULL;
+			lowest_arg = &one_arg;
+			break;
+		}
+		count = mail_search_args_count(arg->value.subargs);
+		if (count < lowest_count) {
+			lowest_arg = arg->value.subargs;
+			lowest_count = count;
+		}
+	}
+	i_assert(lowest_arg != NULL);
+
+	/* if there are any args that include lowest_arg, drop the arg since
+	   it's redundant. (non-SUB duplicates are dropped elsewhere.) */
+	for (argp = &parent_arg->value.subargs; *argp != NULL; ) {
+		if (*argp != lowest_arg && (*argp)->type == SEARCH_SUB &&
+		    (*argp)->value.subargs != lowest_arg &&
+		    mail_search_args_have_all_equal(*argp, lowest_arg)) {
+			*argp = (*argp)->next;
+			ret = TRUE;
+		} else {
+			argp = &(*argp)->next;
+		}
+	}
+	return ret;
+}
+
+static bool
 mail_search_args_simplify_sub(struct mailbox *box,
 			      struct mail_search_arg *args, bool parent_and)
 {
@@ -311,6 +387,10 @@
 		if (args->type == SEARCH_SUB ||
 		    args->type == SEARCH_OR ||
 		    args->type == SEARCH_INTHREAD) {
+			if (args->type == SEARCH_OR) {
+				if (mail_search_args_simplify_or_drop_redundent_args(args))
+					ctx.removals = TRUE;
+			}
 			if (mail_search_args_simplify_sub(box, args->value.subargs,
 							  args->type != SEARCH_OR))
 				ctx.removals = TRUE;
diff -r 91509e171e4b -r 8749308aad53 src/lib-storage/test-mail-search-args-simplify.c
--- a/src/lib-storage/test-mail-search-args-simplify.c	Sun Dec 06 18:09:17 2015 +0200
+++ b/src/lib-storage/test-mail-search-args-simplify.c	Sun Dec 06 18:12:24 2015 +0200
@@ -96,6 +96,12 @@
 	{ "OR BODY foo BODY foo", "BODY foo" },
 	{ "TEXT foo BODY foo", "TEXT foo BODY foo" },
 	{ "OR ( TEXT foo OR TEXT foo TEXT foo ) ( TEXT foo ( TEXT foo ) )", "TEXT foo" },
+
+	{ "OR ( TEXT common1 TEXT unique1 ) TEXT common1", "TEXT common1" },
+	{ "OR ( TEXT unique1 TEXT common1 ) TEXT common1", "TEXT common1" },
+	{ "OR TEXT common1 ( TEXT common1 TEXT unique1 )", "TEXT common1" },
+	{ "OR TEXT common1 ( TEXT unique1 TEXT common1 )", "TEXT common1" },
+	{ "OR TEXT common1 OR ( TEXT unique1 TEXT common1 ) ( TEXT unique3 TEXT common1 )", "TEXT common1" },
 };
 
 static struct mail_search_args *


More information about the dovecot-cvs mailing list