Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib-storage/index/index-sort-string.c @ 9444:a5d8d201bd39 HEAD
imap: Implemented SORT=DISPLAY extension (draft-ietf-morg-sortdisplay-02).
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 18 Oct 2009 18:37:03 -0400 |
parents | c50f133f0acc |
children | 00cd9aacd03c |
rev | line source |
---|---|
8590
b9faf4db2a9f
Updated copyright notices to include year 2009.
Timo Sirainen <tss@iki.fi>
parents:
8480
diff
changeset
|
1 /* Copyright (c) 2006-2009 Dovecot authors, see the included COPYING file */ |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
3 /* The idea is that we use 32bit integers for string sort IDs which specifiy |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
4 the sort order for primary sort condition. The whole 32bit integer space is |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
5 used and whenever adding a string, the available space is halved and the new |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
6 ID is added in the middle. For example if we add one mail the first time, it |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
7 gets ID 2^31. If we then add two mails which are sorted before the first |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 one, they get IDs 2^31/3 and 2^31/3*2. Once we run out of the available |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
9 space between IDs, more space is made by renumbering some IDs. |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
11 #include "lib.h" |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 #include "array.h" |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 #include "str.h" |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
14 #include "index-storage.h" |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
15 #include "index-sort-private.h" |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 #include <stdlib.h> |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
19 struct mail_sort_node { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
20 uint32_t seq:29; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
21 uint32_t wanted:1; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
22 uint32_t no_update:1; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
23 uint32_t sort_id_changed:1; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
24 uint32_t sort_id; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
25 }; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
26 ARRAY_DEFINE_TYPE(mail_sort_node, struct mail_sort_node); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
27 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
28 struct sort_string_context { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
29 struct mail_search_sort_program *program; |
9293
c50f133f0acc
sort: Don't assert-crash if sort indexes are broken.
Timo Sirainen <tss@iki.fi>
parents:
8799
diff
changeset
|
30 const char *primary_sort_name; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
31 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
32 ARRAY_TYPE(mail_sort_node) zero_nodes, nonzero_nodes, sorted_nodes; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
33 const char **sort_strings; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
34 pool_t sort_string_pool; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
35 unsigned int first_missing_sort_id_idx; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
36 |
8480
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
37 uint32_t ext_id, last_seq, highest_reset_id, prev_seq; |
7569
ea913434d522
Sort index optimization: Don't write changes to sort IDs if we're doing it
Timo Sirainen <tss@iki.fi>
parents:
7568
diff
changeset
|
38 uint32_t lowest_nonexpunged_zero; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
39 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
40 unsigned int regetting:1; |
7567
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
41 unsigned int have_all_wanted:1; |
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
42 unsigned int no_writing:1; |
7859
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
43 unsigned int reverse:1; |
8480
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
44 unsigned int seqs_nonsorted:1; |
9293
c50f133f0acc
sort: Don't assert-crash if sort indexes are broken.
Timo Sirainen <tss@iki.fi>
parents:
8799
diff
changeset
|
45 unsigned int broken:1; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
46 }; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
47 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
48 static char expunged_msg; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
49 static struct sort_string_context *static_zero_cmp_context; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
50 |
9293
c50f133f0acc
sort: Don't assert-crash if sort indexes are broken.
Timo Sirainen <tss@iki.fi>
parents:
8799
diff
changeset
|
51 static void index_sort_list_reset_broken(struct sort_string_context *ctx); |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
52 static void index_sort_node_add(struct sort_string_context *ctx, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
53 struct mail_sort_node *node); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
54 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
55 void index_sort_list_init_string(struct mail_search_sort_program *program) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
56 { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
57 struct index_mailbox *ibox = (struct index_mailbox *)program->t->box; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
58 struct sort_string_context *ctx; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
59 const char *name; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
60 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
61 switch (program->sort_program[0] & MAIL_SORT_MASK) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
62 case MAIL_SORT_CC: |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
63 name = "sort-c"; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
64 break; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
65 case MAIL_SORT_FROM: |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
66 name = "sort-f"; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
67 break; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
68 case MAIL_SORT_SUBJECT: |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
69 name = "sort-s"; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
70 break; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
71 case MAIL_SORT_TO: |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
72 name = "sort-t"; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
73 break; |
9444
a5d8d201bd39
imap: Implemented SORT=DISPLAY extension (draft-ietf-morg-sortdisplay-02).
Timo Sirainen <tss@iki.fi>
parents:
9293
diff
changeset
|
74 case MAIL_SORT_DISPLAYFROM: |
a5d8d201bd39
imap: Implemented SORT=DISPLAY extension (draft-ietf-morg-sortdisplay-02).
Timo Sirainen <tss@iki.fi>
parents:
9293
diff
changeset
|
75 name = "sort-df"; |
a5d8d201bd39
imap: Implemented SORT=DISPLAY extension (draft-ietf-morg-sortdisplay-02).
Timo Sirainen <tss@iki.fi>
parents:
9293
diff
changeset
|
76 break; |
a5d8d201bd39
imap: Implemented SORT=DISPLAY extension (draft-ietf-morg-sortdisplay-02).
Timo Sirainen <tss@iki.fi>
parents:
9293
diff
changeset
|
77 case MAIL_SORT_DISPLAYTO: |
a5d8d201bd39
imap: Implemented SORT=DISPLAY extension (draft-ietf-morg-sortdisplay-02).
Timo Sirainen <tss@iki.fi>
parents:
9293
diff
changeset
|
78 name = "sort-dt"; |
a5d8d201bd39
imap: Implemented SORT=DISPLAY extension (draft-ietf-morg-sortdisplay-02).
Timo Sirainen <tss@iki.fi>
parents:
9293
diff
changeset
|
79 break; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
80 default: |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
81 i_unreached(); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
82 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
83 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
84 program->context = ctx = i_new(struct sort_string_context, 1); |
7859
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
85 ctx->reverse = (program->sort_program[0] & MAIL_SORT_FLAG_REVERSE) != 0; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
86 ctx->program = program; |
9293
c50f133f0acc
sort: Don't assert-crash if sort indexes are broken.
Timo Sirainen <tss@iki.fi>
parents:
8799
diff
changeset
|
87 ctx->primary_sort_name = name; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
88 ctx->ext_id = mail_index_ext_register(ibox->index, name, 0, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
89 sizeof(uint32_t), |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
90 sizeof(uint32_t)); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
91 i_array_init(&ctx->zero_nodes, 128); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
92 i_array_init(&ctx->nonzero_nodes, 128); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
93 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
94 |
8480
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
95 static int sort_node_seq_cmp(const void *p1, const void *p2) |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
96 { |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
97 const struct mail_sort_node *n1 = p1, *n2 = p2; |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
98 |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
99 if (n1->seq < n2->seq) |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
100 return -1; |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
101 if (n1->seq > n2->seq) |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
102 return 1; |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
103 return 0; |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
104 } |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
105 |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
106 static void index_sort_nodes_by_seq(struct sort_string_context *ctx) |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
107 { |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
108 struct mail_sort_node *nodes; |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
109 unsigned int count; |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
110 |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
111 nodes = array_get_modifiable(&ctx->zero_nodes, &count); |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
112 qsort(nodes, count, sizeof(struct mail_sort_node), sort_node_seq_cmp); |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
113 |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
114 nodes = array_get_modifiable(&ctx->nonzero_nodes, &count); |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
115 qsort(nodes, count, sizeof(struct mail_sort_node), sort_node_seq_cmp); |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
116 } |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
117 |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
118 static void index_sort_generate_seqs(struct sort_string_context *ctx) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
119 { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
120 struct mail_sort_node *nodes, *nodes2; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
121 unsigned int i, j, count, count2; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
122 uint32_t seq; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
123 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
124 nodes = array_get_modifiable(&ctx->nonzero_nodes, &count); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
125 nodes2 = array_get_modifiable(&ctx->zero_nodes, &count2); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
126 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
127 if (!array_is_created(&ctx->program->seqs)) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
128 i_array_init(&ctx->program->seqs, count + count2); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
129 else |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
130 array_clear(&ctx->program->seqs); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
131 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
132 for (i = j = 0;;) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
133 if (i < count && j < count2) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
134 if (nodes[i].seq < nodes2[j].seq) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
135 seq = nodes[i++].seq; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
136 else |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
137 seq = nodes2[j++].seq; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
138 } else if (i < count) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
139 seq = nodes[i++].seq; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
140 } else if (j < count2) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
141 seq = nodes2[j++].seq; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
142 } else { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
143 break; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
144 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
145 array_append(&ctx->program->seqs, &seq, 1); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
146 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
147 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
148 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
149 static void index_sort_reget_sort_ids(struct sort_string_context *ctx) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
150 { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
151 struct mail_sort_node node; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
152 const uint32_t *seqs; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
153 unsigned int i, count; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
154 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
155 i_assert(!ctx->regetting); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
156 ctx->regetting = TRUE; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
157 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
158 index_sort_generate_seqs(ctx); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
159 array_clear(&ctx->zero_nodes); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
160 array_clear(&ctx->nonzero_nodes); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
161 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
162 memset(&node, 0, sizeof(node)); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
163 node.wanted = TRUE; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
164 seqs = array_get(&ctx->program->seqs, &count); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
165 for (i = 0; i < count; i++) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
166 node.seq = seqs[i]; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
167 index_sort_node_add(ctx, &node); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
168 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
169 ctx->regetting = FALSE; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
170 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
171 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
172 static void index_sort_node_add(struct sort_string_context *ctx, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
173 struct mail_sort_node *node) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
174 { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
175 struct index_transaction_context *t = |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
176 (struct index_transaction_context *)ctx->program->t; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
177 struct mail_index_map *map; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
178 const void *data; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
179 uint32_t reset_id; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
180 bool expunged; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
181 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
182 mail_index_lookup_ext_full(t->trans_view, node->seq, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
183 ctx->ext_id, &map, &data, &expunged); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
184 if (expunged) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
185 /* we don't want to update expunged messages' sort IDs */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
186 node->no_update = TRUE; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
187 /* we can't trust expunged messages' sort IDs. they might be |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
188 valid, but it's also possible that sort IDs were updated |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
189 and the expunged messages' sort IDs became invalid. we could |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
190 use sort ID if we could know the extension's reset_id at the |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
191 time of the expunge so we could compare it to |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
192 highest_reset_id, but this isn't currently possible. */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
193 node->sort_id = 0; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
194 } else { |
9293
c50f133f0acc
sort: Don't assert-crash if sort indexes are broken.
Timo Sirainen <tss@iki.fi>
parents:
8799
diff
changeset
|
195 node->sort_id = ctx->broken || data == NULL ? 0 : |
c50f133f0acc
sort: Don't assert-crash if sort indexes are broken.
Timo Sirainen <tss@iki.fi>
parents:
8799
diff
changeset
|
196 *(const uint32_t *)data; |
7569
ea913434d522
Sort index optimization: Don't write changes to sort IDs if we're doing it
Timo Sirainen <tss@iki.fi>
parents:
7568
diff
changeset
|
197 if (node->sort_id == 0) { |
ea913434d522
Sort index optimization: Don't write changes to sort IDs if we're doing it
Timo Sirainen <tss@iki.fi>
parents:
7568
diff
changeset
|
198 if (ctx->lowest_nonexpunged_zero > node->seq || |
ea913434d522
Sort index optimization: Don't write changes to sort IDs if we're doing it
Timo Sirainen <tss@iki.fi>
parents:
7568
diff
changeset
|
199 ctx->lowest_nonexpunged_zero == 0) |
ea913434d522
Sort index optimization: Don't write changes to sort IDs if we're doing it
Timo Sirainen <tss@iki.fi>
parents:
7568
diff
changeset
|
200 ctx->lowest_nonexpunged_zero = node->seq; |
9293
c50f133f0acc
sort: Don't assert-crash if sort indexes are broken.
Timo Sirainen <tss@iki.fi>
parents:
8799
diff
changeset
|
201 } else if (ctx->lowest_nonexpunged_zero != 0 && |
c50f133f0acc
sort: Don't assert-crash if sort indexes are broken.
Timo Sirainen <tss@iki.fi>
parents:
8799
diff
changeset
|
202 ctx->lowest_nonexpunged_zero <= node->seq) { |
c50f133f0acc
sort: Don't assert-crash if sort indexes are broken.
Timo Sirainen <tss@iki.fi>
parents:
8799
diff
changeset
|
203 index_sort_list_reset_broken(ctx); |
c50f133f0acc
sort: Don't assert-crash if sort indexes are broken.
Timo Sirainen <tss@iki.fi>
parents:
8799
diff
changeset
|
204 ctx->broken = TRUE; |
c50f133f0acc
sort: Don't assert-crash if sort indexes are broken.
Timo Sirainen <tss@iki.fi>
parents:
8799
diff
changeset
|
205 node->sort_id = 0; |
7569
ea913434d522
Sort index optimization: Don't write changes to sort IDs if we're doing it
Timo Sirainen <tss@iki.fi>
parents:
7568
diff
changeset
|
206 } |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
207 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
208 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
209 if (node->sort_id != 0) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
210 /* if reset ID increases, lookup all existing messages' sort |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
211 IDs again. if it decreases, ignore the sort ID. */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
212 if (!mail_index_ext_get_reset_id(t->trans_view, map, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
213 ctx->ext_id, &reset_id)) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
214 reset_id = 0; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
215 if (reset_id != ctx->highest_reset_id) { |
7567
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
216 if (reset_id < ctx->highest_reset_id) { |
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
217 i_assert(expunged); |
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
218 node->sort_id = 0; |
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
219 } else if (ctx->have_all_wanted) { |
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
220 /* a bit late to start changing the reset_id. |
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
221 the node lists aren't ordered by sequence |
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
222 anymore. */ |
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
223 node->sort_id = 0; |
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
224 ctx->no_writing = TRUE; |
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
225 } else { |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
226 ctx->highest_reset_id = reset_id; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
227 index_sort_reget_sort_ids(ctx); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
228 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
229 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
230 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
231 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
232 if (node->sort_id == 0) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
233 array_append(&ctx->zero_nodes, node, 1); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
234 else |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
235 array_append(&ctx->nonzero_nodes, node, 1); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
236 if (ctx->last_seq < node->seq) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
237 ctx->last_seq = node->seq; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
238 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
239 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
240 void index_sort_list_add_string(struct mail_search_sort_program *program, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
241 struct mail *mail) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
242 { |
8480
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
243 struct sort_string_context *ctx = program->context; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
244 struct mail_sort_node node; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
245 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
246 memset(&node, 0, sizeof(node)); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
247 node.seq = mail->seq; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
248 node.wanted = TRUE; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
249 |
8480
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
250 if (mail->seq < ctx->prev_seq) |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
251 ctx->seqs_nonsorted = TRUE; |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
252 ctx->prev_seq = mail->seq; |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
253 |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
254 index_sort_node_add(ctx, &node); |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
255 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
256 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
257 static int sort_node_zero_string_cmp(const void *p1, const void *p2) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
258 { |
7613
63602977ca9b
sort index: Messages without sort_id weren't sorted correctly on secondary
Timo Sirainen <tss@iki.fi>
parents:
7612
diff
changeset
|
259 struct sort_string_context *ctx = static_zero_cmp_context; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
260 const struct mail_sort_node *n1 = p1, *n2 = p2; |
7613
63602977ca9b
sort index: Messages without sort_id weren't sorted correctly on secondary
Timo Sirainen <tss@iki.fi>
parents:
7612
diff
changeset
|
261 int ret; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
262 |
7613
63602977ca9b
sort index: Messages without sort_id weren't sorted correctly on secondary
Timo Sirainen <tss@iki.fi>
parents:
7612
diff
changeset
|
263 ret = strcmp(ctx->sort_strings[n1->seq], ctx->sort_strings[n2->seq]); |
63602977ca9b
sort index: Messages without sort_id weren't sorted correctly on secondary
Timo Sirainen <tss@iki.fi>
parents:
7612
diff
changeset
|
264 if (ret != 0) |
7859
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
265 return !ctx->reverse ? ret : -ret; |
7613
63602977ca9b
sort index: Messages without sort_id weren't sorted correctly on secondary
Timo Sirainen <tss@iki.fi>
parents:
7612
diff
changeset
|
266 |
63602977ca9b
sort index: Messages without sort_id weren't sorted correctly on secondary
Timo Sirainen <tss@iki.fi>
parents:
7612
diff
changeset
|
267 return index_sort_node_cmp_type(ctx->program->temp_mail, |
63602977ca9b
sort index: Messages without sort_id weren't sorted correctly on secondary
Timo Sirainen <tss@iki.fi>
parents:
7612
diff
changeset
|
268 ctx->program->sort_program + 1, |
63602977ca9b
sort index: Messages without sort_id weren't sorted correctly on secondary
Timo Sirainen <tss@iki.fi>
parents:
7612
diff
changeset
|
269 n1->seq, n2->seq); |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
270 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
271 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
272 static void index_sort_zeroes(struct sort_string_context *ctx) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
273 { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
274 struct mail *mail = ctx->program->temp_mail; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
275 enum mail_sort_type sort_type = ctx->program->sort_program[0]; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
276 string_t *str; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
277 pool_t pool; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
278 struct mail_sort_node *nodes; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
279 unsigned int i, count; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
280 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
281 /* first get all the messages' sort strings. although this takes more |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
282 memory, it makes error handling easier and probably also helps |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
283 CPU caching. */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
284 ctx->sort_strings = i_new(const char *, ctx->last_seq + 1); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
285 ctx->sort_string_pool = pool = |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
286 pool_alloconly_create("sort strings", 1024*64); |
8781
513ba5a698a1
SORT: Don't waste data stack memory when sorting many messages.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
287 str = str_new(default_pool, 512); |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
288 nodes = array_get_modifiable(&ctx->zero_nodes, &count); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
289 for (i = 0; i < count; i++) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
290 i_assert(nodes[i].seq <= ctx->last_seq); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
291 |
8781
513ba5a698a1
SORT: Don't waste data stack memory when sorting many messages.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
292 T_BEGIN { |
513ba5a698a1
SORT: Don't waste data stack memory when sorting many messages.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
293 index_sort_header_get(mail, nodes[i].seq, |
513ba5a698a1
SORT: Don't waste data stack memory when sorting many messages.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
294 sort_type, str); |
513ba5a698a1
SORT: Don't waste data stack memory when sorting many messages.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
295 ctx->sort_strings[nodes[i].seq] = |
513ba5a698a1
SORT: Don't waste data stack memory when sorting many messages.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
296 str_len(str) == 0 ? "" : |
513ba5a698a1
SORT: Don't waste data stack memory when sorting many messages.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
297 p_strdup(pool, str_c(str)); |
513ba5a698a1
SORT: Don't waste data stack memory when sorting many messages.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
298 } T_END; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
299 } |
8781
513ba5a698a1
SORT: Don't waste data stack memory when sorting many messages.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
300 str_free(&str); |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
301 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
302 /* we have all strings, sort nodes based on them */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
303 static_zero_cmp_context = ctx; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
304 qsort(nodes, count, sizeof(struct mail_sort_node), |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
305 sort_node_zero_string_cmp); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
306 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
307 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
308 static const char * |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
309 index_sort_get_expunged_string(struct sort_string_context *ctx, uint32_t idx, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
310 string_t *str) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
311 { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
312 struct mail *mail = ctx->program->temp_mail; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
313 enum mail_sort_type sort_type = ctx->program->sort_program[0]; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
314 const struct mail_sort_node *nodes; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
315 const char *result = NULL; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
316 unsigned int i, count; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
317 uint32_t sort_id; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
318 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
319 /* Look forwards and backwards to see if there are |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
320 identical sort_ids. If we do find them, try to get |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
321 their sort string and use it to update the rest. */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
322 nodes = array_get(&ctx->nonzero_nodes, &count); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
323 sort_id = nodes[idx].sort_id; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
324 /* If previous sort ID is identical and its sort string is set, we can |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
325 trust it. If it's expunged, we already verified that there are no |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
326 non-expunged messages. */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
327 if (idx > 0 && nodes[idx-1].sort_id == sort_id && |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
328 ctx->sort_strings[nodes[idx].seq] != NULL) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
329 return ctx->sort_strings[nodes[idx].seq]; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
330 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
331 /* Go forwards as long as there are identical sort IDs. If we find one |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
332 that's not expunged, update string table for all messages with |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
333 identical sort IDs. */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
334 for (i = idx + 1; i < count; i++) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
335 if (nodes[i].sort_id != sort_id) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
336 break; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
337 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
338 if (ctx->sort_strings[nodes[i].seq] != NULL) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
339 /* usually we fill all identical sort_ids and this |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
340 shouldn't happen, but we can get here if we skipped |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
341 over messages when binary searching */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
342 result = ctx->sort_strings[nodes[i].seq]; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
343 break; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
344 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
345 if (index_sort_header_get(mail, nodes[i].seq, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
346 sort_type, str) >= 0) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
347 result = str_len(str) == 0 ? "" : |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
348 p_strdup(ctx->sort_string_pool, str_c(str)); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
349 break; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
350 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
351 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
352 if (result == NULL) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
353 /* unknown */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
354 return &expunged_msg; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
355 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
356 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
357 /* fill all identical sort_ids with the same value */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
358 for (i = idx; i > 0 && nodes[i-1].sort_id == sort_id; i--) ; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
359 for (i = idx; i < count && nodes[i].sort_id == sort_id; i++) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
360 ctx->sort_strings[nodes[i].seq] = result; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
361 return result; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
362 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
363 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
364 static const char * |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
365 index_sort_get_string(struct sort_string_context *ctx, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
366 uint32_t idx, uint32_t seq) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
367 { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
368 struct mail *mail = ctx->program->temp_mail; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
369 int ret; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
370 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
371 if (ctx->sort_strings[seq] == NULL) T_BEGIN { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
372 string_t *str; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
373 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
374 str = t_str_new(256); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
375 ret = index_sort_header_get(mail, seq, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
376 ctx->program->sort_program[0], str); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
377 if (str_len(str) > 0) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
378 ctx->sort_strings[seq] = |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
379 p_strdup(ctx->sort_string_pool, str_c(str)); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
380 } else if (ret >= 0) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
381 ctx->sort_strings[seq] = ""; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
382 } else { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
383 ctx->sort_strings[seq] = |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
384 index_sort_get_expunged_string(ctx, idx, str); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
385 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
386 } T_END; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
387 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
388 return ctx->sort_strings[seq]; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
389 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
390 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
391 static void |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
392 index_sort_bsearch(struct sort_string_context *ctx, const char *key, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
393 unsigned int start_idx, unsigned int *idx_r, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
394 const char **prev_str_r) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
395 { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
396 const struct mail_sort_node *nodes; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
397 const char *str, *str2; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
398 unsigned int idx, left_idx, right_idx, prev; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
399 int ret; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
400 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
401 nodes = array_get_modifiable(&ctx->nonzero_nodes, &right_idx); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
402 idx = left_idx = start_idx; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
403 while (left_idx < right_idx) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
404 idx = (left_idx + right_idx) / 2; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
405 str = index_sort_get_string(ctx, idx, nodes[idx].seq); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
406 if (str != &expunged_msg) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
407 ret = strcmp(key, str); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
408 else { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
409 /* put expunged messages first */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
410 ret = 1; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
411 for (prev = idx; prev > 0; ) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
412 prev--; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
413 str2 = index_sort_get_string(ctx, prev, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
414 nodes[prev].seq); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
415 if (str2 != &expunged_msg) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
416 ret = strcmp(key, str2); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
417 if (ret <= 0) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
418 idx = prev; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
419 str = str2; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
420 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
421 break; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
422 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
423 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
424 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
425 if (ret > 0) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
426 left_idx = idx+1; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
427 else if (ret < 0) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
428 right_idx = idx; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
429 else { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
430 *idx_r = idx + 1; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
431 *prev_str_r = str; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
432 return; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
433 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
434 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
435 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
436 if (left_idx > idx) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
437 idx++; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
438 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
439 *idx_r = idx; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
440 if (idx > start_idx) { |
7566 | 441 prev = idx; |
442 do { | |
443 prev--; | |
444 str2 = index_sort_get_string(ctx, prev, | |
445 nodes[prev].seq); | |
446 } while (str2 == &expunged_msg && prev > 0 && | |
447 nodes[prev-1].sort_id == nodes[prev].sort_id); | |
448 *prev_str_r = str2; | |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
449 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
450 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
451 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
452 static void index_sort_merge(struct sort_string_context *ctx) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
453 { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
454 struct mail_sort_node *znodes, *nznodes; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
455 const char *zstr, *nzstr, *prev_str; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
456 unsigned int zpos, nzpos, nz_next_pos, zcount, nzcount; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
457 int ret; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
458 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
459 /* both zero_nodes and nonzero_nodes are sorted. we'll now just have |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
460 to merge them together. use sorted_nodes as the result array. */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
461 i_array_init(&ctx->sorted_nodes, array_count(&ctx->nonzero_nodes) + |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
462 array_count(&ctx->zero_nodes)); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
463 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
464 znodes = array_get_modifiable(&ctx->zero_nodes, &zcount); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
465 nznodes = array_get_modifiable(&ctx->nonzero_nodes, &nzcount); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
466 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
467 prev_str = NULL; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
468 for (zpos = nzpos = 0; zpos < zcount && nzpos < nzcount; ) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
469 zstr = ctx->sort_strings[znodes[zpos].seq]; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
470 nzstr = index_sort_get_string(ctx, nzpos, nznodes[nzpos].seq); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
471 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
472 if (nzstr != &expunged_msg) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
473 ret = strcmp(zstr, nzstr); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
474 else if (prev_str != NULL && strcmp(zstr, prev_str) == 0) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
475 /* identical to previous message, must keep them |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
476 together */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
477 ret = -1; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
478 } else { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
479 /* we can't be yet sure about the order, but future |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
480 nznodes may reveal that the znode must be added |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
481 later. if future nznodes don't reveal that, we have |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
482 no idea about these nodes' order. so just always |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
483 put the expunged message first. */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
484 ret = 1; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
485 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
486 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
487 if (ret <= 0) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
488 array_append(&ctx->sorted_nodes, &znodes[zpos], 1); |
7566 | 489 prev_str = zstr; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
490 zpos++; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
491 } else { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
492 array_append(&ctx->sorted_nodes, &nznodes[nzpos], 1); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
493 prev_str = nzstr; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
494 nzpos++; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
495 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
496 /* avoid looking up all existing messages' strings by |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
497 binary searching the next zero-node position. don't |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
498 bother if it looks like more work than linear |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
499 scanning. */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
500 if (zcount - zpos < (nzcount - nzpos)/2) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
501 index_sort_bsearch(ctx, zstr, nzpos, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
502 &nz_next_pos, &prev_str); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
503 array_append(&ctx->sorted_nodes, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
504 &nznodes[nzpos], |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
505 nz_next_pos - nzpos); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
506 nzpos = nz_next_pos; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
507 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
508 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
509 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
510 /* only one of zero_nodes and nonzero_nodes can be non-empty now */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
511 for (; zpos < zcount; zpos++) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
512 array_append(&ctx->sorted_nodes, &znodes[zpos], 1); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
513 for (; nzpos < nzcount; nzpos++) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
514 array_append(&ctx->sorted_nodes, &nznodes[nzpos], 1); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
515 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
516 /* future index_sort_get_string() calls use ctx->nonzero_nodes, but we |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
517 use only ctx->sorted_nodes. make them identical. */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
518 array_free(&ctx->nonzero_nodes); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
519 ctx->nonzero_nodes = ctx->sorted_nodes; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
520 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
521 |
7614
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
522 static int |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
523 index_sort_add_ids_range(struct sort_string_context *ctx, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
524 unsigned int left_idx, unsigned int right_idx) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
525 { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
526 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
527 struct mail_sort_node *nodes; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
528 unsigned int i, count, rightmost_idx, skip; |
8799 | 529 const char *left_str = NULL, *right_str = NULL, *str = NULL; |
7609
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
530 uint32_t left_sort_id, right_sort_id, diff; |
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
531 bool no_left_str = FALSE, no_right_str = FALSE; |
7614
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
532 int ret; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
533 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
534 nodes = array_get_modifiable(&ctx->sorted_nodes, &count); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
535 rightmost_idx = count - 1; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
536 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
537 /* get the sort IDs from left and right */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
538 left_sort_id = nodes[left_idx].sort_id; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
539 right_sort_id = nodes[right_idx].sort_id; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
540 /* check if all of them should have the same sort IDs. we don't want |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
541 to hit the renumbering code in that situation. */ |
7612
5824e6f1d279
sort index: Removed some optimization checks that wouldn't always be true,
Timo Sirainen <tss@iki.fi>
parents:
7609
diff
changeset
|
542 if (left_sort_id == right_sort_id && left_sort_id != 0) { |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
543 /* they should all have the same sort ID */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
544 for (i = left_idx + 1; i < right_idx; i++) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
545 nodes[i].sort_id = left_sort_id; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
546 nodes[i].sort_id_changed = TRUE; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
547 } |
7614
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
548 return 0; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
549 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
550 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
551 if (left_sort_id == 0) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
552 i_assert(left_idx == 0); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
553 left_sort_id = 1; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
554 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
555 if (right_sort_id == 0) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
556 i_assert(right_idx == rightmost_idx); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
557 right_sort_id = (uint32_t)-1; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
558 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
559 i_assert(left_sort_id <= right_sort_id); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
560 |
7609
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
561 diff = right_sort_id - left_sort_id; |
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
562 while (diff / (right_idx-left_idx + 2) == 0) { |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
563 /* we most likely don't have enough space. we have to |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
564 renumber some of the existing sort IDs. do this by |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
565 widening the area we're giving sort IDs. */ |
8070
7e3590da43a9
sort indexes: One more assert-crashfix when renumbering sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
8018
diff
changeset
|
566 while (left_idx > 0) { |
7e3590da43a9
sort indexes: One more assert-crashfix when renumbering sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
8018
diff
changeset
|
567 if (nodes[--left_idx].sort_id != left_sort_id) { |
7e3590da43a9
sort indexes: One more assert-crashfix when renumbering sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
8018
diff
changeset
|
568 left_sort_id = nodes[left_idx].sort_id; |
7e3590da43a9
sort indexes: One more assert-crashfix when renumbering sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
8018
diff
changeset
|
569 if (left_sort_id == 0) { |
7e3590da43a9
sort indexes: One more assert-crashfix when renumbering sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
8018
diff
changeset
|
570 i_assert(left_idx == 0); |
7e3590da43a9
sort indexes: One more assert-crashfix when renumbering sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
8018
diff
changeset
|
571 left_sort_id = 1; |
7e3590da43a9
sort indexes: One more assert-crashfix when renumbering sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
8018
diff
changeset
|
572 } |
7e3590da43a9
sort indexes: One more assert-crashfix when renumbering sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
8018
diff
changeset
|
573 break; |
7568
66e6b61680a5
Sort index: Fix to renumbering sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
7567
diff
changeset
|
574 } |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
575 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
576 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
577 while (right_idx < rightmost_idx) { |
7609
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
578 right_idx++; |
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
579 if (nodes[right_idx].sort_id > right_sort_id) |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
580 break; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
581 } |
7568
66e6b61680a5
Sort index: Fix to renumbering sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
7567
diff
changeset
|
582 right_sort_id = nodes[right_idx].sort_id; |
66e6b61680a5
Sort index: Fix to renumbering sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
7567
diff
changeset
|
583 if (right_sort_id == 0) { |
66e6b61680a5
Sort index: Fix to renumbering sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
7567
diff
changeset
|
584 i_assert(right_idx == rightmost_idx); |
66e6b61680a5
Sort index: Fix to renumbering sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
7567
diff
changeset
|
585 right_sort_id = (uint32_t)-1; |
66e6b61680a5
Sort index: Fix to renumbering sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
7567
diff
changeset
|
586 } |
8018 | 587 i_assert(left_sort_id <= right_sort_id); |
7609
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
588 |
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
589 if (diff == right_sort_id - left_sort_id) { |
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
590 /* we did nothing, but there's still not enough space. |
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
591 have to renumber the leftmost/rightmost node(s) */ |
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
592 i_assert(left_idx == 0 && right_idx == rightmost_idx); |
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
593 if (left_sort_id > 1) { |
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
594 left_sort_id = 1; |
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
595 no_left_str = TRUE; |
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
596 } else { |
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
597 i_assert(right_sort_id != (uint32_t)-1); |
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
598 right_sort_id = (uint32_t)-1; |
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
599 no_right_str = TRUE; |
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
600 } |
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
601 } |
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
602 diff = right_sort_id - left_sort_id; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
603 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
604 |
7609
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
605 if (nodes[left_idx].sort_id != 0 && !no_left_str) { |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
606 left_str = index_sort_get_string(ctx, left_idx, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
607 nodes[left_idx].seq); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
608 if (left_str == &expunged_msg) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
609 /* not equivalent with any message */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
610 left_str = NULL; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
611 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
612 left_idx++; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
613 } |
7609
c008dde3c973
sort index: Fixed infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
7569
diff
changeset
|
614 if (nodes[right_idx].sort_id != 0 && !no_right_str) { |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
615 right_str = index_sort_get_string(ctx, right_idx, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
616 nodes[right_idx].seq); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
617 if (right_str == &expunged_msg) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
618 /* not equivalent with any message */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
619 right_str = NULL; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
620 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
621 right_idx--; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
622 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
623 i_assert(left_idx <= right_idx); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
624 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
625 /* give (new) sort IDs to all nodes in left_idx..right_idx range. |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
626 divide the available space so that each message gets an equal sized |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
627 share. some messages' sort strings may be equivalent, so give them |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
628 the same sort IDs. */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
629 for (i = left_idx; i <= right_idx; i++) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
630 str = index_sort_get_string(ctx, i, nodes[i].seq); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
631 if (str == &expunged_msg) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
632 /* it doesn't really matter what we give to this |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
633 message, since it's only temporary and we don't |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
634 know its correct position anyway. so let's assume |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
635 it's equivalent to previous message. */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
636 nodes[i].sort_id = left_sort_id; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
637 continue; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
638 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
639 |
7614
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
640 ret = left_str == NULL ? 1 : strcmp(str, left_str); |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
641 if (ret <= 0) { |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
642 if (ret < 0) { |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
643 /* broken sort_ids */ |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
644 return -1; |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
645 } |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
646 nodes[i].sort_id = left_sort_id; |
7614
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
647 } else if (right_str != NULL && strcmp(str, right_str) == 0) { |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
648 /* the rest of the sort IDs should be the same */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
649 nodes[i].sort_id = right_sort_id; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
650 left_sort_id = right_sort_id; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
651 } else { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
652 /* divide the available space equally. leave the same |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
653 sized space also between the first and the last |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
654 messages */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
655 skip = (right_sort_id - left_sort_id) / |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
656 (right_idx - i + 2); |
8193
b3fb8215a339
Sort indexes: Don't assert-crash with broken sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
8070
diff
changeset
|
657 if (skip == 0) { |
b3fb8215a339
Sort indexes: Don't assert-crash with broken sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
8070
diff
changeset
|
658 /* broken sort IDs (we previously assigned |
b3fb8215a339
Sort indexes: Don't assert-crash with broken sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
8070
diff
changeset
|
659 left_sort_id=right_sort_id) */ |
b3fb8215a339
Sort indexes: Don't assert-crash with broken sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
8070
diff
changeset
|
660 return -1; |
b3fb8215a339
Sort indexes: Don't assert-crash with broken sort IDs.
Timo Sirainen <tss@iki.fi>
parents:
8070
diff
changeset
|
661 } |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
662 left_sort_id += skip; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
663 i_assert(left_sort_id < right_sort_id); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
664 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
665 nodes[i].sort_id = left_sort_id; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
666 left_str = str; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
667 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
668 nodes[i].sort_id_changed = TRUE; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
669 } |
7954
d75fdd0fb8b2
Sort index sometimes failed wrongly with "Sort IDs broken" errors.
Timo Sirainen <tss@iki.fi>
parents:
7859
diff
changeset
|
670 return right_str == NULL || strcmp(str, right_str) < 0 || |
d75fdd0fb8b2
Sort index sometimes failed wrongly with "Sort IDs broken" errors.
Timo Sirainen <tss@iki.fi>
parents:
7859
diff
changeset
|
671 (strcmp(str, right_str) == 0 && |
d75fdd0fb8b2
Sort index sometimes failed wrongly with "Sort IDs broken" errors.
Timo Sirainen <tss@iki.fi>
parents:
7859
diff
changeset
|
672 nodes[i-1].sort_id == right_sort_id) ? 0 : -1; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
673 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
674 |
7614
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
675 static int |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
676 index_sort_add_sort_ids(struct sort_string_context *ctx) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
677 { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
678 const struct mail_sort_node *nodes; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
679 unsigned int i, left_idx, right_idx, count; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
680 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
681 nodes = array_get(&ctx->sorted_nodes, &count); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
682 for (i = 0; i < count; i++) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
683 if (nodes[i].sort_id != 0) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
684 continue; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
685 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
686 /* get the range for all sort_id=0 nodes. include the nodes |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
687 left and right of the range as well */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
688 for (right_idx = i + 1; right_idx < count; right_idx++) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
689 if (nodes[right_idx].sort_id != 0) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
690 break; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
691 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
692 if (right_idx == count) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
693 right_idx--; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
694 left_idx = i == 0 ? 0 : i - 1; |
7614
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
695 if (index_sort_add_ids_range(ctx, left_idx, right_idx) < 0) |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
696 return -1; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
697 } |
7614
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
698 return 0; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
699 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
700 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
701 static void index_sort_write_changed_sort_ids(struct sort_string_context *ctx) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
702 { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
703 struct index_transaction_context *t = |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
704 (struct index_transaction_context *)ctx->program->t; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
705 uint32_t ext_id = ctx->ext_id; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
706 const struct mail_sort_node *nodes; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
707 unsigned int i, count; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
708 |
7567
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
709 if (ctx->no_writing) { |
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
710 /* our reset_id is already stale - don't even bother |
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
711 trying to write */ |
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
712 return; |
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
713 } |
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
714 |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
715 mail_index_ext_reset_inc(t->trans, ext_id, ctx->highest_reset_id, FALSE); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
716 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
717 /* add the missing sort IDs to index */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
718 nodes = array_get_modifiable(&ctx->sorted_nodes, &count); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
719 for (i = 0; i < count; i++) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
720 i_assert(nodes[i].sort_id != 0); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
721 if (!nodes[i].sort_id_changed || nodes[i].no_update) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
722 continue; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
723 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
724 mail_index_update_ext(t->trans, nodes[i].seq, ext_id, |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
725 &nodes[i].sort_id, NULL); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
726 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
727 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
728 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
729 static int sort_node_cmp(const void *p1, const void *p2) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
730 { |
7859
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
731 struct sort_string_context *ctx = static_zero_cmp_context; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
732 const struct mail_sort_node *n1 = p1, *n2 = p2; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
733 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
734 if (n1->sort_id < n2->sort_id) |
7859
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
735 return !ctx->reverse ? -1 : 1; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
736 if (n1->sort_id > n2->sort_id) |
7859
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
737 return !ctx->reverse ? 1 : -1; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
738 |
7859
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
739 return index_sort_node_cmp_type(ctx->program->temp_mail, |
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
740 ctx->program->sort_program + 1, |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
741 n1->seq, n2->seq); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
742 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
743 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
744 static void index_sort_add_missing(struct sort_string_context *ctx) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
745 { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
746 struct mail_sort_node node; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
747 const uint32_t *seqs; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
748 unsigned int i, count; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
749 uint32_t seq, next_seq; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
750 |
7567
9c0d2413735d
Sort index: Handle reset_id growing while adding non-wanted messages to sort
Timo Sirainen <tss@iki.fi>
parents:
7566
diff
changeset
|
751 ctx->have_all_wanted = TRUE; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
752 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
753 seqs = array_get(&ctx->program->seqs, &count); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
754 for (i = 0, next_seq = 1; i < count; i++) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
755 if (seqs[i] == next_seq) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
756 next_seq++; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
757 else { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
758 i_assert(next_seq < seqs[i]); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
759 for (seq = next_seq; seq < seqs[i]; seq++) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
760 memset(&node, 0, sizeof(node)); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
761 node.seq = seq; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
762 index_sort_node_add(ctx, &node); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
763 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
764 next_seq = seqs[i] + 1; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
765 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
766 } |
7569
ea913434d522
Sort index optimization: Don't write changes to sort IDs if we're doing it
Timo Sirainen <tss@iki.fi>
parents:
7568
diff
changeset
|
767 |
ea913434d522
Sort index optimization: Don't write changes to sort IDs if we're doing it
Timo Sirainen <tss@iki.fi>
parents:
7568
diff
changeset
|
768 if (ctx->lowest_nonexpunged_zero == 0) { |
ea913434d522
Sort index optimization: Don't write changes to sort IDs if we're doing it
Timo Sirainen <tss@iki.fi>
parents:
7568
diff
changeset
|
769 /* we're handling only expunged zeros. if it causes us to |
ea913434d522
Sort index optimization: Don't write changes to sort IDs if we're doing it
Timo Sirainen <tss@iki.fi>
parents:
7568
diff
changeset
|
770 renumber some existing sort IDs, don't save them. */ |
ea913434d522
Sort index optimization: Don't write changes to sort IDs if we're doing it
Timo Sirainen <tss@iki.fi>
parents:
7568
diff
changeset
|
771 ctx->no_writing = TRUE; |
ea913434d522
Sort index optimization: Don't write changes to sort IDs if we're doing it
Timo Sirainen <tss@iki.fi>
parents:
7568
diff
changeset
|
772 } |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
773 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
774 |
7614
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
775 static void index_sort_list_reset_broken(struct sort_string_context *ctx) |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
776 { |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
777 struct mailbox *box = ctx->program->t->box; |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
778 struct mail_sort_node *nodes; |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
779 unsigned int i, count; |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
780 |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
781 mail_storage_set_critical(box->storage, |
9293
c50f133f0acc
sort: Don't assert-crash if sort indexes are broken.
Timo Sirainen <tss@iki.fi>
parents:
8799
diff
changeset
|
782 "%s: Broken %s indexes, resetting", |
c50f133f0acc
sort: Don't assert-crash if sort indexes are broken.
Timo Sirainen <tss@iki.fi>
parents:
8799
diff
changeset
|
783 box->name, ctx->primary_sort_name); |
7614
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
784 |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
785 array_clear(&ctx->zero_nodes); |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
786 array_append_array(&ctx->zero_nodes, |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
787 &ctx->nonzero_nodes); |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
788 array_clear(&ctx->nonzero_nodes); |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
789 |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
790 nodes = array_get_modifiable(&ctx->zero_nodes, &count); |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
791 for (i = 0; i < count; i++) |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
792 nodes[i].sort_id = 0; |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
793 } |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
794 |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
795 void index_sort_list_finish_string(struct mail_search_sort_program *program) |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
796 { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
797 struct sort_string_context *ctx = program->context; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
798 struct mail_sort_node *nodes; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
799 unsigned int i, count; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
800 uint32_t seq; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
801 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
802 nodes = array_get_modifiable(&ctx->nonzero_nodes, &count); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
803 |
7859
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
804 static_zero_cmp_context = ctx; |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
805 if (array_count(&ctx->zero_nodes) == 0) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
806 /* fast path: we have all sort IDs */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
807 qsort(nodes, count, sizeof(struct mail_sort_node), |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
808 sort_node_cmp); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
809 |
7956 | 810 if (!array_is_created(&program->seqs)) |
811 i_array_init(&program->seqs, count); | |
812 else | |
813 array_clear(&program->seqs); | |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
814 for (i = 0; i < count; i++) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
815 seq = nodes[i].seq; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
816 array_append(&program->seqs, &seq, 1); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
817 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
818 array_free(&ctx->nonzero_nodes); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
819 } else { |
8480
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
820 if (ctx->seqs_nonsorted) { |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
821 /* the nodes need to be sorted by sequence initially */ |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
822 index_sort_nodes_by_seq(ctx); |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
823 } |
f0c9677bf489
Sorting: Don't break if search code adds sequences in random order.
Timo Sirainen <tss@iki.fi>
parents:
8193
diff
changeset
|
824 |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
825 /* we have to add some sort IDs. we'll do this for all |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
826 messages, so first remember what messages we wanted |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
827 to know about. */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
828 index_sort_generate_seqs(ctx); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
829 /* add messages not in seqs list */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
830 index_sort_add_missing(ctx); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
831 /* sort all messages with sort IDs */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
832 nodes = array_get_modifiable(&ctx->nonzero_nodes, &count); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
833 qsort(nodes, count, sizeof(struct mail_sort_node), |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
834 sort_node_cmp); |
7614
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
835 for (;;) { |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
836 /* sort all messages without sort IDs */ |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
837 index_sort_zeroes(ctx); |
7859
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
838 |
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
839 if (ctx->reverse) { |
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
840 /* sort lists are descending currently, but |
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
841 merging and sort ID assigning works only |
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
842 with ascending lists. reverse the lists |
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
843 temporarily. we can't do this while earlier |
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
844 because secondary sort conditions must not |
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
845 be reversed in results (but while assigning |
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
846 sort IDs it doesn't matter). */ |
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
847 array_reverse(&ctx->nonzero_nodes); |
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
848 array_reverse(&ctx->zero_nodes); |
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
849 } |
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
850 |
7614
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
851 /* merge zero and non-zero arrays into sorted_nodes */ |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
852 index_sort_merge(ctx); |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
853 /* give sort IDs to messages missing them */ |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
854 if (index_sort_add_sort_ids(ctx) == 0) |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
855 break; |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
856 |
7859
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
857 /* broken, try again with sort IDs reset */ |
7614
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
858 index_sort_list_reset_broken(ctx); |
dd899a1841d9
sort index: Try to catch broken sort_ids and recreate them correctly instead
Timo Sirainen <tss@iki.fi>
parents:
7613
diff
changeset
|
859 } |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
860 index_sort_write_changed_sort_ids(ctx); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
861 |
7859
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
862 if (ctx->reverse) { |
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
863 /* restore the correct sort order */ |
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
864 array_reverse(&ctx->sorted_nodes); |
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
865 } |
f431c67621ed
Reversing the primary sort criterion reversed also reversed secondary
Timo Sirainen <tss@iki.fi>
parents:
7614
diff
changeset
|
866 |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
867 nodes = array_get_modifiable(&ctx->sorted_nodes, &count); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
868 array_clear(&program->seqs); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
869 for (i = 0; i < count; i++) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
870 if (nodes[i].wanted) { |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
871 seq = nodes[i].seq; |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
872 array_append(&program->seqs, &seq, 1); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
873 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
874 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
875 pool_unref(&ctx->sort_string_pool); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
876 i_free(ctx->sort_strings); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
877 array_free(&ctx->sorted_nodes); |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
878 /* NOTE: we already freed nonzero_nodes and made it point to |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
879 sorted_nodes. */ |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
880 } |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
881 |
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
882 array_free(&ctx->zero_nodes); |
7956 | 883 i_free(ctx); |
884 program->context = NULL; | |
7564
4a9ce9df52c5
Message sort index handling rewrite to fix several race conditions when
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
885 } |