mail-search-args-simplify.c revision 25f959d63f5379702f44f5ae125eb3b70a6a47d7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen/* Copyright (c) 2002-2015 Dovecot authors, see the included COPYING file */
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen /* arg mask => prev_arg */
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen HASH_TABLE(struct mail_search_simplify_prev_arg *,
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen struct mail_search_simplify_prev_arg *) prev_args;
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainenmail_search_simplify_prev_arg_cmp(const struct mail_search_simplify_prev_arg *arg1,
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen const struct mail_search_simplify_prev_arg *arg2)
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen ret = memcmp(&arg1->bin_mask, &arg2->bin_mask, sizeof(arg1->bin_mask));
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen ret = null_strcmp(arg1->hdr_field_name_mask, arg2->hdr_field_name_mask);
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen ret = null_strcmp(arg1->str_mask, arg2->str_mask);
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainenstatic unsigned int
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainenmail_search_simplify_prev_arg_hash(const struct mail_search_simplify_prev_arg *arg)
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen unsigned int hash;
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen hash = mem_hash(&arg->bin_mask, sizeof(arg->bin_mask));
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainenstatic void mail_search_arg_get_base_mask(const struct mail_search_arg *arg,
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen mask_r->bin_mask.search_flags = arg->value.search_flags;
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainenstatic struct mail_search_arg **
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainenmail_search_args_simplify_get_prev_argp(struct mail_search_simplify_ctx *ctx,
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen const struct mail_search_simplify_prev_arg *mask)
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen struct mail_search_simplify_prev_arg *prev_arg;
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen prev_arg = hash_table_lookup(ctx->prev_args, mask);
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen prev_arg = p_new(ctx->pool, struct mail_search_simplify_prev_arg, 1);
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen p_strdup(ctx->pool, mask->hdr_field_name_mask);
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen hash_table_insert(ctx->prev_args, prev_arg, prev_arg);
7000810786f2959f02cd6d2f4151a9eb61ff5db8Timo Sirainenstatic bool mail_search_args_merge_flags(struct mail_search_simplify_ctx *ctx,
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen if (!((!args->match_not && ctx->parent_and) ||
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen prev_argp = mail_search_args_simplify_get_prev_argp(ctx, &mask);
7000810786f2959f02cd6d2f4151a9eb61ff5db8Timo Sirainen (*prev_argp)->value.flags |= args->value.flags;
7000810786f2959f02cd6d2f4151a9eb61ff5db8Timo Sirainenstatic bool mail_search_args_merge_set(struct mail_search_simplify_ctx *ctx,
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen if (!((!args->match_not && ctx->parent_and) ||
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen prev_argp = mail_search_args_simplify_get_prev_argp(ctx, &mask);
7000810786f2959f02cd6d2f4151a9eb61ff5db8Timo Sirainen seq_range_array_merge(&(*prev_argp)->value.seqset,
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainenstatic bool mail_search_args_merge_time(struct mail_search_simplify_ctx *ctx,
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen struct mail_search_arg **prev_argp, *prev_arg;
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen mask.bin_mask.date_type = args->value.date_type;
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen prev_argp = mail_search_args_simplify_get_prev_argp(ctx, &mask);
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen if (prev_arg->value.time < args->value.time) {
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen /* prev_arg < 5 AND arg < 10 */
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen /* prev_arg < 10 AND arg < 5 */
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen if (prev_arg->value.time < args->value.time) {
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen /* prev_arg < 5 OR arg < 10 */
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen /* prev_arg < 10 OR arg < 5 */
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen if (prev_arg->value.time < args->value.time) {
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen /* prev_arg >= 5 AND arg >= 10 */
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen /* prev_arg >= 10 AND arg >= 5 */
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen if (prev_arg->value.time < args->value.time) {
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen /* prev_arg >= 5 OR arg >= 10 */
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen /* prev_arg >= 10 OR arg >= 5 */
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainenstatic bool mail_search_args_merge_size(struct mail_search_simplify_ctx *ctx,
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen struct mail_search_arg **prev_argp, *prev_arg;
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen prev_argp = mail_search_args_simplify_get_prev_argp(ctx, &mask);
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen if (prev_arg->value.size < args->value.size) {
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen /* prev_arg < 5 AND arg < 10 */
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen /* prev_arg < 10 AND arg < 5 */
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen if (prev_arg->value.size < args->value.size) {
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen /* prev_arg < 5 OR arg < 10 */
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen /* prev_arg < 10 OR arg < 5 */
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen if (prev_arg->value.size < args->value.size) {
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen /* prev_arg >= 5 AND arg >= 10 */
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen /* prev_arg >= 10 AND arg >= 5 */
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen if (prev_arg->value.size < args->value.size) {
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen /* prev_arg >= 5 OR arg >= 10 */
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen /* prev_arg >= 10 OR arg >= 5 */
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainenstatic bool mail_search_args_merge_text(struct mail_search_simplify_ctx *ctx,
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen mask.hdr_field_name_mask = args->hdr_field_name;
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen prev_argp = mail_search_args_simplify_get_prev_argp(ctx, &mask);
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen /* duplicate search word. */
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainenmail_search_args_simplify_sub(struct mailbox *box,
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen struct mail_search_arg *args, bool parent_and)
7000810786f2959f02cd6d2f4151a9eb61ff5db8Timo Sirainen struct mail_search_arg *sub, *prev_arg = NULL;
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen ctx.pool = pool_alloconly_create("mail search args simplify", 1024);
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen hash_table_create(&ctx.prev_args, ctx.pool, 0,
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen if (args->match_not && (args->type == SEARCH_SUB ||
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen /* neg(p and q and ..) == neg(p) or neg(q) or ..
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen neg(p or q or ..) == neg(p) and neg(q) and .. */
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen if ((args->type == SEARCH_SUB && parent_and) ||
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen ((args->type == SEARCH_SUB || args->type == SEARCH_OR) &&
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen /* p and (q and ..) == p and q and ..
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen p or (q or ..) == p or q or ..
fb79b36eb34532dbe67caf99eefe3660b8c841e0Timo Sirainen if (mail_search_args_simplify_sub(box, args->value.subargs,
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen /* try to merge arguments */
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen merged = mail_search_args_merge_flags(&ctx, args);
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen merged = mail_search_args_merge_set(&ctx, args);
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen merged = mail_search_args_merge_time(&ctx, args);
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen merged = mail_search_args_merge_size(&ctx, args);
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen merged = mail_search_args_merge_text(&ctx, args);
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainenmail_search_args_unnest_inthreads(struct mail_search_args *args,
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen struct mail_search_arg *arg, *thread_arg, *or_arg;
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen bool child_inthreads = FALSE, non_inthreads = FALSE;
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen for (arg = *argp; arg != NULL; arg = arg->next) {
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen /* children converted to SEARCH_INTHREADs */
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen if (!parent_inthreads || !child_inthreads || !non_inthreads)
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen /* put all non-INTHREADs under a single INTHREAD */
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen thread_arg = p_new(args->pool, struct mail_search_arg, 1);
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen /* not an INTHREAD or a SUB/OR with only INTHREADs */
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen /* We want to OR the args */
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen or_arg = p_new(args->pool, struct mail_search_arg, 1);
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen or_arg->value.subargs = thread_arg->value.subargs;
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainenvoid mail_search_args_simplify(struct mail_search_args *args)
fb79b36eb34532dbe67caf99eefe3660b8c841e0Timo Sirainen removals = mail_search_args_simplify_sub(args->box, args->args, TRUE);
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen if (mail_search_args_unnest_inthreads(args, &args->args,
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen /* we may have added some extra SUBs that could be dropped */
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen mail_search_args_simplify_sub(args->box, args->args, TRUE);