[dovecot-cvs] dovecot/src/lib-storage/index index-storage.h, 1.100,
1.101 index-search.c, 1.110, 1.111
cras at dovecot.org
cras at dovecot.org
Fri Apr 14 15:30:24 EEST 2006
Update of /var/lib/cvs/dovecot/src/lib-storage/index
In directory talvi:/tmp/cvs-serv15869/index
Modified Files:
index-storage.h index-search.c
Log Message:
Optimized searching a bit for cases where we can restrict search range by
simply looking at sequence sets. Also optimized some deleted/seen flag
searches where no results would be found. Added search_next_update_seq()
virtual method which allows plugins to restrict the search range (eg.
allowing indexed text search plugins).
Index: index-storage.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/index-storage.h,v
retrieving revision 1.100
retrieving revision 1.101
diff -u -d -r1.100 -r1.101
--- index-storage.h 9 Apr 2006 15:50:25 -0000 1.100
+++ index-storage.h 14 Apr 2006 12:30:21 -0000 1.101
@@ -177,6 +177,7 @@
int index_storage_search_deinit(struct mail_search_context *ctx);
int index_storage_search_next(struct mail_search_context *ctx,
struct mail *mail);
+int index_storage_search_next_update_seq(struct mail_search_context *ctx);
void index_transaction_init(struct index_transaction_context *t,
struct index_mailbox *ibox,
Index: index-search.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/index-search.c,v
retrieving revision 1.110
retrieving revision 1.111
diff -u -d -r1.110 -r1.111
--- index-search.c 25 Feb 2006 08:24:18 -0000 1.110
+++ index-search.c 14 Apr 2006 12:30:21 -0000 1.111
@@ -34,6 +34,7 @@
const char *error;
unsigned int failed:1;
+ unsigned int have_seqsets:1;
};
struct search_header_context {
@@ -89,9 +90,6 @@
const char *const *keywords;
switch (type) {
- case SEARCH_ALL:
- return 1;
-
/* flags */
case SEARCH_ANSWERED:
return rec->flags & MAIL_ANSWERED;
@@ -121,17 +119,38 @@
}
}
-static void search_index_arg(struct mail_search_arg *arg, void *context)
+static void search_init_seqset_arg(struct mail_search_arg *arg, void *context)
+{
+ struct index_search_context *ctx = context;
+
+ switch (arg->type) {
+ case SEARCH_SEQSET:
+ ctx->have_seqsets = TRUE;
+ break;
+ case SEARCH_ALL:
+ if (!arg->not)
+ arg->match_always = TRUE;
+ break;
+ default:
+ break;
+ }
+}
+
+static void search_seqset_arg(struct mail_search_arg *arg, void *context)
{
struct index_search_context *ctx = context;
if (arg->type == SEARCH_SEQSET) {
- if (seqset_contains(arg->value.seqset, ctx->mail->seq))
+ if (seqset_contains(arg->value.seqset, ctx->mail_ctx.seq))
ARG_SET_RESULT(arg, 1);
else
ARG_SET_RESULT(arg, 0);
- return;
}
+}
+
+static void search_index_arg(struct mail_search_arg *arg, void *context)
+{
+ struct index_search_context *ctx = context;
if (ctx->imail->data.rec == NULL) {
/* expunged message */
@@ -654,7 +673,8 @@
uint32_t *seq1, uint32_t *seq2)
{
for (; args != NULL; args = args->next) {
- if (args->type == SEARCH_SEEN) {
+ switch (args->type) {
+ case SEARCH_SEEN:
/* SEEN with 0 seen? */
if (!args->not && hdr->seen_messages_count == 0)
return 0;
@@ -673,9 +693,8 @@
seq1) < 0)
return -1;
}
- }
-
- if (args->type == SEARCH_DELETED) {
+ break;
+ case SEARCH_DELETED:
/* DELETED with 0 deleted? */
if (!args->not && hdr->deleted_messages_count == 0)
return 0;
@@ -695,6 +714,13 @@
seq1) < 0)
return -1;
}
+ break;
+ case SEARCH_ALL:
+ if (args->not)
+ return 0;
+ break;
+ default:
+ break;
}
}
@@ -705,6 +731,7 @@
struct mail_search_arg *args)
{
const struct mail_index_header *hdr;
+ int ret;
hdr = mail_index_get_header(ctx->view);
if (hdr->messages_count == 0) {
@@ -728,9 +755,14 @@
i_assert(ctx->seq1 <= ctx->seq2);
/* UNSEEN and DELETED in root search level may limit the range */
- if (search_limit_by_flags(ctx, hdr, args,
- &ctx->seq1, &ctx->seq2) < 0)
+ ret = search_limit_by_flags(ctx, hdr, args, &ctx->seq1, &ctx->seq2);
+ if (ret < 0)
return -1;
+ if (ret == 0) {
+ /* no matches */
+ ctx->seq1 = 1;
+ ctx->seq2 = 0;
+ }
return 0;
}
@@ -769,6 +801,11 @@
ctx->failed = TRUE;
ctx->seq1 = 1;
ctx->seq2 = 0;
+ } else {
+ (void)mail_search_args_foreach(args, search_init_seqset_arg,
+ ctx);
+ /* Need to reset results for match_always cases */
+ mail_search_args_reset(ctx->args, FALSE);
}
return &ctx->mail_ctx;
}
@@ -799,7 +836,6 @@
int ret;
/* check the index matches first */
- mail_search_args_reset(ctx->args, FALSE);
ret = mail_search_args_foreach(ctx->args, search_index_arg, ctx);
if (ret >= 0)
return ret > 0;
@@ -831,29 +867,62 @@
struct mail *mail)
{
struct index_search_context *ctx = (struct index_search_context *)_ctx;
+ struct mailbox *box = _ctx->transaction->box;
int ret;
ctx->mail = mail;
ctx->imail = (struct index_mail *)mail;
- ret = 0;
- while (ctx->seq1 <= ctx->seq2) {
- if (mail_set_seq(mail, ctx->seq1++) < 0) {
- ctx->failed = TRUE;
+ while ((ret = box->v.search_next_update_seq(_ctx)) > 0) {
+ if (mail_set_seq(mail, _ctx->seq) < 0) {
+ ret = -1;
break;
}
t_push();
- ret = search_match_next(ctx);
+ ret = search_match_next(ctx) ? 1 : 0;
t_pop();
+ mail_search_args_reset(ctx->args, FALSE);
+
if (ctx->error != NULL)
ret = -1;
if (ret != 0)
break;
}
+ if (ret < 0)
+ ctx->failed = TRUE;
ctx->mail = NULL;
ctx->imail = NULL;
return ret;
}
+
+int index_storage_search_next_update_seq(struct mail_search_context *_ctx)
+{
+ struct index_search_context *ctx = (struct index_search_context *)_ctx;
+ int ret;
+
+ if (_ctx->seq == 0) {
+ /* first time */
+ _ctx->seq = ctx->seq1;
+ } else {
+ _ctx->seq++;
+ }
+
+ if (!ctx->have_seqsets)
+ return _ctx->seq <= ctx->seq2 ? 1 : 0;
+
+ ret = 0;
+ while (_ctx->seq <= ctx->seq2) {
+ /* check if the sequence matches */
+ ret = mail_search_args_foreach(ctx->args,
+ search_seqset_arg, ctx);
+ if (ret != 0)
+ break;
+
+ /* doesn't, try next one */
+ _ctx->seq++;
+ }
+ return ret == 0 ? 0 : 1;
+}
More information about the dovecot-cvs
mailing list