dovecot-2.2: lib-storage: Moved mail_search_args_simplify() to i...

dovecot at dovecot.org dovecot at dovecot.org
Thu Apr 23 16:31:23 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/faa7d6c473f7
changeset: 18458:faa7d6c473f7
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Apr 23 19:29:43 2015 +0300
description:
lib-storage: Moved mail_search_args_simplify() to its own file and added unit tests.
No functional changes.

diffstat:

 src/lib-storage/Makefile.am                      |   10 +
 src/lib-storage/mail-search-args-simplify.c      |  156 +++++++++++++++++++++++
 src/lib-storage/mail-search.c                    |  152 ----------------------
 src/lib-storage/test-mail-search-args-simplify.c |   80 +++++++++++
 4 files changed, 246 insertions(+), 152 deletions(-)

diffs (truncated from 440 to 300 lines):

diff -r de60c42e6ad6 -r faa7d6c473f7 src/lib-storage/Makefile.am
--- a/src/lib-storage/Makefile.am	Thu Apr 23 19:28:04 2015 +0300
+++ b/src/lib-storage/Makefile.am	Thu Apr 23 19:29:43 2015 +0300
@@ -29,6 +29,7 @@
 	mail-namespace.c \
 	mail-search.c \
 	mail-search-args-imap.c \
+	mail-search-args-simplify.c \
 	mail-search-build.c \
 	mail-search-parser.c \
 	mail-search-parser-imap.c \
@@ -98,6 +99,7 @@
 
 test_programs = \
 	test-mail-search-args-imap \
+	test-mail-search-args-simplify \
 	test-mailbox-get
 
 noinst_PROGRAMS = $(test_programs)
@@ -114,6 +116,14 @@
 	libstorage.la \
 	$(LIBDOVECOT_DEPS)
 
+test_mail_search_args_simplify_SOURCES = test-mail-search-args-simplify.c
+test_mail_search_args_simplify_LDADD = \
+	$(LIBDOVECOT_STORAGE) \
+	$(LIBDOVECOT)
+test_mail_search_args_simplify_DEPENDENCIES = \
+	libstorage.la \
+	$(LIBDOVECOT_DEPS)
+
 test_mailbox_get_SOURCES = test-mailbox-get.c
 test_mailbox_get_LDADD = mailbox-get.lo $(test_libs)
 test_mailbox_get_DEPENDENCIES = $(noinst_LTLIBRARIES) $(test_libs)
