[dovecot-cvs] dovecot/src/lib-index mail-index-sync.c, 1.13, 1.14 mail-transaction-util.c, 1.5, 1.6 mail-transaction-util.h, 1.1, 1.2 mail-transaction-log-view.c, 1.9, 1.10

cras at procontrol.fi cras at procontrol.fi
Thu May 20 16:43:50 EEST 2004


Update of /home/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv26223

Modified Files:
	mail-index-sync.c mail-transaction-util.c 
	mail-transaction-util.h mail-transaction-log-view.c 
Log Message:
last tried fixes with sequences-in-log approach. moving to uids next, wonder
why I didn't earlier.



Index: mail-index-sync.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-sync.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- a/mail-index-sync.c	10 May 2004 21:26:31 -0000	1.13
+++ b/mail-index-sync.c	20 May 2004 13:43:47 -0000	1.14
@@ -14,30 +14,32 @@
 	const struct mail_transaction_flag_update *src, *src_end;
 	const struct mail_transaction_flag_update *dest;
 	struct mail_transaction_flag_update new_update;
-	struct mail_transaction_expunge_traverse_ctx *exp_ctx;
+	struct mail_transaction_expunge_iter_ctx *exp_ctx;
 	uint32_t last;
 	size_t i, dest_count;
 
 	src = ctx->data;
 	src_end = PTR_OFFSET(src, ctx->hdr->size);
+	if (src == src_end)
+		return;
 
 	dest = buffer_get_data(ctx->updates_buf, &dest_count);
 	dest_count /= sizeof(*dest);
 
-	exp_ctx = mail_transaction_expunge_traverse_init(ctx->expunges_buf);
+	exp_ctx = mail_transaction_expunge_iter_init(ctx->expunges_buf);
+	mail_transaction_expunge_iter_seek(exp_ctx, src->seq1, src->seq2);
 
-	for (i = 0; src != src_end; src++) {
+	for (i = 0; src != src_end; ) {
 		new_update = *src;
 
-		/* find seq1 */
-		new_update.seq1 +=
-			mail_transaction_expunge_traverse_to(exp_ctx,
-							     src->seq1);
-
-		/* find seq2 */
-		new_update.seq2 +=
-			mail_transaction_expunge_traverse_to(exp_ctx,
-							     src->seq2);
+		if (!mail_transaction_expunge_iter_get(exp_ctx,
+						       &new_update.seq1,
+						       &new_update.seq2)) {
+			mail_transaction_expunge_iter_seek(exp_ctx, src->seq1,
+							   src->seq2);
+			src++;
+			continue;
+		}
 
 		/* insert it into buffer, split it in multiple parts if needed
 		   to make sure the ordering stays the same */
@@ -66,7 +68,7 @@
 		dest = buffer_get_data(ctx->updates_buf, NULL);
 		dest_count++;
 	}
-	mail_transaction_expunge_traverse_deinit(exp_ctx);
+	mail_transaction_expunge_iter_deinit(exp_ctx);
 }
 
 static void mail_index_sync_sort_transaction(struct mail_index_sync_ctx *ctx)

Index: mail-transaction-util.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-util.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- a/mail-transaction-util.c	17 May 2004 16:31:25 -0000	1.5
+++ b/mail-transaction-util.c	20 May 2004 13:43:47 -0000	1.6
@@ -6,11 +6,11 @@
 #include "mail-transaction-log.h"
 #include "mail-transaction-util.h"
 
-struct mail_transaction_expunge_traverse_ctx {
+struct mail_transaction_expunge_iter_ctx {
 	const struct mail_transaction_expunge *expunges;
-	size_t expunges_count, cur_idx, old_idx;
-	uint32_t cur_seq, expunges_before;
-	uint32_t old_seq, old_expunges_before;
+	size_t expunges_count;
+	uint32_t cur_seq, cur_idx, expunges_before;
+	uint32_t iter_seq, iter_count, iter_idx;
 };
 
 const struct mail_transaction_type_map mail_transaction_type_map[] = {
@@ -149,7 +149,7 @@
 			if (src->seq1 + expunges_before < dest[i].seq1)
 				break;
 
-			i_assert(src->uid2 > dest[i].uid1);
+			i_assert(src->uid2 == 0 || src->uid2 > dest[i].uid1);
 			expunges_before += dest[i].seq2 - dest[i].seq1 + 1;
 		}
 
@@ -169,7 +169,8 @@
 			new_exp.seq2 += count;
 			if (new_exp.seq2 == dest[i].seq2)
 				new_exp.uid2 = dest[i].uid2;
-			i_assert(new_exp.uid2 >= dest[i].uid2);
+			i_assert(new_exp.uid2 == 0 ||
+				 new_exp.uid2 >= dest[i].uid2);
 			i++;
 		}
 
