[dovecot-cvs] dovecot/src/lib-index/mbox mbox-index.h,1.26,1.27 mbox-rewrite.c,1.54,1.55
cras at procontrol.fi
cras at procontrol.fi
Sun Apr 13 22:02:16 EEST 2003
Update of /home/cvs/dovecot/src/lib-index/mbox
In directory danu:/tmp/cvs-serv30572/lib-index/mbox
Modified Files:
mbox-index.h mbox-rewrite.c
Log Message:
More optimized mbox rewriting. It now tries to shrink/extend the filler in
x-keywords header.
Index: mbox-index.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mbox/mbox-index.h,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- mbox-index.h 26 Mar 2003 17:29:02 -0000 1.26
+++ mbox-index.h 13 Apr 2003 18:02:14 -0000 1.27
@@ -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;
Index: mbox-rewrite.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mbox/mbox-rewrite.c,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -d -r1.54 -r1.55
--- mbox-rewrite.c 26 Mar 2003 17:29:02 -0000 1.54
+++ mbox-rewrite.c 13 Apr 2003 18:02:14 -0000 1.55
@@ -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)) {
More information about the dovecot-cvs
mailing list