dovecot-1.2: Search code cleanups and minor optimizations.
dovecot at dovecot.org
dovecot at dovecot.org
Fri Jun 20 05:37:40 EEST 2008
details: http://hg.dovecot.org/dovecot-1.2/rev/1e69c84a1e5a
changeset: 7908:1e69c84a1e5a
user: Timo Sirainen <tss at iki.fi>
date: Fri Jun 20 05:35:05 2008 +0300
description:
Search code cleanups and minor optimizations.
diffstat:
4 files changed, 64 insertions(+), 31 deletions(-)
src/lib-storage/index/index-search.c | 28 ++++++++++++-----
src/lib-storage/mail-search.c | 55 +++++++++++++++++++++-------------
src/lib-storage/mail-search.h | 9 +++--
src/lib-storage/mail-storage.c | 3 +
diffs (229 lines):
diff -r 021c39f58af3 -r 1e69c84a1e5a src/lib-storage/index/index-search.c
--- a/src/lib-storage/index/index-search.c Fri Jun 20 05:30:00 2008 +0300
+++ b/src/lib-storage/index/index-search.c Fri Jun 20 05:35:05 2008 +0300
@@ -688,17 +688,23 @@ static void search_or_parse_msgset_args(
for (; args != NULL; args = args->next) {
seq1 = 1; seq2 = hdr->messages_count;
- if (args->type == SEARCH_SUB) {
+ switch (args->type) {
+ case SEARCH_SUB:
i_assert(!args->not);
search_parse_msgset_args(hdr, args->value.subargs,
&seq1, &seq2);
- } else if (args->type == SEARCH_OR) {
+ break;
+ case SEARCH_OR:
i_assert(!args->not);
search_or_parse_msgset_args(hdr, args->value.subargs,
&seq1, &seq2);
- } else if (args->type == SEARCH_SEQSET) {
+ break;
+ case SEARCH_SEQSET:
search_msgset_fix(hdr, &args->value.seqset,
&seq1, &seq2, args->not);
+ break;
+ default:
+ break;
}
if (min_seq1 == 0) {
@@ -724,19 +730,25 @@ static void search_parse_msgset_args(con
uint32_t *seq1_r, uint32_t *seq2_r)
{
for (; args != NULL; args = args->next) {
- if (args->type == SEARCH_SUB) {
+ switch (args->type) {
+ case SEARCH_SUB:
i_assert(!args->not);
search_parse_msgset_args(hdr, args->value.subargs,
seq1_r, seq2_r);
- } else if (args->type == SEARCH_OR) {
+ break;
+ case SEARCH_OR:
/* go through our children and use the widest seqset
range */
i_assert(!args->not);
search_or_parse_msgset_args(hdr, args->value.subargs,
seq1_r, seq2_r);
- } else if (args->type == SEARCH_SEQSET) {
+ break;
+ case SEARCH_SEQSET:
search_msgset_fix(hdr, &args->value.seqset,
seq1_r, seq2_r, args->not);
+ break;
+ default:
+ break;
}
}
}
@@ -983,7 +995,9 @@ static bool search_arg_is_static(struct
return FALSE;
}
return TRUE;
- case SEARCH_SEQSET: /* changes between syncs */
+ case SEARCH_SEQSET:
+ /* changes between syncs, but we can't really handle this
+ currently. seqsets should be converted to uidsets first. */
case SEARCH_FLAGS:
case SEARCH_KEYWORDS:
case SEARCH_MODSEQ:
diff -r 021c39f58af3 -r 1e69c84a1e5a src/lib-storage/mail-search.c
--- a/src/lib-storage/mail-search.c Fri Jun 20 05:30:00 2008 +0300
+++ b/src/lib-storage/mail-search.c Fri Jun 20 05:35:05 2008 +0300
@@ -56,36 +56,38 @@ mailbox_uidset_change(struct mail_search
}
static void
-mail_search_args_init_sub(struct mail_search_arg *args,
- struct mailbox *box, bool change_uidsets,
+mail_search_args_init_sub(struct mail_search_args *args,
+ struct mail_search_arg *arg,
+ bool change_uidsets,
const ARRAY_TYPE(seq_range) *search_saved_uidset)
{
const char *keywords[2];
- for (; args != NULL; args = args->next) {
- switch (args->type) {
+ for (; arg != NULL; arg = arg->next) {
+ switch (arg->type) {
case SEARCH_UIDSET:
if (change_uidsets) T_BEGIN {
- mailbox_uidset_change(args, box,
+ mailbox_uidset_change(arg, args->box,
search_saved_uidset);
} T_END;
break;
case SEARCH_MODSEQ:
- if (args->value.str == NULL)
+ if (arg->value.str == NULL)
break;
/* modseq with keyword */
case SEARCH_KEYWORDS:
- keywords[0] = args->value.str;
+ keywords[0] = arg->value.str;
keywords[1] = NULL;
- i_assert(args->value.keywords == NULL);
- args->value.keywords =
- mailbox_keywords_create_valid(box, keywords);
+ i_assert(arg->value.keywords == NULL);
+ arg->value.keywords =
+ mailbox_keywords_create_valid(args->box,
+ keywords);
break;
case SEARCH_SUB:
case SEARCH_OR:
- mail_search_args_init_sub(args->value.subargs, box,
+ mail_search_args_init_sub(args, arg->value.subargs,
change_uidsets,
search_saved_uidset);
break;
@@ -99,8 +101,15 @@ void mail_search_args_init(struct mail_s
struct mailbox *box, bool change_uidsets,
const ARRAY_TYPE(seq_range) *search_saved_uidset)
{
+ if (args->initialized) {
+ i_assert(args->box == box);
+ return;
+ }
+
args->box = box;
- mail_search_args_init_sub(args->args, box, change_uidsets,
+ if (!args->simplified)
+ mail_search_args_simplify(args);
+ mail_search_args_init_sub(args, args->args, change_uidsets,
search_saved_uidset);
}
@@ -127,10 +136,12 @@ static void mail_search_args_deinit_sub(
void mail_search_args_deinit(struct mail_search_args *args)
{
- if (args->refcount > 1)
+ if (args->refcount > 1 || !args->initialized)
return;
mail_search_args_deinit_sub(args, args->args);
+ args->initialized = FALSE;
+ args->box = NULL;
}
static void mail_search_args_seq2uid_sub(struct mail_search_args *args,
@@ -407,7 +418,7 @@ mail_search_args_simplify_sub(struct mai
prev_flags_arg = prev_not_flags_arg = NULL;
prev_kw_arg = prev_not_kw_arg = NULL;
- for (; args != NULL;) {
+ while (args != NULL) {
if (args->not && (args->type == SEARCH_SUB ||
args->type == SEARCH_OR)) {
/* neg(p and q and ..) == neg(p) or neg(q) or ..
@@ -421,9 +432,12 @@ mail_search_args_simplify_sub(struct mai
}
if ((args->type == SEARCH_SUB && parent_and) ||
- (args->type == SEARCH_OR && !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 or (q or ..) == p or q or ..
+ (p) = p */
sub = args->value.subargs;
for (; sub->next != NULL; sub = sub->next) ;
sub->next = args->next;
@@ -493,7 +507,8 @@ mail_search_args_simplify_sub(struct mai
}
}
-void mail_search_args_simplify(struct mail_search_arg *args)
-{
- mail_search_args_simplify_sub(args, TRUE);
-}
+void mail_search_args_simplify(struct mail_search_args *args)
+{
+ args->simplified = TRUE;
+ mail_search_args_simplify_sub(args->args, TRUE);
+}
diff -r 021c39f58af3 -r 1e69c84a1e5a src/lib-storage/mail-search.h
--- a/src/lib-storage/mail-search.h Fri Jun 20 05:30:00 2008 +0300
+++ b/src/lib-storage/mail-search.h Fri Jun 20 05:35:05 2008 +0300
@@ -91,6 +91,10 @@ struct mail_search_args {
struct mailbox *box;
struct mail_search_arg *args;
const char *charset;
+
+ unsigned int initialized:1;
+ unsigned int simplified:1;
+ unsigned int have_inthreads:1;
};
#define ARG_SET_RESULT(arg, res) \
@@ -142,8 +146,7 @@ mail_search_args_analyze(struct mail_sea
mail_search_args_analyze(struct mail_search_arg *args,
bool *have_headers, bool *have_body);
-/* 1) Change args so that SEARCH_SUB and SEARCH_OR will never have "not" set
- 2) Drop unnecessary nested SEARCH_SUB and SEARCH_ORs */
-void mail_search_args_simplify(struct mail_search_arg *args);
+/* Simplify/optimize search arguments */
+void mail_search_args_simplify(struct mail_search_args *args);
#endif
diff -r 021c39f58af3 -r 1e69c84a1e5a src/lib-storage/mail-storage.c
--- a/src/lib-storage/mail-storage.c Fri Jun 20 05:30:00 2008 +0300
+++ b/src/lib-storage/mail-storage.c Fri Jun 20 05:35:05 2008 +0300
@@ -643,7 +643,8 @@ mailbox_search_init(struct mailbox_trans
const enum mail_sort_type *sort_program)
{
mail_search_args_ref(args);
- mail_search_args_simplify(args->args);
+ if (!args->simplified)
+ mail_search_args_simplify(args);
return t->box->v.search_init(t, args, sort_program);
}
More information about the dovecot-cvs
mailing list