@@ -201,14 +202,13 @@
 	}
 }
 
-struct mail_transaction_expunge_traverse_ctx *
-mail_transaction_expunge_traverse_init(const buffer_t *expunges_buf)
+struct mail_transaction_expunge_iter_ctx *
+mail_transaction_expunge_iter_init(const buffer_t *expunges_buf)
 {
-	struct mail_transaction_expunge_traverse_ctx *ctx;
+	struct mail_transaction_expunge_iter_ctx *ctx;
 
-	ctx = i_new(struct mail_transaction_expunge_traverse_ctx, 1);
+	ctx = i_new(struct mail_transaction_expunge_iter_ctx, 1);
 	ctx->cur_seq = 1;
-	ctx->old_seq = 1;
 
 	if (expunges_buf != NULL) {
 		ctx->expunges =
@@ -218,34 +218,25 @@
 	return ctx;
 }
 
-void mail_transaction_expunge_traverse_deinit(
-	struct mail_transaction_expunge_traverse_ctx *ctx)
+void mail_transaction_expunge_iter_deinit(
+	struct mail_transaction_expunge_iter_ctx *ctx)
 {
 	i_free(ctx);
 }
 
-uint32_t mail_transaction_expunge_traverse_to(
-	struct mail_transaction_expunge_traverse_ctx *ctx, uint32_t seq)
+int mail_transaction_expunge_iter_seek(
+	struct mail_transaction_expunge_iter_ctx *ctx,
+	uint32_t seq1, uint32_t seq2)
 {
 	uint32_t idx, count, last_seq;
 
-	if (seq < ctx->cur_seq) {
-		/* allow seeking one back */
-		ctx->cur_idx = ctx->old_idx;
-		ctx->cur_seq = ctx->old_seq;
-		ctx->expunges_before = ctx->old_expunges_before;
-	} else {
-		ctx->old_idx = ctx->cur_idx;
-		ctx->old_seq = ctx->cur_seq;
-		ctx->old_expunges_before = ctx->expunges_before;
-	}
-	i_assert(seq >= ctx->cur_seq);
+	i_assert(seq1 >= ctx->cur_seq);
 
 	idx = ctx->cur_idx;
 	last_seq = idx == 0 ? 1 : ctx->expunges[idx-1].seq2 + 1;
 	for (; idx < ctx->expunges_count; idx++) {
 		count = ctx->expunges[idx].seq1 - last_seq;
-		if (ctx->cur_seq + count > seq)
+		if (ctx->cur_seq + count > seq1)
 			break;
 		ctx->cur_seq += count;
 
@@ -254,6 +245,42 @@
 		last_seq = ctx->expunges[idx].seq2+1;
 	}
 
+	ctx->iter_idx = idx;
+	ctx->iter_seq = seq1 + ctx->expunges_before;
+	ctx->iter_count = seq2 - seq1 + 1;
+
 	ctx->cur_idx = idx;
-	return ctx->expunges_before;
+	return ctx->expunges_before != 0 ||
+		(idx != ctx->expunges_count && ctx->expunges[idx].seq1 <= seq2);
+}
+
+int mail_transaction_expunge_iter_get(
+	struct mail_transaction_expunge_iter_ctx *ctx,
+	uint32_t *seq1_r, uint32_t *seq2_r)
+{
+	if (ctx->iter_count == 0)
+		return 0;
+
+	*seq1_r = ctx->iter_seq;
+
+	if (ctx->iter_idx == ctx->expunges_count ||
+	    ctx->expunges[ctx->iter_idx].seq1 >=
+	    ctx->iter_seq + ctx->iter_count) {
+		/* last one */
+		*seq2_r = ctx->iter_seq + ctx->iter_count - 1;
+		ctx->iter_count = 0;
+		return 1;
+	}
+
+	ctx->iter_count -= ctx->expunges[ctx->iter_idx].seq1 - ctx->iter_seq;
+	i_assert(ctx->iter_count > 0);
+
+	/* have to split this one */
+	*seq2_r = ctx->expunges[ctx->iter_idx].seq1-1;
+	do {
+		ctx->iter_seq = ctx->expunges[ctx->iter_idx].seq2+1;
+		ctx->iter_idx++;
+	} while (ctx->iter_idx != ctx->expunges_count &&
+		 ctx->expunges[ctx->iter_idx].seq1 == ctx->iter_seq);
+	return 1;
 }

Index: mail-transaction-util.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-util.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- a/mail-transaction-util.h	27 Apr 2004 20:25:53 -0000	1.1
+++ b/mail-transaction-util.h	20 May 2004 13:43:47 -0000	1.2
@@ -30,13 +30,24 @@
 void
 mail_transaction_log_sort_expunges(buffer_t *expunges_buf,
 				   const struct mail_transaction_expunge *src,
-				   size_t src_buf_size);;
+				   size_t src_buf_size);
 
