dovecot-2.0: lib-storage: Fixes/optimizations to SEARCH_MAILBOX*.
dovecot at dovecot.org
dovecot at dovecot.org
Fri Apr 30 16:15:31 EEST 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/dedf835014a2
changeset: 11238:dedf835014a2
user: Timo Sirainen <tss at iki.fi>
date: Fri Apr 30 16:14:42 2010 +0300
description:
lib-storage: Fixes/optimizations to SEARCH_MAILBOX*.
diffstat:
src/lib-storage/index/index-search.c | 92 +++++++++++++++++++++++-------
src/lib-storage/mail-search.c | 14 +++-
src/lib-storage/mail-search.h | 1 +
3 files changed, 83 insertions(+), 24 deletions(-)
diffs (195 lines):
diff -r 6327433bccb9 -r dedf835014a2 src/lib-storage/index/index-search.c
--- a/src/lib-storage/index/index-search.c Fri Apr 30 15:53:23 2010 +0300
+++ b/src/lib-storage/index/index-search.c Fri Apr 30 16:14:42 2010 +0300
@@ -58,6 +58,7 @@
unsigned int sorted:1;
unsigned int have_seqsets:1;
unsigned int have_index_args:1;
+ unsigned int have_mailbox_args:1;
};
struct search_header_context {
@@ -87,6 +88,9 @@
static void search_init_arg(struct mail_search_arg *arg,
struct index_search_context *ctx)
{
+ uint8_t guid[MAIL_GUID_128_SIZE];
+ bool match;
+
switch (arg->type) {
case SEARCH_SEQSET:
ctx->have_seqsets = TRUE;
@@ -100,9 +104,28 @@
mail_index_modseq_enable(ctx->box->index);
ctx->have_index_args = TRUE;
break;
+ case SEARCH_MAILBOX_GUID:
+ if (mailbox_get_guid(ctx->box, guid) < 0) {
+ /* result will be unknown */
+ break;
+ }
+
+ match = strcmp(mail_guid_128_to_string(guid),
+ arg->value.str) == 0;
+ if (match != arg->not)
+ arg->match_always = TRUE;
+ else
+ arg->nonmatch_always = TRUE;
+ break;
+ case SEARCH_MAILBOX:
+ case SEARCH_MAILBOX_GLOB:
+ ctx->have_mailbox_args = TRUE;
+ break;
case SEARCH_ALL:
if (!arg->not)
arg->match_always = TRUE;
+ else
+ arg->nonmatch_always = TRUE;
break;
default:
break;
@@ -150,8 +173,6 @@
struct mail_search_arg *arg,
const struct mail_index_record *rec)
{
- uint8_t guid[MAIL_GUID_128_SIZE];
- const char *str;
enum mail_flags flags;
uint64_t modseq;
int ret;
@@ -186,25 +207,6 @@
}
return modseq >= arg->value.modseq->modseq;
}
- case SEARCH_MAILBOX:
- if (mail_get_special(ctx->mail, MAIL_FETCH_MAILBOX_NAME,
- &str) < 0)
- return -1;
-
- if (strcasecmp(str, "INBOX") == 0)
- return strcasecmp(arg->value.str, "INBOX") == 0;
- return strcmp(str, arg->value.str) == 0;
- case SEARCH_MAILBOX_GUID:
- if (mailbox_get_guid(ctx->mail->box, guid) < 0)
- return -1;
-
- return strcmp(mail_guid_128_to_string(guid),
- arg->value.str) == 0;
- case SEARCH_MAILBOX_GLOB:
- if (mail_get_special(ctx->mail, MAIL_FETCH_MAILBOX_NAME,
- &str) < 0)
- return -1;
- return imap_match(arg->value.mailbox_glob, str) == IMAP_MATCH_YES;
default:
return -1;
}
@@ -230,6 +232,47 @@
}
/* Returns >0 = matched, 0 = not matched, -1 = unknown */
+static int search_arg_match_mailbox(struct index_search_context *ctx,
+ struct mail_search_arg *arg)
+{
+ const char *str;
+
+ switch (arg->type) {
+ case SEARCH_MAILBOX:
+ if (mail_get_special(ctx->mail, MAIL_FETCH_MAILBOX_NAME,
+ &str) < 0)
+ return -1;
+
+ if (strcasecmp(str, "INBOX") == 0)
+ return strcasecmp(arg->value.str, "INBOX") == 0;
+ return strcmp(str, arg->value.str) == 0;
+ case SEARCH_MAILBOX_GLOB:
+ if (mail_get_special(ctx->mail, MAIL_FETCH_MAILBOX_NAME,
+ &str) < 0)
+ return -1;
+ return imap_match(arg->value.mailbox_glob, str) == IMAP_MATCH_YES;
+ default:
+ return -1;
+ }
+}
+
+static void search_mailbox_arg(struct mail_search_arg *arg,
+ struct index_search_context *ctx)
+{
+ switch (search_arg_match_mailbox(ctx, arg)) {
+ case -1:
+ /* unknown */
+ break;
+ case 0:
+ ARG_SET_RESULT(arg, 0);
+ break;
+ default:
+ ARG_SET_RESULT(arg, 1);
+ break;
+ }
+}
+
+/* Returns >0 = matched, 0 = not matched, -1 = unknown */
static int search_arg_match_cached(struct index_search_context *ctx,
struct mail_search_arg *arg)
{
@@ -1104,6 +1147,13 @@
unsigned int i;
int ret = -1;
+ if (ctx->have_mailbox_args) {
+ ret = mail_search_args_foreach(ctx->mail_ctx.args->args,
+ search_mailbox_arg, ctx);
+ if (ret >= 0)
+ return ret > 0;
+ }
+
/* try to avoid doing extra work for as long as possible */
for (i = 0; i < N_ELEMENTS(cache_lookups) && ret < 0; i++) {
ctx->mail->lookup_abort = cache_lookups[i];
diff -r 6327433bccb9 -r dedf835014a2 src/lib-storage/mail-search.c
--- a/src/lib-storage/mail-search.c Fri Apr 30 15:53:23 2010 +0300
+++ b/src/lib-storage/mail-search.c Fri Apr 30 16:14:42 2010 +0300
@@ -268,6 +268,7 @@
new_arg->type = arg->type;
new_arg->not = arg->not;
new_arg->match_always = arg->match_always;
+ new_arg->nonmatch_always = arg->nonmatch_always;
new_arg->value.search_flags = arg->value.search_flags;
switch (arg->type) {
@@ -356,15 +357,22 @@
if (args->type == SEARCH_OR || args->type == SEARCH_SUB)
mail_search_args_reset(args->value.subargs, full_reset);
- if (!args->match_always)
- args->result = -1;
- else {
+ if (args->match_always) {
if (!full_reset)
args->result = 1;
else {
args->match_always = FALSE;
args->result = -1;
}
+ } else if (args->nonmatch_always) {
+ if (!full_reset)
+ args->result = 0;
+ else {
+ args->nonmatch_always = FALSE;
+ args->result = -1;
+ }
+ } else {
+ args->result = -1;
}
args = args->next;
diff -r 6327433bccb9 -r dedf835014a2 src/lib-storage/mail-search.h
--- a/src/lib-storage/mail-search.h Fri Apr 30 15:53:23 2010 +0300
+++ b/src/lib-storage/mail-search.h Fri Apr 30 16:14:42 2010 +0300
@@ -95,6 +95,7 @@
const char *hdr_field_name; /* for SEARCH_HEADER* */
unsigned int not:1;
unsigned int match_always:1; /* result = 1 always */
+ unsigned int nonmatch_always:1; /* result = 0 always */
int result; /* -1 = unknown, 0 = unmatched, 1 = matched */
};
More information about the dovecot-cvs
mailing list