Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/plugins/virtual/virtual-search.c @ 8483:b12705704329 HEAD
Optimized searching with virtual mailboxes.
Instead of going through the messages in the virtual mailbox order, go them
through one mailbox at a time and in ascending message order within that
mailbox.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 23 Nov 2008 02:40:09 +0200 |
parents | |
children | f323bf2465bd |
rev | line source |
---|---|
8483
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
1 /* Copyright (c) 2008 Dovecot authors, see the included COPYING file */ |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
3 #include "lib.h" |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
4 #include "array.h" |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
5 #include "mail-search.h" |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
6 #include "index-storage.h" |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
7 #include "virtual-storage.h" |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
9 #include <stdlib.h> |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
11 enum virtual_search_state { |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 VIRTUAL_SEARCH_STATE_FAILED = -1, |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 VIRTUAL_SEARCH_STATE_BUILD, |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
14 VIRTUAL_SEARCH_STATE_RETURN, |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
15 VIRTUAL_SEARCH_STATE_SORT, |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 VIRTUAL_SEARCH_STATE_SORT_DONE |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 }; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
19 struct virtual_search_record { |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
20 uint32_t mailbox_id; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
21 uint32_t real_uid; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
22 uint32_t virtual_seq; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
23 }; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
24 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
25 struct virtual_search_context { |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
26 union mail_search_module_context module_ctx; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
27 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
28 ARRAY_TYPE(seq_range) result; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
29 struct seq_range_iter result_iter; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
30 ARRAY_DEFINE(records, struct virtual_search_record); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
31 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
32 enum virtual_search_state search_state; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
33 unsigned int next_result_n; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
34 unsigned int next_record_idx; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
35 }; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
36 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
37 static int virtual_search_record_cmp(const void *p1, const void *p2) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
38 { |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
39 const struct virtual_search_record *r1 = p1, *r2 = p2; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
40 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
41 if (r1->mailbox_id < r2->mailbox_id) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
42 return -1; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
43 if (r1->mailbox_id > r2->mailbox_id) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
44 return 1; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
45 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
46 if (r1->real_uid < r2->real_uid) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
47 return -1; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
48 if (r1->real_uid > r2->real_uid) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
49 return 1; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
50 return 0; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
51 } |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
52 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
53 static int mail_search_get_result(struct mail_search_context *ctx) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
54 { |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
55 const struct mail_search_arg *arg; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
56 int ret = 1; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
57 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
58 for (arg = ctx->args->args; arg != NULL; arg = arg->next) { |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
59 if (arg->result < 0) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
60 return -1; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
61 if (arg->result == 0) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
62 ret = 0; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
63 } |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
64 return ret; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
65 } |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
66 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
67 static int virtual_search_get_records(struct mail_search_context *ctx, |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
68 struct virtual_search_context *vctx) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
69 { |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
70 struct virtual_mailbox *mbox = |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
71 (struct virtual_mailbox *)ctx->transaction->box; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
72 const struct virtual_mail_index_record *vrec; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
73 struct virtual_search_record srec, *srecs; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
74 unsigned int count; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
75 const void *data; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
76 bool expunged; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
77 int ret, result; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
78 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
79 memset(&srec, 0, sizeof(srec)); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
80 while ((ret = index_storage_search_next_update_seq(ctx)) > 0) { |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
81 result = mail_search_get_result(ctx); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
82 i_assert(result != 0); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
83 if (result > 0) { |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
84 /* full match, no need to check this any further */ |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
85 seq_range_array_add(&vctx->result, 0, ctx->seq); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
86 } else { |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
87 /* possible match, save and check later */ |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
88 mail_index_lookup_ext(mbox->ibox.view, ctx->seq, |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
89 mbox->virtual_ext_id, |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
90 &data, &expunged); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
91 vrec = data; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
92 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
93 srec.mailbox_id = vrec->mailbox_id; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
94 srec.real_uid = vrec->real_uid; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
95 srec.virtual_seq = ctx->seq; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
96 array_append(&vctx->records, &srec, 1); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
97 } |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
98 mail_search_args_reset(ctx->args->args, FALSE); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
99 } |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
100 srecs = array_get_modifiable(&vctx->records, &count); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
101 qsort(srecs, count, sizeof(*srecs), virtual_search_record_cmp); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
102 return ret; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
103 } |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
104 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
105 struct mail_search_context * |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
106 virtual_search_init(struct mailbox_transaction_context *t, |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
107 struct mail_search_args *args, |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
108 const enum mail_sort_type *sort_program) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
109 { |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
110 struct mail_search_context *ctx; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
111 struct virtual_search_context *vctx; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
112 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
113 ctx = index_storage_search_init(t, args, sort_program); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
114 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
115 vctx = i_new(struct virtual_search_context, 1); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
116 vctx->search_state = VIRTUAL_SEARCH_STATE_BUILD; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
117 i_array_init(&vctx->result, 64); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
118 i_array_init(&vctx->records, 64); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
119 MODULE_CONTEXT_SET(ctx, virtual_storage_module, vctx); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
120 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
121 if (virtual_search_get_records(ctx, vctx) < 0) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
122 vctx->search_state = VIRTUAL_SEARCH_STATE_FAILED; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
123 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
124 seq_range_array_iter_init(&vctx->result_iter, &vctx->result); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
125 return ctx; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
126 } |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
127 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
128 int virtual_search_deinit(struct mail_search_context *ctx) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
129 { |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
130 struct virtual_search_context *vctx = VIRTUAL_CONTEXT(ctx); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
131 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
132 array_free(&vctx->result); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
133 array_free(&vctx->records); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
134 i_free(vctx); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
135 return index_storage_search_deinit(ctx); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
136 } |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
137 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
138 int virtual_search_next_nonblock(struct mail_search_context *ctx, |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
139 struct mail *mail, bool *tryagain_r) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
140 { |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
141 struct virtual_search_context *vctx = VIRTUAL_CONTEXT(ctx); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
142 uint32_t seq; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
143 int ret; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
144 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
145 switch (vctx->search_state) { |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
146 case VIRTUAL_SEARCH_STATE_FAILED: |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
147 return -1; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
148 case VIRTUAL_SEARCH_STATE_BUILD: |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
149 if (ctx->sort_program == NULL) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
150 vctx->search_state = VIRTUAL_SEARCH_STATE_SORT; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
151 else |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
152 vctx->search_state = VIRTUAL_SEARCH_STATE_RETURN; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
153 return virtual_search_next_nonblock(ctx, mail, tryagain_r); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
154 case VIRTUAL_SEARCH_STATE_RETURN: |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
155 return index_storage_search_next_nonblock(ctx, mail, tryagain_r); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
156 case VIRTUAL_SEARCH_STATE_SORT: |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
157 /* the messages won't be returned sorted, so we'll have to |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
158 do it ourself */ |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
159 while ((ret = index_storage_search_next_nonblock(ctx, mail, |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
160 tryagain_r)) > 0) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
161 seq_range_array_add(&vctx->result, 0, mail->seq); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
162 if (ret < 0 || *tryagain_r) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
163 return ret; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
164 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
165 vctx->next_result_n = 0; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
166 vctx->search_state = VIRTUAL_SEARCH_STATE_SORT_DONE; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
167 /* fall through */ |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
168 case VIRTUAL_SEARCH_STATE_SORT_DONE: |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
169 *tryagain_r = FALSE; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
170 if (!seq_range_array_iter_nth(&vctx->result_iter, |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
171 vctx->next_result_n, &seq)) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
172 return 0; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
173 vctx->next_result_n++; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
174 mail_set_seq(mail, seq); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
175 return 1; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
176 } |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
177 i_unreached(); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
178 } |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
179 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
180 static void search_args_set_full_match(struct mail_search_arg *args) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
181 { |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
182 for (; args != NULL; args = args->next) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
183 args->result = 1; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
184 } |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
185 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
186 bool virtual_search_next_update_seq(struct mail_search_context *ctx) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
187 { |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
188 struct virtual_search_context *vctx = VIRTUAL_CONTEXT(ctx); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
189 const struct virtual_search_record *recs; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
190 unsigned int count; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
191 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
192 recs = array_get(&vctx->records, &count); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
193 if (vctx->next_record_idx < count) { |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
194 ctx->seq = recs[vctx->next_record_idx++].virtual_seq - 1; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
195 if (!index_storage_search_next_update_seq(ctx)) |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
196 i_unreached(); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
197 return TRUE; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
198 } |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
199 |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
200 if (ctx->sort_program != NULL && |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
201 seq_range_array_iter_nth(&vctx->result_iter, |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
202 vctx->next_result_n, &ctx->seq)) { |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
203 search_args_set_full_match(ctx->args->args); |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
204 vctx->next_result_n++; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
205 return TRUE; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
206 } |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
207 return FALSE; |
b12705704329
Optimized searching with virtual mailboxes.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
208 } |