-struct mail_transaction_expunge_traverse_ctx *
-mail_transaction_expunge_traverse_init(const buffer_t *expunges_buf);
-void mail_transaction_expunge_traverse_deinit(
-	struct mail_transaction_expunge_traverse_ctx *ctx);
-uint32_t mail_transaction_expunge_traverse_to(
-	struct mail_transaction_expunge_traverse_ctx *ctx, uint32_t seq);
+/* Iterate through expunges buffer. iter_seek()'s seq1/seq2 is assumed to be
+   in post-expunge view, iter_get() updates them to pre-expunge view. Some
+   post-expunge sequence arrays may go through expunges, we split them so it
+   won't be visible. */
+struct mail_transaction_expunge_iter_ctx *
+mail_transaction_expunge_iter_init(const buffer_t *expunges_buf);
+void mail_transaction_expunge_iter_deinit(
+	struct mail_transaction_expunge_iter_ctx *ctx);
+/* Returns TRUE if seq1 or seq2 will be modified by iter_get(). If FALSE is
+   returned calling iter_get() is a bit pointless. */
+int mail_transaction_expunge_iter_seek(
+	struct mail_transaction_expunge_iter_ctx *ctx,
+	uint32_t seq1, uint32_t seq2);
+/* Returns TRUE while sequences are returned. */
+int mail_transaction_expunge_iter_get(
+	struct mail_transaction_expunge_iter_ctx *ctx,
+	uint32_t *seq1_r, uint32_t *seq2_r);
 
 #endif

Index: mail-transaction-log-view.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-log-view.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- a/mail-transaction-log-view.c	2 May 2004 12:57:29 -0000	1.9
+++ b/mail-transaction-log-view.c	20 May 2004 13:43:47 -0000	1.10
@@ -15,7 +15,7 @@
 
 	enum mail_transaction_type type_mask;
 	buffer_t *expunges_buf, *data_buf;
-        struct mail_transaction_expunge_traverse_ctx *exp_ctx;
+        struct mail_transaction_expunge_iter_ctx *exp_ctx;
 	struct mail_transaction_header tmp_hdr;
 
         struct mail_transaction_log_file *file;
