[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