dovecot-2.2: lib-storage: mail_search_args_simplify() refactoring
dovecot at dovecot.org
dovecot at dovecot.org
Sun Dec 6 18:49:15 UTC 2015
details: http://hg.dovecot.org/dovecot-2.2/rev/91b9510237fd
changeset: 19477:91b9510237fd
user: Timo Sirainen <tss at iki.fi>
date: Sun Dec 06 20:46:52 2015 +0200
description:
lib-storage: mail_search_args_simplify() refactoring
Removed parent_arg from mail_search_args_simplify_extract_common_and() in
preperation for the next changeset.
diffstat:
src/lib-storage/mail-search-args-simplify.c | 53 ++++++++++++++---------
src/lib-storage/test-mail-search-args-simplify.c | 2 +-
2 files changed, 34 insertions(+), 21 deletions(-)
diffs (134 lines):
diff -r d68d1c95b52c -r 91b9510237fd src/lib-storage/mail-search-args-simplify.c
--- a/src/lib-storage/mail-search-args-simplify.c Sun Dec 06 19:27:45 2015 +0200
+++ b/src/lib-storage/mail-search-args-simplify.c Sun Dec 06 20:46:52 2015 +0200
@@ -278,20 +278,20 @@
}
static bool
-mail_search_args_remove_equal(struct mail_search_arg *parent_arg,
+mail_search_args_remove_equal(struct mail_search_arg **argsp,
const struct mail_search_arg *wanted_arg,
bool check_subs)
{
struct mail_search_arg **argp;
bool found = FALSE;
- for (argp = &parent_arg->value.subargs; (*argp) != NULL; ) {
+ for (argp = argsp; (*argp) != NULL; ) {
if (mail_search_arg_one_equals(*argp, wanted_arg)) {
*argp = (*argp)->next;
found = TRUE;
} else if (check_subs) {
i_assert((*argp)->type == SEARCH_SUB);
- if (!mail_search_args_remove_equal(*argp, wanted_arg, FALSE)) {
+ if (!mail_search_args_remove_equal(&(*argp)->value.subargs, wanted_arg, FALSE)) {
/* we already verified that this should have
existed. */
i_unreached();
@@ -377,17 +377,26 @@
}
static bool
-mail_search_args_simplify_extract_common_and(struct mail_search_arg *parent_arg,
+mail_search_args_simplify_extract_common_and(struct mail_search_arg **argsp,
pool_t pool)
{
+ /* Simple SUB example:
+ (a AND b) OR (a AND c) -> a AND (b OR c)
+
+ 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))
+ */
struct mail_search_arg *arg, *sub_arg, *sub_next;
- struct mail_search_arg *or_arg, *common_args = NULL;
+ struct mail_search_arg *new_arg, *child_arg, *common_args = NULL;
- i_assert(parent_arg->type == SEARCH_OR);
- i_assert(!parent_arg->match_not);
+ if ((*argsp)->next == NULL) {
+ /* single arg, nothing to extract */
+ return FALSE;
+ }
/* find the first SEARCH_SUB */
- for (arg = parent_arg->value.subargs; arg != NULL; arg = arg->next) {
+ for (arg = *argsp; arg != NULL; arg = arg->next) {
if (arg->type == SEARCH_SUB)
break;
}
@@ -398,7 +407,7 @@
sub_next = sub_arg->next;
/* check if sub_arg is found from all the args */
- for (arg = parent_arg->value.subargs; arg != NULL; arg = arg->next) {
+ 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 &&
@@ -412,26 +421,28 @@
continue;
/* extract the arg and put it to common_args */
- mail_search_args_remove_equal(parent_arg, sub_arg, TRUE);
+ mail_search_args_remove_equal(argsp, sub_arg, TRUE);
sub_arg->next = common_args;
common_args = sub_arg;
}
if (common_args == NULL)
return FALSE;
- if (parent_arg->value.subargs == NULL) {
+ /* 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;
+ if (*argsp == NULL) {
/* there are only common args */
- parent_arg->type = SEARCH_SUB;
- parent_arg->value.subargs = common_args;
+ new_arg->value.subargs = common_args;
} else {
/* replace OR arg with AND(common_args, OR(non_common_args)) */
- or_arg = p_new(pool, struct mail_search_arg, 1);
- *or_arg = *parent_arg;
- or_arg->next = common_args;
-
- parent_arg->type = SEARCH_SUB;
- parent_arg->value.subargs = or_arg;
+ child_arg = p_new(pool, struct mail_search_arg, 1);
+ child_arg->type = SEARCH_OR;
+ child_arg->value.subargs = *argsp;
+ child_arg->next = common_args;
+ new_arg->value.subargs = child_arg;
}
+ *argsp = new_arg;
return TRUE;
}
@@ -483,11 +494,13 @@
if (args->type == SEARCH_SUB ||
args->type == SEARCH_OR ||
args->type == SEARCH_INTHREAD) {
+ 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))
ctx.removals = TRUE;
if (args->type == SEARCH_OR &&
- mail_search_args_simplify_extract_common_and(args, pool))
+ mail_search_args_simplify_extract_common_and(&args->value.subargs, pool))
ctx.removals = TRUE;
}
if (mail_search_args_simplify_sub(box, pool, args->value.subargs,
diff -r d68d1c95b52c -r 91b9510237fd src/lib-storage/test-mail-search-args-simplify.c
--- a/src/lib-storage/test-mail-search-args-simplify.c Sun Dec 06 19:27:45 2015 +0200
+++ b/src/lib-storage/test-mail-search-args-simplify.c Sun Dec 06 20:46:52 2015 +0200
@@ -102,7 +102,7 @@
{ "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 TEXT common2 ) ( TEXT common1 TEXT common2 TEXT unique1 )", "TEXT common2 TEXT common1" },
+ { "OR ( TEXT common1 TEXT common2 ) ( TEXT common1 TEXT common2 TEXT unique1 )", "TEXT common1 TEXT common2" },
{ "OR TEXT common1 OR ( TEXT unique1 TEXT common1 ) ( TEXT unique3 TEXT common1 )", "TEXT common1" },
/* OR: extract common AND */
More information about the dovecot-cvs
mailing list