Mercurial > dovecot > original-hg > dovecot-1.2
changeset 1356:026ae7f33d61 HEAD
More optimized mbox rewriting. It now tries to shrink/extend the filler in
x-keywords header.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 13 Apr 2003 21:02:14 +0300 |
parents | 96e28b964269 |
children | 5986d8920b86 |
files | src/lib-index/mbox/mbox-index.h src/lib-index/mbox/mbox-rewrite.c src/lib-storage/index/mbox/mbox-save.c |
diffstat | 3 files changed, 51 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mbox/mbox-index.h Sun Apr 13 21:01:25 2003 +0300 +++ b/src/lib-index/mbox/mbox-index.h Sun Apr 13 21:02:14 2003 +0300 @@ -4,6 +4,9 @@ #include "md5.h" #include "mail-index.h" +/* Extra space to leave in X-Keywords header when rewriting mbox */ +#define MBOX_HEADER_EXTRA_SPACE 100 + struct mbox_header_context { struct mail_index *index; enum mail_flags flags;
--- a/src/lib-index/mbox/mbox-rewrite.c Sun Apr 13 21:01:25 2003 +0300 +++ b/src/lib-index/mbox/mbox-rewrite.c Sun Apr 13 21:02:14 2003 +0300 @@ -24,13 +24,13 @@ uoff_t content_length; unsigned int seq, uid; unsigned int msg_flags; - const char **custom_flags; + const char **custom_flags; unsigned int uid_validity; unsigned int uid_last; + char *x_keywords; unsigned int ximapbase_found:1; - unsigned int xkeywords_found:1; unsigned int xuid_found:1; unsigned int status_found:1; unsigned int xstatus_found:1; @@ -120,14 +120,19 @@ } static int mbox_write_xkeywords(struct mbox_rewrite_context *ctx, - const char *x_keywords) + const char *x_keywords, uoff_t wanted_offset, + int force_filler) { unsigned int field; int i; if ((ctx->msg_flags & MAIL_CUSTOM_FLAGS_MASK) == 0 && - x_keywords == NULL) + x_keywords == NULL && !force_filler && + ctx->output->offset + sizeof("X-Keywords:")+1 >= wanted_offset) { + /* nothing to do, and not enough extra space to write the + filler. Do it only if there's space for "X-Keywords: \n" */ return TRUE; + } if (o_stream_send_str(ctx->output, "X-Keywords:") < 0) return FALSE; @@ -153,6 +158,23 @@ return FALSE; } + /* fill the rest with spaces. -1 for \n */ + if (ctx->output->offset < wanted_offset-1 || force_filler) { + char buf[1024]; + uoff_t fill_left; + + fill_left = force_filler ? MBOX_HEADER_EXTRA_SPACE : + wanted_offset-1 - ctx->output->offset; + memset(buf, ' ', sizeof(buf)); + while (fill_left > sizeof(buf)) { + if (o_stream_send(ctx->output, buf, sizeof(buf)) < 0) + return FALSE; + fill_left -= sizeof(buf); + } + if (o_stream_send(ctx->output, buf, fill_left) < 0) + return FALSE; + } + if (o_stream_send(ctx->output, "\n", 1) < 0) return FALSE; @@ -304,17 +326,17 @@ break; case 10: if (strcasecmp(hdr->name, "X-Keywords") == 0) { - if (ctx->xkeywords_found) + if (ctx->x_keywords != NULL) return TRUE; if (hdr->continues) { hdr->use_full_value = TRUE; return TRUE; } - ctx->xkeywords_found = TRUE; str = strip_custom_flags(hdr->full_value, hdr->full_value_len, ctx); - return mbox_write_xkeywords(ctx, str); + ctx->x_keywords = i_strdup(str); + return TRUE; } else if (strcasecmp(hdr->name, "X-IMAPbase") == 0) { if (ctx->seq != 1 || ctx->ximapbase_found) return TRUE; @@ -352,7 +374,7 @@ static int mbox_write_header(struct mail_index *index, struct mail_index_record *rec, unsigned int seq, struct istream *input, struct ostream *output, - uoff_t end_offset, + uoff_t end_offset, uoff_t wanted_offset, uoff_t hdr_size, uoff_t body_size) { /* We need to update fields that define message flags. Standard fields @@ -370,6 +392,7 @@ struct message_header_parser_ctx *hdr_ctx; struct message_header_line *hdr; struct message_size hdr_parsed_size; + int force_filler; if (input->v_offset >= end_offset) { /* fsck should have noticed it.. */ @@ -394,8 +417,11 @@ i_stream_set_read_limit(input, input->v_offset + hdr_size); hdr_ctx = message_parse_header_init(input, &hdr_parsed_size); - while ((hdr = message_parse_header_next(hdr_ctx)) != NULL) + while ((hdr = message_parse_header_next(hdr_ctx)) != NULL) { + t_push(); write_header(&ctx, hdr); + t_pop(); + } message_parse_header_deinit(hdr_ctx); i_stream_set_read_limit(input, 0); @@ -408,17 +434,22 @@ (void)mbox_write_ximapbase(&ctx); } + force_filler = !ctx.xuid_found; if (!ctx.status_found) (void)mbox_write_status(&ctx, NULL); if (!ctx.xstatus_found) (void)mbox_write_xstatus(&ctx, NULL); - if (!ctx.xkeywords_found) - (void)mbox_write_xkeywords(&ctx, NULL); if (!ctx.xuid_found) (void)mbox_write_xuid(&ctx); if (!ctx.content_length_found) (void)mbox_write_content_length(&ctx); + /* write the x-keywords header last so it can fill the extra space + with spaces. -1 is for ending \n. */ + (void)mbox_write_xkeywords(&ctx, ctx.x_keywords, + wanted_offset - 1, force_filler); + i_free(ctx.x_keywords); + t_pop(); /* empty line ends headers */ @@ -533,7 +564,7 @@ struct mail_index_record *rec; struct istream *input; struct ostream *output; - uoff_t offset, hdr_size, body_size, dirty_offset; + uoff_t offset, hdr_size, body_size, dirty_offset, wanted_offset; const char *path; unsigned int seq; int tmp_fd, failed, dirty_found, rewrite, no_locking; @@ -659,14 +690,15 @@ /* write header, updating flag fields */ offset += hdr_size; + wanted_offset = offset - dirty_offset; if (!mbox_write_header(index, rec, seq, input, output, - offset, hdr_size, body_size)) { + offset, wanted_offset, + hdr_size, body_size)) { failed = TRUE; break; } - if (dirty_found && - offset - dirty_offset == output->offset) { + if (dirty_found && wanted_offset == output->offset) { /* no need to write more, flush */ if (!dirty_flush(index, dirty_offset, output, tmp_fd)) {
--- a/src/lib-storage/index/mbox/mbox-save.c Sun Apr 13 21:01:25 2003 +0300 +++ b/src/lib-storage/index/mbox/mbox-save.c Sun Apr 13 21:02:14 2003 +0300 @@ -15,8 +15,6 @@ #include <sys/stat.h> #include <netdb.h> -#define HEADER_EXTRA_SPACE 100 - struct mail_save_context { struct index_mailbox *ibox; int transaction; @@ -196,7 +194,7 @@ value needs, then write that amount of spaces. */ space = strlen(get_custom_flags(ctx->flags)); space += sizeof("X-Keywords: "); - space += HEADER_EXTRA_SPACE + MAX_INT_STRLEN + 1; + space += MBOX_HEADER_EXTRA_SPACE + MAX_INT_STRLEN + 1; /* @UNSAFE */ buf = t_malloc(space);