dovecot-2.2: lib-storage: mail_search_args_simplify() handles no...
dovecot at dovecot.org
dovecot at dovecot.org
Sun Dec 6 18:49:16 UTC 2015
details: http://hg.dovecot.org/dovecot-2.2/rev/33465d1d595c
changeset: 19478:33465d1d595c
user: Timo Sirainen <tss at iki.fi>
date: Sun Dec 06 20:48:55 2015 +0200
description:
lib-storage: mail_search_args_simplify() handles now "(a OR b) AND (a OR c)" -> "a OR (b AND c)"
diffstat:
src/lib-storage/mail-search-args-simplify.c | 40 ++++++++++++++++-------
src/lib-storage/test-mail-search-args-simplify.c | 16 +++++++++
2 files changed, 44 insertions(+), 12 deletions(-)
diffs (134 lines):
diff -r 91b9510237fd -r 33465d1d595c src/lib-storage/mail-search-args-simplify.c
--- a/src/lib-storage/mail-search-args-simplify.c Sun Dec 06 20:46:52 2015 +0200
+++ b/src/lib-storage/mail-search-args-simplify.c Sun Dec 06 20:48:55 2015 +0200
@@ -290,7 +290,8 @@
*argp = (*argp)->next;
found = TRUE;
} else if (check_subs) {
- i_assert((*argp)->type == SEARCH_SUB);
+ i_assert((*argp)->type == SEARCH_SUB ||
+ (*argp)->type == SEARCH_OR);
if (!mail_search_args_remove_equal(&(*argp)->value.subargs, wanted_arg, FALSE)) {
/* we already verified that this should have
existed. */
@@ -377,8 +378,8 @@
}
static bool
-mail_search_args_simplify_extract_common_and(struct mail_search_arg **argsp,
- pool_t pool)
+mail_search_args_simplify_extract_common(struct mail_search_arg **argsp,
+ pool_t pool, bool and_arg)
{
/* Simple SUB example:
(a AND b) OR (a AND c) -> a AND (b OR c)
@@ -386,18 +387,28 @@
More complicated example:
(c1 AND c2 AND u1 AND u2) OR (c1 AND c2 AND u3 AND u4) ->
c1 AND c2 AND ((u1 AND u2) OR (u3 AND u4))
+
+ Similarly for ORs:
+ (a OR b) AND (a OR c) -> a OR (b AND c)
+
+ (c1 OR c2 OR u1 OR u2) AND (c1 OR c2 OR u3 OR u4) ->
+ c1 OR c2 OR ((u1 OR u2) AND (u3 OR u4))
+
*/
struct mail_search_arg *arg, *sub_arg, *sub_next;
struct mail_search_arg *new_arg, *child_arg, *common_args = NULL;
+ enum mail_search_arg_type child_subargs_type;
if ((*argsp)->next == NULL) {
/* single arg, nothing to extract */
return FALSE;
}
- /* find the first SEARCH_SUB */
+ child_subargs_type = and_arg ? SEARCH_OR : SEARCH_SUB;
+
+ /* find the first arg with child_subargs_type */
for (arg = *argsp; arg != NULL; arg = arg->next) {
- if (arg->type == SEARCH_SUB)
+ if (arg->type == child_subargs_type)
break;
}
if (arg == NULL)
@@ -410,7 +421,7 @@
for (arg = *argsp; arg != NULL; arg = arg->next) {
if (mail_search_arg_one_equals(arg, sub_arg)) {
/* the whole arg matches */
- } else if (arg->type == SEARCH_SUB &&
+ } else if (arg->type == child_subargs_type &&
mail_search_args_have_equal(arg->value.subargs, sub_arg)) {
/* exists as subarg */
} else {
@@ -430,14 +441,16 @@
/* replace all the original args with a single new SUB/OR arg */
new_arg = p_new(pool, struct mail_search_arg, 1);
- new_arg->type = SEARCH_SUB;
+ new_arg->type = child_subargs_type;
if (*argsp == NULL) {
/* there are only common args */
new_arg->value.subargs = common_args;
} else {
- /* replace OR arg with AND(common_args, OR(non_common_args)) */
+ /* replace OR arg with AND(OR(non_common_args), common_args)
+ or
+ replace AND arg with OR(AND(non_common_args), common_args) */
child_arg = p_new(pool, struct mail_search_arg, 1);
- child_arg->type = SEARCH_OR;
+ child_arg->type = and_arg ? SEARCH_SUB : SEARCH_OR;
child_arg->value.subargs = *argsp;
child_arg->next = common_args;
new_arg->value.subargs = child_arg;
@@ -497,10 +510,11 @@
i_assert(!args->match_not);
if (args->type != SEARCH_INTHREAD) {
- if (mail_search_args_simplify_drop_redundent_args(&args->value.subargs, args->type == SEARCH_SUB))
+ bool and_arg = args->type == SEARCH_SUB;
+
+ if (mail_search_args_simplify_drop_redundent_args(&args->value.subargs, and_arg))
ctx.removals = TRUE;
- if (args->type == SEARCH_OR &&
- mail_search_args_simplify_extract_common_and(&args->value.subargs, pool))
+ if (mail_search_args_simplify_extract_common(&args->value.subargs, pool, and_arg))
ctx.removals = TRUE;
}
if (mail_search_args_simplify_sub(box, pool, args->value.subargs,
@@ -635,6 +649,8 @@
for (;;) {
if (mail_search_args_simplify_drop_redundent_args(&args->args, TRUE))
removals = TRUE;
+ if (mail_search_args_simplify_extract_common(&args->args, args->pool, TRUE))
+ removals = TRUE;
if (!removals)
break;
removals = mail_search_args_simplify_sub(args->box, args->pool, args->args, TRUE);
diff -r 91b9510237fd -r 33465d1d595c src/lib-storage/test-mail-search-args-simplify.c
--- a/src/lib-storage/test-mail-search-args-simplify.c Sun Dec 06 20:46:52 2015 +0200
+++ b/src/lib-storage/test-mail-search-args-simplify.c Sun Dec 06 20:48:55 2015 +0200
@@ -129,6 +129,22 @@
{ "( OR TEXT common1 TEXT common2 ) ( OR TEXT common1 OR TEXT common2 TEXT unique1 )", "(OR TEXT common1 TEXT common2)" },
{ "TEXT common1 ( OR TEXT unique1 TEXT common1 ) ( OR TEXT unique3 TEXT common1 )", "TEXT common1" },
{ "OR ( TEXT common1 ( OR TEXT unique1 TEXT common1 ) ) TEXT unique1", "(OR TEXT common1 TEXT unique1)" },
+
+ /* SUB: extract common OR */
+ { "( OR TEXT common1 TEXT unique1 ) ( OR TEXT common1 TEXT unique2 )", "(OR (TEXT unique1 TEXT unique2) TEXT common1)" },
+ { "( OR TEXT unique1 TEXT common1 ) ( OR TEXT unique2 TEXT common1 )", "(OR (TEXT unique1 TEXT unique2) TEXT common1)" },
+ { "( OR TEXT common1 TEXT unique1 ) ( OR TEXT unique2 TEXT common1 )", "(OR (TEXT unique1 TEXT unique2) TEXT common1)" },
+ { "( OR TEXT unique1 TEXT common1 ) ( OR TEXT common1 TEXT unique2 )", "(OR (TEXT unique1 TEXT unique2) TEXT common1)" },
+
+ { "( OR TEXT unique1 TEXT common1 ) ( OR TEXT common1 OR TEXT unique2 TEXT unique3 )", "(OR (TEXT unique1 (OR TEXT unique2 TEXT unique3)) TEXT common1)" },
+ { "( OR TEXT common1 OR TEXT common2 TEXT unique1 ) ( OR TEXT common1 OR TEXT common2 TEXT unique2 )", "(OR (TEXT unique1 TEXT unique2) OR TEXT common2 TEXT common1)" },
+ { "( OR TEXT common1 OR TEXT common2 OR TEXT unique1 TEXT unique2 ) ( OR TEXT common1 OR TEXT common2 OR TEXT unique3 TEXT unique4 )", "(OR ((OR TEXT unique1 TEXT unique2) (OR TEXT unique3 TEXT unique4)) OR TEXT common2 TEXT common1)" },
+
+ /* non-matching cases */
+ { "( OR TEXT unique1 TEXT unique2 ) TEXT unique3", "(OR TEXT unique1 TEXT unique2) TEXT unique3" },
+ { "( OR TEXT unique1 TEXT unique2 ) ( OR TEXT unique3 TEXT unique4 )", "(OR TEXT unique1 TEXT unique2) (OR TEXT unique3 TEXT unique4)" },
+ { "( OR TEXT common1 TEXT unique1 ) ( OR TEXT common1 TEXT unique2 ) TEXT unique3", "(OR TEXT common1 TEXT unique1) (OR TEXT common1 TEXT unique2) TEXT unique3" },
+ { "( OR TEXT common1 TEXT unique1 ) ( OR TEXT common1 TEXT common2 ) ( OR TEXT common2 TEXT unique2 )", "(OR TEXT common1 TEXT unique1) (OR TEXT common1 TEXT common2) (OR TEXT common2 TEXT unique2)" },
};
static struct mail_search_args *
More information about the dovecot-cvs
mailing list