Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8480:f0c9677bf489 HEAD
Sorting: Don't break if search code adds sequences in random order.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 23 Nov 2008 02:36:08 +0200 |
parents | bcdbf33ae9b8 |
children | 9db582413fef |
files | src/lib-storage/index/index-sort-string.c |
diffstat | 1 files changed, 36 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/index-sort-string.c Sun Nov 23 01:59:35 2008 +0200 +++ b/src/lib-storage/index/index-sort-string.c Sun Nov 23 02:36:08 2008 +0200 @@ -33,13 +33,14 @@ pool_t sort_string_pool; unsigned int first_missing_sort_id_idx; - uint32_t ext_id, last_seq, highest_reset_id; + uint32_t ext_id, last_seq, highest_reset_id, prev_seq; uint32_t lowest_nonexpunged_zero; unsigned int regetting:1; unsigned int have_all_wanted:1; unsigned int no_writing:1; unsigned int reverse:1; + unsigned int seqs_nonsorted:1; }; static char expunged_msg; @@ -81,6 +82,29 @@ i_array_init(&ctx->nonzero_nodes, 128); } +static int sort_node_seq_cmp(const void *p1, const void *p2) +{ + const struct mail_sort_node *n1 = p1, *n2 = p2; + + if (n1->seq < n2->seq) + return -1; + if (n1->seq > n2->seq) + return 1; + return 0; +} + +static void index_sort_nodes_by_seq(struct sort_string_context *ctx) +{ + struct mail_sort_node *nodes; + unsigned int count; + + nodes = array_get_modifiable(&ctx->zero_nodes, &count); + qsort(nodes, count, sizeof(struct mail_sort_node), sort_node_seq_cmp); + + nodes = array_get_modifiable(&ctx->nonzero_nodes, &count); + qsort(nodes, count, sizeof(struct mail_sort_node), sort_node_seq_cmp); +} + static void index_sort_generate_seqs(struct sort_string_context *ctx) { struct mail_sort_node *nodes, *nodes2; @@ -203,13 +227,18 @@ void index_sort_list_add_string(struct mail_search_sort_program *program, struct mail *mail) { + struct sort_string_context *ctx = program->context; struct mail_sort_node node; memset(&node, 0, sizeof(node)); node.seq = mail->seq; node.wanted = TRUE; - index_sort_node_add(program->context, &node); + if (mail->seq < ctx->prev_seq) + ctx->seqs_nonsorted = TRUE; + ctx->prev_seq = mail->seq; + + index_sort_node_add(ctx, &node); } static int sort_node_zero_string_cmp(const void *p1, const void *p2) @@ -770,6 +799,11 @@ } array_free(&ctx->nonzero_nodes); } else { + if (ctx->seqs_nonsorted) { + /* the nodes need to be sorted by sequence initially */ + index_sort_nodes_by_seq(ctx); + } + /* we have to add some sort IDs. we'll do this for all messages, so first remember what messages we wanted to know about. */