diff -r de60c42e6ad6 -r faa7d6c473f7 src/lib-storage/mail-search-args-simplify.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/mail-search-args-simplify.c	Thu Apr 23 19:29:43 2015 +0300
@@ -0,0 +1,156 @@
+/* Copyright (c) 2002-2015 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "mail-search.h"
+
+static void
+mail_search_args_simplify_sub(struct mailbox *box,
+			      struct mail_search_arg *args, bool parent_and)
+{
+	struct mail_search_arg *sub, *prev = NULL;
+	struct mail_search_arg *prev_flags_arg, *prev_not_flags_arg;
+
+	prev_flags_arg = prev_not_flags_arg = NULL;
+	while (args != NULL) {
+		if (args->match_not && (args->type == SEARCH_SUB ||
+					args->type == SEARCH_OR)) {
+			/* neg(p and q and ..) == neg(p) or neg(q) or ..
+			   neg(p or q or ..) == neg(p) and neg(q) and .. */
+			args->type = args->type == SEARCH_SUB ?
+				SEARCH_OR : SEARCH_SUB;
+			args->match_not = FALSE;
+			sub = args->value.subargs;
+			do {
+				sub->match_not = !sub->match_not;
+				sub = sub->next;
+			} while (sub != NULL);
+		}
+
+		if ((args->type == SEARCH_SUB && parent_and) ||
+		    (args->type == SEARCH_OR && !parent_and) ||
+		    ((args->type == SEARCH_SUB || args->type == SEARCH_OR) &&
+		     args->value.subargs->next == NULL)) {
+			/* p and (q and ..) == p and q and ..
+			   p or (q or ..) == p or q or ..
+			   (p) = p */
+			sub = args->value.subargs;
+			for (; sub->next != NULL; sub = sub->next) ;
+			sub->next = args->next;
+			*args = *args->value.subargs;
+			continue;
+		}
+
+		if (args->type == SEARCH_SUB ||
+		    args->type == SEARCH_OR ||
+		    args->type == SEARCH_INTHREAD) {
+			mail_search_args_simplify_sub(box, args->value.subargs,
+						      args->type != SEARCH_OR);
+		}
+
+		/* merge all flags arguments */
+		if (args->type == SEARCH_FLAGS &&
+		    !args->match_not && parent_and) {
+			if (prev_flags_arg == NULL)
+				prev_flags_arg = args;
+			else {
+				prev_flags_arg->value.flags |=
+					args->value.flags;
+				prev->next = args->next;
+				args = args->next;
+				continue;
+			}
+		} else if (args->type == SEARCH_FLAGS && args->match_not &&
+			   !parent_and) {
+			if (prev_not_flags_arg == NULL)
+				prev_not_flags_arg = args;
+			else {
+				prev_not_flags_arg->value.flags |=
+					args->value.flags;
+				prev->next = args->next;
+				args = args->next;
+				continue;
+			}
+		}
+
+		prev = args;
+		args = args->next;
+	}
+}
+
+static bool
+mail_search_args_unnest_inthreads(struct mail_search_args *args,
+				  struct mail_search_arg **argp,
+				  bool parent_inthreads, bool parent_and)
+{
+	struct mail_search_arg *arg, *thread_arg, *or_arg;
+	bool child_inthreads = FALSE, non_inthreads = FALSE;
+
+	for (arg = *argp; arg != NULL; arg = arg->next) {
+		switch (arg->type) {
+		case SEARCH_SUB:
+		case SEARCH_OR:
+			if (!mail_search_args_unnest_inthreads(args,
+					&arg->value.subargs, parent_inthreads,
+					arg->type != SEARCH_OR)) {
+				arg->result = 1;
+				child_inthreads = TRUE;
+			} else {
+				arg->result = 0;
+				non_inthreads = TRUE;
+			}
+			break;
+		case SEARCH_INTHREAD:
+			if (mail_search_args_unnest_inthreads(args,
+					&arg->value.subargs, TRUE, TRUE)) {
+				/* children converted to SEARCH_INTHREADs */
+				arg->type = SEARCH_SUB;
+			}
+			args->have_inthreads = TRUE;
+			arg->result = 1;
+			child_inthreads = TRUE;
+			break;
+		default:
+			arg->result = 0;
+			non_inthreads = TRUE;
+			break;
+		}
+	}
+
+	if (!parent_inthreads || !child_inthreads || !non_inthreads)
+		return FALSE;
+
+	/* put all non-INTHREADs under a single INTHREAD */
+	thread_arg = p_new(args->pool, struct mail_search_arg, 1);
+	thread_arg->type = SEARCH_INTHREAD;
+
+	while (*argp != NULL) {
+		arg = *argp;
+		argp = &(*argp)->next;
+
+		if (arg->result == 0) {
+			/* not an INTHREAD or a SUB/OR with only INTHREADs */
+			arg->next = thread_arg->value.subargs;
+			thread_arg->value.subargs = arg;
+		}
+	}
+	if (!parent_and) {
+		/* We want to OR the args */
+		or_arg = p_new(args->pool, struct mail_search_arg, 1);
+		or_arg->type = SEARCH_OR;
+		or_arg->value.subargs = thread_arg->value.subargs;
+		thread_arg->value.subargs = or_arg;
+	}
+	return TRUE;
+}
+
+void mail_search_args_simplify(struct mail_search_args *args)
+{
+	args->simplified = TRUE;
+
+	mail_search_args_simplify_sub(args->box, args->args, TRUE);
+	if (mail_search_args_unnest_inthreads(args, &args->args,
+					      FALSE, TRUE)) {
+		/* we may have added some extra SUBs that could be dropped */
+		mail_search_args_simplify_sub(args->box, args->args, TRUE);
+	}
+}
diff -r de60c42e6ad6 -r faa7d6c473f7 src/lib-storage/mail-search.c
--- a/src/lib-storage/mail-search.c	Thu Apr 23 19:28:04 2015 +0300
+++ b/src/lib-storage/mail-search.c	Thu Apr 23 19:29:43 2015 +0300
@@ -587,158 +587,6 @@
 	return TRUE;
 }
 
