Mercurial > dovecot > original-hg > dovecot-1.2
changeset 7859:f431c67621ed HEAD
Reversing the primary sort criterion reversed also reversed secondary
criterions.
Fixed reverse sorting the first condition.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 13 Jun 2008 04:39:49 +0300 |
parents | 69c1e3e13464 |
children | 85f457b9b3ad |
files | src/lib-storage/index/index-sort-private.h src/lib-storage/index/index-sort-string.c src/lib-storage/index/index-sort.c |
diffstat | 3 files changed, 39 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/index-sort-private.h Fri Jun 13 04:36:19 2008 +0300 +++ b/src/lib-storage/index/index-sort-private.h Fri Jun 13 04:39:49 2008 +0300 @@ -15,8 +15,6 @@ ARRAY_TYPE(uint32_t) seqs; unsigned int iter_idx; - - unsigned int reverse:1; }; int index_sort_header_get(struct mail *mail, uint32_t seq,
--- a/src/lib-storage/index/index-sort-string.c Fri Jun 13 04:36:19 2008 +0300 +++ b/src/lib-storage/index/index-sort-string.c Fri Jun 13 04:39:49 2008 +0300 @@ -39,11 +39,11 @@ unsigned int regetting:1; unsigned int have_all_wanted:1; unsigned int no_writing:1; + unsigned int reverse:1; }; static char expunged_msg; static struct sort_string_context *static_zero_cmp_context; -static struct mail_search_sort_program *static_sort_node_cmp_context; static void index_sort_node_add(struct sort_string_context *ctx, struct mail_sort_node *node); @@ -72,6 +72,7 @@ } program->context = ctx = i_new(struct sort_string_context, 1); + ctx->reverse = (program->sort_program[0] & MAIL_SORT_FLAG_REVERSE) != 0; ctx->program = program; ctx->ext_id = mail_index_ext_register(ibox->index, name, 0, sizeof(uint32_t), @@ -219,7 +220,7 @@ ret = strcmp(ctx->sort_strings[n1->seq], ctx->sort_strings[n2->seq]); if (ret != 0) - return ret; + return !ctx->reverse ? ret : -ret; return index_sort_node_cmp_type(ctx->program->temp_mail, ctx->program->sort_program + 1, @@ -671,16 +672,16 @@ static int sort_node_cmp(const void *p1, const void *p2) { - struct mail_search_sort_program *program = static_sort_node_cmp_context; + struct sort_string_context *ctx = static_zero_cmp_context; const struct mail_sort_node *n1 = p1, *n2 = p2; if (n1->sort_id < n2->sort_id) - return -1; + return !ctx->reverse ? -1 : 1; if (n1->sort_id > n2->sort_id) - return 1; + return !ctx->reverse ? 1 : -1; - return index_sort_node_cmp_type(program->temp_mail, - program->sort_program + 1, + return index_sort_node_cmp_type(ctx->program->temp_mail, + ctx->program->sort_program + 1, n1->seq, n2->seq); } @@ -744,7 +745,7 @@ nodes = array_get_modifiable(&ctx->nonzero_nodes, &count); - static_sort_node_cmp_context = program; + static_zero_cmp_context = ctx; if (array_count(&ctx->zero_nodes) == 0) { /* fast path: we have all sort IDs */ qsort(nodes, count, sizeof(struct mail_sort_node), @@ -770,17 +771,35 @@ for (;;) { /* sort all messages without sort IDs */ index_sort_zeroes(ctx); + + if (ctx->reverse) { + /* sort lists are descending currently, but + merging and sort ID assigning works only + with ascending lists. reverse the lists + temporarily. we can't do this while earlier + because secondary sort conditions must not + be reversed in results (but while assigning + sort IDs it doesn't matter). */ + array_reverse(&ctx->nonzero_nodes); + array_reverse(&ctx->zero_nodes); + } + /* merge zero and non-zero arrays into sorted_nodes */ index_sort_merge(ctx); /* give sort IDs to messages missing them */ if (index_sort_add_sort_ids(ctx) == 0) break; - /* broken, try again */ + /* broken, try again with sort IDs reset */ index_sort_list_reset_broken(ctx); } index_sort_write_changed_sort_ids(ctx); + if (ctx->reverse) { + /* restore the correct sort order */ + array_reverse(&ctx->sorted_nodes); + } + nodes = array_get_modifiable(&ctx->sorted_nodes, &count); array_clear(&program->seqs); for (i = 0; i < count; i++) {
--- a/src/lib-storage/index/index-sort.c Fri Jun 13 04:36:19 2008 +0300 +++ b/src/lib-storage/index/index-sort.c Fri Jun 13 04:39:49 2008 +0300 @@ -26,6 +26,7 @@ struct sort_cmp_context { struct mail_search_sort_program *program; struct mail *mail; + bool reverse; }; static struct sort_cmp_context static_node_cmp_context; @@ -87,9 +88,9 @@ const struct mail_sort_node_date *n1 = p1, *n2 = p2; if (n1->date < n2->date) - return -1; + return !ctx->reverse ? -1 : 1; if (n1->date > n2->date) - return 1; + return !ctx->reverse ? 1 : -1; return index_sort_node_cmp_type(ctx->mail, ctx->program->sort_program + 1, @@ -117,9 +118,9 @@ const struct mail_sort_node_size *n1 = p1, *n2 = p2; if (n1->size < n2->size) - return -1; + return !ctx->reverse ? -1 : 1; if (n1->size > n2->size) - return 1; + return !ctx->reverse ? 1 : -1; return index_sort_node_cmp_type(ctx->mail, ctx->program->sort_program + 1, @@ -146,11 +147,10 @@ memset(&static_node_cmp_context, 0, sizeof(static_node_cmp_context)); static_node_cmp_context.program = program; static_node_cmp_context.mail = program->temp_mail; + static_node_cmp_context.reverse = + (program->sort_program[0] & MAIL_SORT_FLAG_REVERSE) != 0; program->sort_list_finish(program); - - if (program->reverse) - program->iter_idx = array_count(&program->seqs); } bool index_sort_list_next(struct mail_search_sort_program *program, @@ -158,17 +158,10 @@ { const uint32_t *seqp; - if (!program->reverse) { - if (program->iter_idx == array_count(&program->seqs)) - return FALSE; + if (program->iter_idx == array_count(&program->seqs)) + return FALSE; - seqp = array_idx(&program->seqs, program->iter_idx++); - } else { - if (program->iter_idx == 0) - return FALSE; - - seqp = array_idx(&program->seqs, --program->iter_idx); - } + seqp = array_idx(&program->seqs, program->iter_idx++); mail_set_seq(mail, *seqp); return TRUE; } @@ -188,11 +181,7 @@ program->t = t; program->temp_mail = mail_alloc(t, 0, NULL); - /* primary reversion isn't stored to sort_program. we handle it by - iterating backwards at the end. */ - program->reverse = (sort_program[0] & MAIL_SORT_FLAG_REVERSE) != 0; - program->sort_program[0] = sort_program[0] & ~MAIL_SORT_FLAG_REVERSE; - for (i = 1; i < MAX_SORT_PROGRAM_SIZE; i++) { + for (i = 0; i < MAX_SORT_PROGRAM_SIZE; i++) { program->sort_program[i] = sort_program[i]; if (sort_program[i] == MAIL_SORT_END) break; @@ -387,7 +376,6 @@ seq1, seq2); } - /* primary reversion isn't in sort_program */ if ((*sort_program & MAIL_SORT_FLAG_REVERSE) != 0) ret = ret < 0 ? 1 : -1; return ret;