dovecot-1.1: Reversing the primary sort criterion reversed also ...
dovecot at dovecot.org
dovecot at dovecot.org
Fri Jun 13 04:39:54 EEST 2008
details: http://hg.dovecot.org/dovecot-1.1/rev/5e5721c49d3d
changeset: 7659:5e5721c49d3d
user: Timo Sirainen <tss at iki.fi>
date: Fri Jun 13 04:39:49 2008 +0300
description:
Reversing the primary sort criterion reversed also reversed secondary
criterions.
Fixed reverse sorting the first condition.
diffstat:
3 files changed, 41 insertions(+), 36 deletions(-)
src/lib-storage/index/index-sort-private.h | 2 -
src/lib-storage/index/index-sort-string.c | 39 ++++++++++++++++++++--------
src/lib-storage/index/index-sort.c | 36 ++++++++-----------------
diffs (205 lines):
diff -r 7f7de0ca30c5 -r 5e5721c49d3d src/lib-storage/index/index-sort-private.h
--- 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 @@ struct mail_search_sort_program {
ARRAY_TYPE(uint32_t) seqs;
unsigned int iter_idx;
-
- unsigned int reverse:1;
};
int index_sort_header_get(struct mail *mail, uint32_t seq,
diff -r 7f7de0ca30c5 -r 5e5721c49d3d src/lib-storage/index/index-sort-string.c
--- 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 @@ struct sort_string_context {
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 @@ void index_sort_list_init_string(struct
}
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 @@ static int sort_node_zero_string_cmp(con
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 void index_sort_write_changed_sor
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 index_sort_node_cmp_type(program->temp_mail,
- program->sort_program + 1,
+ return !ctx->reverse ? 1 : -1;
+
+ return index_sort_node_cmp_type(ctx->program->temp_mail,
+ ctx->program->sort_program + 1,
n1->seq, n2->seq);
}
@@ -744,7 +745,7 @@ void index_sort_list_finish_string(struc
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,16 +771,34 @@ void index_sort_list_finish_string(struc
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);
diff -r 7f7de0ca30c5 -r 5e5721c49d3d src/lib-storage/index/index-sort.c
--- 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 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 @@ static int sort_node_date_cmp(const void
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 @@ static int sort_node_size_cmp(const void
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 @@ void index_sort_list_finish(struct mail_
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 @@ bool index_sort_list_next(struct mail_se
{
const uint32_t *seqp;
- if (!program->reverse) {
- 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);
- }
+ if (program->iter_idx == array_count(&program->seqs))
+ return FALSE;
+
+ seqp = array_idx(&program->seqs, program->iter_idx++);
mail_set_seq(mail, *seqp);
return TRUE;
}
@@ -188,11 +181,7 @@ index_sort_program_init(struct mailbox_t
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 @@ int index_sort_node_cmp_type(struct mail
seq1, seq2);
}
- /* primary reversion isn't in sort_program */
if ((*sort_program & MAIL_SORT_FLAG_REVERSE) != 0)
ret = ret < 0 ? 1 : -1;
return ret;
More information about the dovecot-cvs
mailing list