@@ -319,23 +319,21 @@
 {
 	struct mail_transaction_log_view *view = context;
 	struct mail_transaction_expunge new_e;
-	uint32_t expunges_before;
 
-	expunges_before = mail_transaction_expunge_traverse_to(view->exp_ctx,
-							       e->seq2);
-	if (expunges_before == 0) {
-		buffer_append(view->data_buf, e, sizeof(*e));
-		return 1;
+	if (!mail_transaction_expunge_iter_seek(view->exp_ctx,
+						e->seq1, e->seq2)) {
+		new_e = *e;
+		/*FIXME:buffer_append(view->data_buf, e, sizeof(*e));
+		return 1;*/
 	}
 
-	/* FIXME: if there's expunges in the middle of the
-	   range, we'd have to split this to multiple records */
+	new_e.uid1 = new_e.uid2 = 0; // FIXME: this breaks anyway
 
-	new_e = *e;
-	new_e.seq2 += expunges_before;
-	new_e.seq1 += mail_transaction_expunge_traverse_to(view->exp_ctx,
-							   new_e.seq1);
-	buffer_append(view->data_buf, &new_e, sizeof(new_e));
+	while (mail_transaction_expunge_iter_get(view->exp_ctx,
+						 &new_e.seq1, &new_e.seq2)) {
+		i_assert(new_e.seq1 != 0);
+		buffer_append(view->data_buf, &new_e, sizeof(new_e));
+	}
 	return 1;
 }
 
@@ -344,23 +342,17 @@
 {
 	struct mail_transaction_log_view *view = context;
 	struct mail_transaction_flag_update new_u;
-	uint32_t expunges_before;
 
-	expunges_before = mail_transaction_expunge_traverse_to(view->exp_ctx,
-							       u->seq2);
-	if (expunges_before == 0) {
+	if (!mail_transaction_expunge_iter_seek(view->exp_ctx,
+						u->seq1, u->seq2)) {
 		buffer_append(view->data_buf, u, sizeof(*u));
 		return 1;
 	}
 
-	/* FIXME: if there's expunges in the middle of the
-	   range, we'd have to split this to multiple records */
-
 	new_u = *u;
-	new_u.seq2 += expunges_before;
-	new_u.seq1 += mail_transaction_expunge_traverse_to(view->exp_ctx,
-							   new_u.seq1);
-	buffer_append(view->data_buf, &new_u, sizeof(new_u));
+	while (mail_transaction_expunge_iter_get(view->exp_ctx,
+						 &new_u.seq1, &new_u.seq2))
+		buffer_append(view->data_buf, &new_u, sizeof(new_u));
 	return 1;
 }
 
@@ -369,17 +361,17 @@
 {
 	struct mail_transaction_log_view *view = context;
 	struct mail_transaction_cache_update new_u;
-	uint32_t expunges_before;
 
-	expunges_before = mail_transaction_expunge_traverse_to(view->exp_ctx,
-							       u->seq);
-	if (expunges_before != 0) {
-		new_u = *u;
-		new_u.seq += expunges_before;
-		u = &new_u;
+	if (!mail_transaction_expunge_iter_seek(view->exp_ctx,
+						u->seq, u->seq)) {
+		buffer_append(view->data_buf, u, sizeof(*u));
+		return 1;
 	}
 
-	buffer_append(view->data_buf, u, sizeof(*u));
+	new_u = *u;
+	if (mail_transaction_expunge_iter_get(view->exp_ctx,
+					      &new_u.seq, &new_u.seq))
+		buffer_append(view->data_buf, &new_u, sizeof(new_u));
 	return 1;
 }
 
@@ -432,15 +424,18 @@
 			buffer_set_used_size(view->data_buf, 0);
 		}
 
-		view->exp_ctx = mail_transaction_expunge_traverse_init(
-					view->expunges_buf);
+		view->exp_ctx =
+			mail_transaction_expunge_iter_init(view->expunges_buf);
 		ret = mail_transaction_map(hdr, data, &seqfix_funcs, view);
-		mail_transaction_expunge_traverse_deinit(view->exp_ctx);
+		mail_transaction_expunge_iter_deinit(view->exp_ctx);
 
 		if (ret > 0) {
-			/* modified */
-			i_assert(buffer_get_used_size(view->data_buf) ==
-				 hdr->size);
+			/* modified - size may have changed, so update header */
+			view->tmp_hdr = *hdr;
+			view->tmp_hdr.size =
+				buffer_get_used_size(view->data_buf);
+			*hdr_r = &view->tmp_hdr;
+
 			*data_r = buffer_get_data(view->data_buf, NULL);
 		} else {
 			i_assert(buffer_get_used_size(view->data_buf) == 0);
@@ -452,9 +447,11 @@
 						   data, hdr->size);
 
 		/* hide expunge protection */
-		view->tmp_hdr = *hdr;
+		if (*hdr_r != &view->tmp_hdr) {
+			view->tmp_hdr = *hdr;
+			*hdr_r = &view->tmp_hdr;
+		}
 		view->tmp_hdr.type &= ~MAIL_TRANSACTION_EXPUNGE_PROT;
-		*hdr_r = &view->tmp_hdr;
 	}
 
 	return 1;



More information about the dovecot-cvs mailing list