Mercurial > dovecot > original-hg > dovecot-1.2
diff src/imap/cmd-sort.c @ 4303:5f03738219a6 HEAD
Changed mail-storage API to do the mail sorting internally. Optimized it
internally to keep a 32bit sort_id field in index for each used primary sort
condition. Practically this should mean less disk I/O, memory and CPU usage
when SORT command is used.
author | Timo Sirainen <timo.sirainen@movial.fi> |
---|---|
date | Thu, 08 Jun 2006 15:49:31 +0300 |
parents | 55df57c028d4 |
children | ff2272c228cc |
line wrap: on
line diff
--- a/src/imap/cmd-sort.c Wed Jun 07 12:05:05 2006 +0300 +++ b/src/imap/cmd-sort.c Thu Jun 08 15:49:31 2006 +0300 @@ -20,28 +20,32 @@ { MAIL_SORT_SUBJECT, "subject" }, { MAIL_SORT_TO, "to" }, - { MAIL_SORT_REVERSE, "reverse" }, { MAIL_SORT_END, NULL } }; -static enum mail_sort_type * -get_sort_program(struct client_command_context *cmd, struct imap_arg *args) +static int +get_sort_program(struct client_command_context *cmd, struct imap_arg *args, + enum mail_sort_type program[MAX_SORT_PROGRAM_SIZE]) { - enum mail_sort_type type; - buffer_t *buf; - int i; + enum mail_sort_type mask = 0; + unsigned int i, pos; + bool reverse; if (args->type == IMAP_ARG_EOL) { /* empyty list */ client_send_command_error(cmd, "Empty sort program."); - return NULL; + return -1; } - buf = buffer_create_dynamic(pool_datastack_create(), - 32 * sizeof(enum mail_sort_type)); + pos = 0; reverse = FALSE; + for (; args->type == IMAP_ARG_ATOM || args->type == IMAP_ARG_STRING; + args++) { + const char *arg = IMAP_ARG_STR(args); - while (args->type == IMAP_ARG_ATOM || args->type == IMAP_ARG_STRING) { - const char *arg = IMAP_ARG_STR(args); + if (strcasecmp(arg, "reverse") == 0) { + reverse = !reverse; + continue; + } for (i = 0; sort_names[i].type != MAIL_SORT_END; i++) { if (strcasecmp(arg, sort_names[i].name) == 0) @@ -51,31 +55,37 @@ if (sort_names[i].type == MAIL_SORT_END) { client_send_command_error(cmd, t_strconcat( "Unknown sort argument: ", arg, NULL)); - return NULL; + return -1; } - buffer_append(buf, &sort_names[i].type, - sizeof(enum mail_sort_type)); - args++; + if ((mask & sort_names[i].type) != 0) + continue; + mask |= sort_names[i].type; + + /* @UNSAFE: mask check should prevent us from ever + overflowing */ + i_assert(pos < MAX_SORT_PROGRAM_SIZE-1); + program[pos++] = sort_names[i].type | + (reverse ? MAIL_SORT_FLAG_REVERSE : 0); + reverse = FALSE; } - type = MAIL_SORT_END; - buffer_append(buf, &type, sizeof(type)); + program[pos++] = MAIL_SORT_END; if (args->type != IMAP_ARG_EOL) { client_send_command_error(cmd, "Invalid sort list argument."); - return NULL; + return -1; } - return buffer_free_without_data(buf); + return 0; } bool cmd_sort(struct client_command_context *cmd) { struct client *client = cmd->client; struct mail_search_arg *sargs; - enum mail_sort_type *sorting; + enum mail_sort_type sorting[MAX_SORT_PROGRAM_SIZE]; struct imap_arg *args; int args_count; pool_t pool; @@ -100,8 +110,7 @@ return TRUE; } - sorting = get_sort_program(cmd, IMAP_ARG_LIST(args)->args); - if (sorting == NULL) + if (get_sort_program(cmd, IMAP_ARG_LIST(args)->args, sorting) < 0) return TRUE; args++;