-static void
-mail_search_args_simplify_sub(struct mailbox *box,
-			      struct mail_search_arg *args, bool parent_and)
-{
-	struct mail_search_arg *sub, *prev = NULL;
-	struct mail_search_arg *prev_flags_arg, *prev_not_flags_arg;
-
-	prev_flags_arg = prev_not_flags_arg = NULL;
-	while (args != NULL) {
-		if (args->match_not && (args->type == SEARCH_SUB ||
-					args->type == SEARCH_OR)) {
-			/* neg(p and q and ..) == neg(p) or neg(q) or ..
-			   neg(p or q or ..) == neg(p) and neg(q) and .. */
-			args->type = args->type == SEARCH_SUB ?
-				SEARCH_OR : SEARCH_SUB;
-			args->match_not = FALSE;
-			sub = args->value.subargs;
-			do {
-				sub->match_not = !sub->match_not;
-				sub = sub->next;
-			} while (sub != NULL);
-		}
-
-		if ((args->type == SEARCH_SUB && parent_and) ||
-		    (args->type == SEARCH_OR && !parent_and) ||
-		    ((args->type == SEARCH_SUB || args->type == SEARCH_OR) &&
-		     args->value.subargs->next == NULL)) {
-			/* p and (q and ..) == p and q and ..
-			   p or (q or ..) == p or q or ..
-			   (p) = p */
-			sub = args->value.subargs;
-			for (; sub->next != NULL; sub = sub->next) ;
-			sub->next = args->next;
-			*args = *args->value.subargs;
-			continue;
-		}
-
-		if (args->type == SEARCH_SUB ||
-		    args->type == SEARCH_OR ||
-		    args->type == SEARCH_INTHREAD) {
-			mail_search_args_simplify_sub(box, args->value.subargs,
-						      args->type != SEARCH_OR);
-		}
-
-		/* merge all flags arguments */
-		if (args->type == SEARCH_FLAGS &&
-		    !args->match_not && parent_and) {
-			if (prev_flags_arg == NULL)
-				prev_flags_arg = args;
-			else {
-				prev_flags_arg->value.flags |=
-					args->value.flags;
-				prev->next = args->next;
-				args = args->next;
-				continue;
-			}
-		} else if (args->type == SEARCH_FLAGS && args->match_not &&
-			   !parent_and) {
-			if (prev_not_flags_arg == NULL)
-				prev_not_flags_arg = args;
-			else {
-				prev_not_flags_arg->value.flags |=
-					args->value.flags;
-				prev->next = args->next;
-				args = args->next;
-				continue;
-			}
-		}
-
-		prev = args;
-		args = args->next;
-	}
-}
-
-static bool
-mail_search_args_unnest_inthreads(struct mail_search_args *args,
-				  struct mail_search_arg **argp,
-				  bool parent_inthreads, bool parent_and)
-{
-	struct mail_search_arg *arg, *thread_arg, *or_arg;
-	bool child_inthreads = FALSE, non_inthreads = FALSE;
-
-	for (arg = *argp; arg != NULL; arg = arg->next) {
-		switch (arg->type) {
-		case SEARCH_SUB:
-		case SEARCH_OR:
-			if (!mail_search_args_unnest_inthreads(args,
-					&arg->value.subargs, parent_inthreads,
-					arg->type != SEARCH_OR)) {
-				arg->result = 1;
-				child_inthreads = TRUE;
-			} else {
-				arg->result = 0;
-				non_inthreads = TRUE;
-			}
-			break;
-		case SEARCH_INTHREAD:
-			if (mail_search_args_unnest_inthreads(args,
-					&arg->value.subargs, TRUE, TRUE)) {


More information about the dovecot-cvs mailing list