[dovecot-cvs] dovecot/src/lib-index mail-index-sync-private.h, 1.4, 1.5 mail-index-sync-update.c, 1.13, 1.14 mail-index-sync.c, 1.14, 1.15 mail-index-transaction.c, 1.4, 1.5 mail-index-view-sync.c, 1.7, 1.8 mail-index.h, 1.107, 1.108 mail-transaction-log-view.c, 1.10, 1.11 mail-transaction-log.c, 1.27, 1.28 mail-transaction-log.h, 1.8, 1.9 mail-transaction-util.c, 1.6, 1.7 mail-transaction-util.h, 1.2, 1.3

cras at procontrol.fi cras at procontrol.fi
Sat May 22 03:48:47 EEST 2004


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

Modified Files:
	mail-index-sync-private.h mail-index-sync-update.c 
	mail-index-sync.c mail-index-transaction.c 
	mail-index-view-sync.c mail-index.h 
	mail-transaction-log-view.c mail-transaction-log.c 
	mail-transaction-log.h mail-transaction-util.c 
	mail-transaction-util.h 
Log Message:
Transaction log contains only UIDs now, no more sequences which just mess up
everything.



Index: mail-index-sync-private.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-sync-private.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- a/mail-index-sync-private.h	9 May 2004 23:06:27 -0000	1.4
+++ b/mail-index-sync-private.h	22 May 2004 00:48:45 -0000	1.5
@@ -15,7 +15,7 @@
 	const void *data;
 
 	size_t expunge_idx, update_idx;
-	uint32_t next_seq;
+	uint32_t next_uid;
 
 	unsigned int lock_id, dirty_lock_id;
 

Index: mail-index-sync-update.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-sync-update.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- a/mail-index-sync-update.c	3 May 2004 19:53:07 -0000	1.13
+++ b/mail-index-sync-update.c	22 May 2004 00:48:45 -0000	1.14
@@ -10,6 +10,7 @@
 
 struct mail_index_update_ctx {
 	struct mail_index *index;
+	struct mail_index_view *view;
 	struct mail_index_header hdr;
 	struct mail_transaction_log_view *log_view;
 };
@@ -64,7 +65,15 @@
 	struct mail_index_record *rec, *end;
 	uint8_t flag_mask, old_flags;
 	keywords_mask_t keyword_mask;
-	int i, update_keywords;
+	uint32_t seq1, seq2;
+	int i, update_keywords, ret;
+
+	ret = mail_index_lookup_uid_range(ctx->view, syncrec->uid1,
+					  syncrec->uid2, &seq1, &seq2);
+	i_assert(ret == 0);
+
+	if (seq1 == 0)
+		return;
 
 	update_keywords = FALSE;
 	for (i = 0; i < INDEX_KEYWORDS_BYTE_COUNT; i++) {
@@ -76,8 +85,8 @@
 	}
 
 	flag_mask = ~syncrec->remove_flags;
-	rec = &ctx->index->map->records[syncrec->seq1-1];
-	end = rec + (syncrec->seq2 - syncrec->seq1) + 1;
+	rec = &ctx->index->map->records[seq1-1];
+	end = rec + (seq2 - seq1) + 1;
 	for (; rec != end; rec++) {
 		old_flags = rec->flags;
 		rec->flags = (rec->flags & flag_mask) | syncrec->add_flags;
@@ -177,6 +186,7 @@
 	const struct mail_index_record *appends;
 	unsigned int append_count;
 	uint32_t count, file_seq, src_idx, dest_idx, dirty_flag;
+	uint32_t seq1, seq2;
 	uoff_t file_offset;
 	unsigned int lock_id;
 	int ret, changed;
@@ -190,6 +200,7 @@
 
 	memset(&ctx, 0, sizeof(ctx));
 	ctx.index = index;
+	ctx.view = sync_ctx->view;
 	ctx.hdr = *index->hdr;
 	ctx.log_view = sync_ctx->view->log_view;
 
@@ -227,10 +238,18 @@
 		switch (rec.type) {
 		case MAIL_INDEX_SYNC_TYPE_APPEND:
 			i_assert(appends == NULL);
-			append_count = rec.seq2 - rec.seq1 + 1;
 			appends = rec.appends;
+			append_count = rec.appends_count;
 			break;
 		case MAIL_INDEX_SYNC_TYPE_EXPUNGE:
+			ret = mail_index_lookup_uid_range(sync_ctx->view,
+							  rec.uid1, rec.uid2,
+							  &seq1, &seq2);
+			i_assert(ret == 0);
+
+			if (seq1 == 0)
+				break;
+
 			if (src_idx == 0) {
 				/* expunges have to be atomic. so we'll have
 				   to copy the mapping, do the changes there
@@ -244,18 +263,17 @@
 				index->hdr = map->hdr;
 				map->write_to_disk = TRUE;
 
-				dest_idx = rec.seq1-1;
+				dest_idx = seq1-1;
 			} else {
-				count = (rec.seq1-1) - src_idx;
+				count = (seq1-1) - src_idx;
 				memmove(map->records + dest_idx,
 					map->records + src_idx,
 					count * sizeof(*map->records));
 				dest_idx += count;
 			}
 
-			mail_index_sync_update_expunges(&ctx, rec.seq1,
-							rec.seq2);
-			src_idx = rec.seq2;
+			mail_index_sync_update_expunges(&ctx, seq1, seq2);
+			src_idx = seq2;
 			break;
 		case MAIL_INDEX_SYNC_TYPE_FLAGS:
 			mail_index_sync_update_flags(&ctx, &rec);

Index: mail-index-sync.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-sync.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- a/mail-index-sync.c	20 May 2004 13:43:47 -0000	1.14
+++ b/mail-index-sync.c	22 May 2004 00:48:45 -0000	1.15
@@ -14,7 +14,6 @@
 	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_iter_ctx *exp_ctx;
 	uint32_t last;
 	size_t i, dest_count;
 
@@ -26,41 +25,29 @@
 	dest = buffer_get_data(ctx->updates_buf, &dest_count);
 	dest_count /= sizeof(*dest);
 
-	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; ) {
 		new_update = *src;
 
-		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 */
 		for (; i < dest_count; i++) {
-			if (dest[i].seq1 <= new_update.seq1)
+			if (dest[i].uid1 <= new_update.uid1)
 				continue;
 
-			if (dest[i].seq1 > new_update.seq2)
+			if (dest[i].uid1 > new_update.uid2)
 				break;
 
 			/* partial */
-			last = new_update.seq2;
-			new_update.seq2 = dest[i].seq1-1;
+			last = new_update.uid2;
+			new_update.uid2 = dest[i].uid1-1;
 
 			buffer_insert(ctx->updates_buf, i * sizeof(new_update),
 				      &new_update, sizeof(new_update));
 			dest = buffer_get_data(ctx->updates_buf, NULL);
 			dest_count++;
 
-			new_update.seq1 = new_update.seq2+1;
-			new_update.seq2 = last;
+			new_update.uid1 = new_update.uid2+1;
+			new_update.uid2 = last;
 		}
 
 		buffer_insert(ctx->updates_buf, i * sizeof(new_update),
@@ -68,7 +55,6 @@
 		dest = buffer_get_data(ctx->updates_buf, NULL);
 		dest_count++;
 	}
-	mail_transaction_expunge_iter_deinit(exp_ctx);
 }
 
 static void mail_index_sync_sort_transaction(struct mail_index_sync_ctx *ctx)
@@ -205,8 +191,8 @@
 			    const struct mail_transaction_expunge *exp)
 {
 	rec->type = MAIL_INDEX_SYNC_TYPE_EXPUNGE;
-	rec->seq1 = exp->seq1;
-	rec->seq2 = exp->seq2;
+	rec->uid1 = exp->uid1;
+	rec->uid2 = exp->uid2;
 }
 
 void
@@ -214,8 +200,8 @@
 			   const struct mail_transaction_flag_update *update)
 {
 	rec->type = MAIL_INDEX_SYNC_TYPE_FLAGS;
-	rec->seq1 = update->seq1;
-	rec->seq2 = update->seq2;
+	rec->uid1 = update->uid1;
+	rec->uid2 = update->uid2;
 
 	rec->add_flags = update->add_flags;
 	memcpy(rec->add_keywords, update->add_keywords,
@@ -228,23 +214,13 @@
 static int mail_index_sync_rec_check(struct mail_index_view *view,
 				     struct mail_index_sync_rec *rec)
 {
-	uint32_t message_count;
-
 	switch (rec->type) {
 	case MAIL_INDEX_SYNC_TYPE_EXPUNGE:
 	case MAIL_INDEX_SYNC_TYPE_FLAGS:
-		if (rec->seq1 > rec->seq2 || rec->seq1 == 0) {
-			mail_transaction_log_view_set_corrupted(view->log_view,
-				"Broken sequence: %u..%u (type 0x%x)",
-				rec->seq1, rec->seq2, rec->type);
-			return FALSE;
-		}
-
-		message_count = mail_index_view_get_message_count(view);
-		if (rec->seq2 > message_count) {
+		if (rec->uid1 > rec->uid2 || rec->uid1 == 0) {
 			mail_transaction_log_view_set_corrupted(view->log_view,
-				"Sequence out of range: %u > %u (type 0x%x)",
-				rec->seq2, message_count, rec->type);
+				"Broken UID range: %u..%u (type 0x%x)",
+				rec->uid1, rec->uid2, rec->type);
 			return FALSE;
 		}
 		break;
@@ -281,19 +257,19 @@
 	   update A: 7, 7
 	*/
 	while (next_update != NULL &&
-	       (next_exp == NULL || next_update->seq1 < next_exp->seq1)) {
-		if (next_update->seq2 >= ctx->next_seq) {
+	       (next_exp == NULL || next_update->uid1 < next_exp->uid1)) {
+		if (next_update->uid2 >= ctx->next_uid) {
 			mail_index_sync_get_update(sync_rec, next_update);
 			if (next_exp != NULL &&
-			    next_exp->seq1 <= next_update->seq2) {
+			    next_exp->uid1 <= next_update->uid2) {
 				/* it's overlapping.. */
-				sync_rec->seq2 = next_exp->seq1-1;
+				sync_rec->uid2 = next_exp->uid1-1;
 			}
 
-			if (sync_rec->seq1 < ctx->next_seq)
-				sync_rec->seq1 = ctx->next_seq;
+			if (sync_rec->uid1 < ctx->next_uid)
+				sync_rec->uid1 = ctx->next_uid;
 
-			i_assert(sync_rec->seq1 <= sync_rec->seq2);
+			i_assert(sync_rec->uid1 <= sync_rec->uid2);
 			ctx->update_idx++;
 			return mail_index_sync_rec_check(ctx->view, sync_rec);
 		}
@@ -304,44 +280,25 @@
 	}
 
 	if (next_exp != NULL) {
-		/* a few sanity checks here, we really don't ever want to
-		   accidentally expunge a message. If sequence and UID matches,
-		   it's quite unlikely this expunge was caused by some bug. */
-		uint32_t uid1, uid2;
-
 		mail_index_sync_get_expunge(sync_rec, next_exp);
 		if (mail_index_sync_rec_check(ctx->view, sync_rec) < 0)
 			return -1;
 
-		if (mail_index_lookup_uid(ctx->view, next_exp->seq1, &uid1) < 0)
-			return -1;
-		if (mail_index_lookup_uid(ctx->view, next_exp->seq2, &uid2) < 0)
-			return -1;
-		if (next_exp->uid1 != uid1 || next_exp->uid2 != uid2) {
-			mail_transaction_log_view_set_corrupted(
-				ctx->view->log_view, "Expunge range %u..%u: "
-				"UIDs %u..%u doesn't match real UIDs %u..%u",
-				next_exp->seq1, next_exp->seq2,
-				next_exp->uid1, next_exp->uid2, uid1, uid2);
-			return -1;
-		}
-
 		ctx->expunge_idx++;
 
 		/* scan updates again from the beginning */
 		ctx->update_idx = 0;
-		ctx->next_seq = next_exp->seq2;          
+		ctx->next_uid = next_exp->uid2+1;
 		return 1;
 	}
 
 	if (ctx->sync_appends) {
 		ctx->sync_appends = FALSE;
 		sync_rec->type = MAIL_INDEX_SYNC_TYPE_APPEND;
-		sync_rec->seq1 = ctx->index->map->records_count+1;
-		sync_rec->seq2 = sync_rec->seq1-1 +
-			buffer_get_used_size(ctx->appends_buf) /
-			sizeof(struct mail_index_record);
-		sync_rec->appends = buffer_get_data(ctx->appends_buf, NULL);
+		sync_rec->appends = buffer_get_data(ctx->appends_buf,
+						    &sync_rec->appends_count);
+		sync_rec->appends_count /= sizeof(*sync_rec->appends);
+		sync_rec->uid1 = sync_rec->uid2 = 0;
 		return 1;
 	}
 
@@ -363,6 +320,8 @@
 			return -1;
 	}
 
+	/* FIXME: maybe this should go through transaction log anyway?
+	   doesn't work well with non-mmaped indexes.. */
 	i_assert(seq <= ctx->view->map->records_count);
 	ctx->view->map->records[seq-1].flags |= MAIL_INDEX_MAIL_FLAG_DIRTY;
 	ctx->have_dirty = TRUE;

Index: mail-index-transaction.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-transaction.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- a/mail-index-transaction.c	16 May 2004 23:12:49 -0000	1.4
+++ b/mail-index-transaction.c	22 May 2004 00:48:45 -0000	1.5
@@ -1,5 +1,9 @@
 /* Copyright (C) 2003-2004 Timo Sirainen */
 
+/* Inside transaction we keep messages stored in sequences in uid fields.
+   Before they're written to transaction log the sequences are changed to
+   UIDs. This is because we're able to compress sequence ranges better. */
+
 #include "lib.h"
 #include "buffer.h"
 #include "mail-index-view-private.h"
@@ -34,6 +38,43 @@
 	i_free(t);
 }
 
+static void
+mail_index_buffer_convert_to_uids(struct mail_index_view *view,
+				  buffer_t *buf, size_t record_size, int range)
+{
+	unsigned char *data;
+	size_t size, i;
+	uint32_t *seq;
+
+	if (buf == NULL)
+		return;
+
+	/* @UNSAFE */
+	data = buffer_get_modifyable_data(buf, &size);
+	for (i = 0; i < size; i += record_size) {
+		seq = (uint32_t *)&data[i];
+
+		seq[0] = view->map->records[seq[0]-1].uid;
+		if (range)
+			seq[1] = view->map->records[seq[1]-1].uid;
+	}
+}
+
+static int
+mail_index_transaction_convert_to_uids(struct mail_index_transaction *t)
+{
+	if (mail_index_view_lock(t->view) < 0)
+		return -1;
+
+	mail_index_buffer_convert_to_uids(t->view, t->expunges,
+		sizeof(struct mail_transaction_expunge), TRUE);
+	mail_index_buffer_convert_to_uids(t->view, t->updates,
+		sizeof(struct mail_transaction_flag_update), TRUE);
+	mail_index_buffer_convert_to_uids(t->view, t->cache_updates,
+		sizeof(struct mail_transaction_cache_update), TRUE);
+	return 0;
+}
+
 int mail_index_transaction_commit(struct mail_index_transaction *t,
 				  uint32_t *log_file_seq_r,
 				  uoff_t *log_file_offset_r)
@@ -45,10 +86,15 @@
 		return -1;
 	}
 
-	if (t->last_update.seq1 != 0)
+	if (t->last_update.uid1 != 0)
 		mail_index_transaction_add_last(t);
 
-	ret = mail_transaction_log_append(t, log_file_seq_r, log_file_offset_r);
+	if (mail_index_transaction_convert_to_uids(t) < 0)
+		ret = -1;
+	else {
+		ret = mail_transaction_log_append(t, log_file_seq_r,
+						  log_file_offset_r);
+	}
 
 	mail_index_transaction_free(t);
 	return ret;
@@ -87,14 +133,11 @@
 {
         struct mail_transaction_expunge exp, *data;
 	unsigned int idx, left_idx, right_idx;
-	uint32_t uid;
 	size_t size;
 
 	i_assert(seq > 0 && seq <= mail_index_view_get_message_count(t->view));
 
-	uid = t->view->map->records[seq-1].uid;
-	exp.seq1 = exp.seq2 = seq;
-	exp.uid1 = exp.uid2 = uid;
+	exp.uid1 = exp.uid2 = seq;
 
 	/* expunges is a sorted array of {seq1, seq2, ..}, .. */
 
@@ -110,23 +153,21 @@
 	i_assert(size > 0);
 
 	/* quick checks */
-	if (data[size-1].seq2 == seq-1) {
+	if (data[size-1].uid2 == seq-1) {
 		/* grow last range */
-		data[size-1].seq2 = seq;
-		data[size-1].uid2 = uid;
+		data[size-1].uid2 = seq;
 		return;
 	}
-	if (data[size-1].seq2 < seq) {
+	if (data[size-1].uid2 < seq) {
 		buffer_append(t->expunges, &exp, sizeof(exp));
 		return;
 	}
-	if (data[0].seq1 == seq+1) {
+	if (data[0].uid1 == seq+1) {
 		/* grow down first range */
-		data[0].seq1 = seq;
-		data[0].uid1 = uid;
+		data[0].uid1 = seq;
 		return;
 	}
-	if (data[0].seq1 > seq) {
+	if (data[0].uid1 > seq) {
 		buffer_insert(t->expunges, 0, &exp, sizeof(exp));
 		return;
 	}
@@ -137,42 +178,38 @@
 	while (left_idx < right_idx) {
 		idx = (left_idx + right_idx) / 2;
 
-		if (data[idx].seq1 < seq)
+		if (data[idx].uid1 < seq)
 			left_idx = idx+1;
-		else if (data[idx].seq1 > seq)
+		else if (data[idx].uid1 > seq)
 			right_idx = idx;
 		else
 			break;
 	}
 
-	if (data[idx].seq2 < seq)
+	if (data[idx].uid2 < seq)
 		idx++;
 
         /* idx == size couldn't happen because we already handle it above */
-	i_assert(idx < size && data[idx].seq1 >= seq);
+	i_assert(idx < size && data[idx].uid1 >= seq);
 
-	if (data[idx].seq1 <= seq && data[idx].seq2 >= seq) {
+	if (data[idx].uid1 <= seq && data[idx].uid2 >= seq) {
 		/* already expunged */
 		return;
 	}
 
-	if (data[idx].seq1 == seq+1) {
-		data[idx].seq1 = seq;
-		data[idx].uid1 = uid;
-		if (idx > 0 && data[idx-1].seq2 == seq-1) {
+	if (data[idx].uid1 == seq+1) {
+		data[idx].uid1 = seq;
+		if (idx > 0 && data[idx-1].uid2 == seq-1) {
 			/* merge */
-			data[idx-1].seq2 = data[idx].seq2;
 			data[idx-1].uid2 = data[idx].uid2;
 			buffer_delete(t->expunges, idx * sizeof(*data),
 				      sizeof(*data));
 		}
-	} else if (data[idx].seq2 == seq-1) {
+	} else if (data[idx].uid2 == seq-1) {
 		i_assert(idx+1 < size); /* already handled above */
-		data[idx].seq2 = seq;
-		data[idx].uid2 = uid;
-		if (data[idx+1].seq1 == seq+1) {
+		data[idx].uid2 = seq;
+		if (data[idx+1].uid1 == seq+1) {
 			/* merge */
-			data[idx+1].seq1 = data[idx].seq1;
 			data[idx+1].uid1 = data[idx].uid1;
 			buffer_delete(t->expunges, idx * sizeof(*data),
 				      sizeof(*data));
@@ -237,25 +274,25 @@
 	/* first get group updates into same structure. this allows faster
 	   updates if same mails have multiple flag updates during same
 	   transaction (eg. 1:10 +seen, 1:10 +deleted) */
-	if (t->last_update.seq2 == seq-1) {
-		if (t->last_update.seq1 != 0 &&
+	if (t->last_update.uid2 == seq-1) {
+		if (t->last_update.uid1 != 0 &&
 		    IS_COMPATIBLE_UPDATE(t, modify_type, flags, keywords)) {
-			t->last_update.seq2 = seq;
+			t->last_update.uid2 = seq;
 			return;
 		}
-	} else if (t->last_update.seq1 == seq+1) {
-		if (t->last_update.seq1 != 0 &&
+	} else if (t->last_update.uid1 == seq+1) {
+		if (t->last_update.uid1 != 0 &&
 		    IS_COMPATIBLE_UPDATE(t, modify_type, flags, keywords)) {
-			t->last_update.seq1 = seq;
+			t->last_update.uid1 = seq;
 			return;
 		}
 	}
 
-	if (t->last_update.seq1 != 0)
+	if (t->last_update.uid1 != 0)
 		mail_index_transaction_add_last(t);
 
 	t->last_update_modify_type = modify_type;
-	t->last_update.seq1 = t->last_update.seq2 = seq;
+	t->last_update.uid1 = t->last_update.uid2 = seq;
 	t->last_update.add_flags = flags;
 	memcpy(t->last_update.add_keywords, keywords,
 	       INDEX_KEYWORDS_BYTE_COUNT);
@@ -312,35 +349,35 @@
 	while (left_idx < right_idx) {
 		idx = (left_idx + right_idx) / 2;
 
-		if (data[idx].seq1 < update.seq1)
+		if (data[idx].uid1 < update.uid1)
 			left_idx = idx+1;
-		else if (data[idx].seq1 > update.seq1)
+		else if (data[idx].uid1 > update.uid1)
 			right_idx = idx;
 		else
 			break;
 	}
-	if (idx < size && data[idx].seq2 < update.seq1)
+	if (idx < size && data[idx].uid2 < update.uid1)
 		idx++;
 
-	i_assert(idx == size || data[idx].seq1 < update.seq1);
+	i_assert(idx == size || data[idx].uid1 < update.uid1);
 
 	/* insert it into buffer, split it in multiple parts if needed
 	   to make sure the ordering stays the same */
 	for (; idx < size; idx++) {
-		if (data[idx].seq1 > update.seq2)
+		if (data[idx].uid1 > update.uid2)
 			break;
 
 		/* partial */
-		last = update.seq2;
-		update.seq2 = data[idx].seq1-1;
+		last = update.uid2;
+		update.uid2 = data[idx].uid1-1;
 
 		buffer_insert(t->updates, idx * sizeof(update),
 			      &update, sizeof(update));
 		data = buffer_get_modifyable_data(t->updates, NULL);
 		size++;
 
-		update.seq1 = update.seq2+1;
-		update.seq2 = last;
+		update.uid1 = update.uid2+1;
+		update.uid2 = last;
 	}
 
 	buffer_insert(t->updates, idx * sizeof(update),
@@ -363,16 +400,16 @@
 	size /= sizeof(*data);
 
 	/* we're probably appending it, check */
-	if (size == 0 || data[size-1].seq < seq)
+	if (size == 0 || data[size-1].uid < seq)
 		idx = size;
 	else {
 		idx = 0; left_idx = 0; right_idx = size;
 		while (left_idx < right_idx) {
 			idx = (left_idx + right_idx) / 2;
 
-			if (data[idx].seq < seq)
+			if (data[idx].uid < seq)
 				left_idx = idx+1;
-			else if (data[idx].seq > seq)
+			else if (data[idx].uid > seq)
 				right_idx = idx;
 			else {
 				/* already there, update */
@@ -382,7 +419,7 @@
 		}
 	}
 
-	update.seq = seq;
+	update.uid = seq;
 	update.cache_offset = offset;
 	buffer_insert(t->updates, idx * sizeof(update),
 		      &update, sizeof(update));

Index: mail-index-view-sync.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-view-sync.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- a/mail-index-view-sync.c	9 May 2004 23:52:13 -0000	1.7
+++ b/mail-index-view-sync.c	22 May 2004 00:48:45 -0000	1.8
@@ -25,9 +25,13 @@
 static int
 view_sync_get_expunges(struct mail_index_view *view, buffer_t **expunges_r)
 {
-	const struct mail_transaction_expunge *exp, *end;
-	buffer_t *expunges;
+	const struct mail_transaction_header *hdr;
+	struct mail_transaction_expunge *src, *src_end, *dest;
+	const void *data;
 	size_t size;
+	int ret;
+
+	*expunges_r = buffer_create_dynamic(default_pool, 512, (size_t)-1);
 
 	/* with mask 0 we don't get anything, we'll just read the expunges
 	   while seeking to end */
@@ -36,23 +40,37 @@
 					  view->log_file_offset,
 					  view->index->hdr->log_file_seq,
 					  view->index->hdr->log_file_offset,
-					  0) < 0)
-		return -1;
-	if (mail_transaction_log_view_next(view->log_view,
-					   NULL, NULL, NULL) < 0)
+					  MAIL_TRANSACTION_EXPUNGE) < 0)
 		return -1;
+	while ((ret = mail_transaction_log_view_next(view->log_view,
+						     &hdr, &data, NULL)) > 0) {
+		mail_transaction_log_sort_expunges(*expunges_r,
+						   data, hdr->size);
+	}
 
-	expunges = mail_transaction_log_view_get_expunges(view->log_view);
-	exp = buffer_get_data(expunges, &size);
-	end = CONST_PTR_OFFSET(exp, size);
+	if (ret == 0) {
+		/* convert to sequences */
+		src = dest = buffer_get_modifyable_data(*expunges_r, &size);
+		src_end = src + size / sizeof(*src);
+		for (; src != src_end; src++) {
+			ret = mail_index_lookup_uid_range(view, src->uid1,
+							  src->uid2,
+							  &dest->uid1,
+							  &dest->uid2);
+			i_assert(ret == 0);
 
-	*expunges_r = buffer_create_dynamic(default_pool, size, (size_t)-1);
-	for (; exp != end; exp++) {
-		buffer_append(*expunges_r, &exp->seq1, sizeof(exp->seq1));
-		buffer_append(*expunges_r, &exp->seq2, sizeof(exp->seq2));
+			if (dest->uid1 == 0)
+				size -= sizeof(*dest);
+			else
+				dest++;
+		}
+		buffer_set_used_size(*expunges_r, size);
+	} else {
+		buffer_set_used_size(*expunges_r, 0);
 	}
-        mail_transaction_log_view_unset(view->log_view);
-	return 0;
+
+	mail_transaction_log_view_unset(view->log_view);
+	return ret;
 }
 
 int mail_index_view_sync_begin(struct mail_index_view *view,
@@ -135,17 +153,26 @@
 
 static int sync_expunge(const struct mail_transaction_expunge *e, void *context)
 {
-	struct mail_index_map *map = context;
-	unsigned int idx, count;
+        struct mail_index_view_sync_ctx *ctx = context;
+	struct mail_index_map *map = ctx->sync_map;
+	uint32_t idx, count, seq1, seq2;
+	int ret;
 
-	for (idx = e->seq1-1; idx < e->seq2; idx++) {
+	ret = mail_index_lookup_uid_range(ctx->view, e->uid1, e->uid2,
+					  &seq1, &seq2);
+	i_assert(ret == 0);
+
+	if (seq1 == 0)
+		return 1;
+
+	for (idx = seq1-1; idx < seq2; idx++) {
 		mail_index_header_update_counts(&map->hdr_copy,
 						map->records[idx].flags, 0);
 	}
 
-	count = e->seq2 - e->seq1 + 1;
+	count = seq2 - seq1 + 1;
 	buffer_delete(map->buffer,
-		      (e->seq1-1) * sizeof(struct mail_index_record),
+		      (seq1-1) * sizeof(struct mail_index_record),
 		      count * sizeof(struct mail_index_record));
 	map->records = buffer_get_modifyable_data(map->buffer, NULL);
 
@@ -156,7 +183,8 @@
 
 static int sync_append(const struct mail_index_record *rec, void *context)
 {
-	struct mail_index_map *map = context;
+        struct mail_index_view_sync_ctx *ctx = context;
+	struct mail_index_map *map = ctx->sync_map;
 
 	buffer_append(map->buffer, rec, sizeof(*rec));
 	map->records = buffer_get_modifyable_data(map->buffer, NULL);
@@ -173,12 +201,21 @@
 static int sync_flag_update(const struct mail_transaction_flag_update *u,
 			    void *context)
 {
-	struct mail_index_map *map = context;
+        struct mail_index_view_sync_ctx *ctx = context;
+	struct mail_index_map *map = ctx->sync_map;
 	struct mail_index_record *rec;
-	unsigned int i, idx;
+	uint32_t i, idx, seq1, seq2;
 	uint8_t old_flags;
+	int ret;
 
-	for (idx = u->seq1-1; idx < u->seq2; idx++) {
+	ret = mail_index_lookup_uid_range(ctx->view, u->uid1, u->uid2,
+					  &seq1, &seq2);
+	i_assert(ret == 0);
+
+	if (seq1 == 0)
+		return 1;
+
+	for (idx = seq1-1; idx < seq2; idx++) {
 		rec = &map->records[idx];
 
 		old_flags = rec->flags;
@@ -198,9 +235,16 @@
 static int sync_cache_update(const struct mail_transaction_cache_update *u,
 			     void *context)
 {
-	struct mail_index_map *map = context;
+        struct mail_index_view_sync_ctx *ctx = context;
+	uint32_t seq;
+	int ret;
 
-	map->records[u->seq-1].cache_offset = u->cache_offset;
+	ret = mail_index_lookup_uid_range(ctx->view, u->uid, u->uid,
+					  &seq, &seq);
+	i_assert(ret == 0);
+
+	if (seq != 0)
+		ctx->sync_map->records[seq-1].cache_offset = u->cache_offset;
 	return 1;
 }
 
@@ -211,7 +255,7 @@
 	};
 
 	return mail_transaction_map(ctx->hdr, ctx->data,
-				    &map_funcs, ctx->sync_map);
+				    &map_funcs, ctx);
 }
 
 static int mail_index_view_sync_next_trans(struct mail_index_view_sync_ctx *ctx,
@@ -258,12 +302,7 @@
 	switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
 	case MAIL_TRANSACTION_APPEND: {
 		rec->type = MAIL_INDEX_SYNC_TYPE_APPEND;
-		rec->seq1 = ctx->messages_count + 1;
-		ctx->messages_count +=
-			hdr->size / sizeof(struct mail_index_record);
-		rec->seq2 = ctx->messages_count;
-		rec->appends = NULL;
-
+		rec->uid1 = rec->uid2 = 0;
 		ctx->data_offset += hdr->size;
 		break;
 	}

Index: mail-index.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index.h,v
retrieving revision 1.107
retrieving revision 1.108
diff -u -d -r1.107 -r1.108
--- a/mail-index.h	3 May 2004 14:22:46 -0000	1.107
+++ b/mail-index.h	22 May 2004 00:48:45 -0000	1.108
@@ -109,7 +109,7 @@
 #define MAIL_INDEX_SYNC_MASK_ALL 0xff
 
 struct mail_index_sync_rec {
-	uint32_t seq1, seq2;
+	uint32_t uid1, uid2;
 	enum mail_index_sync_type type;
 
 	/* MAIL_INDEX_SYNC_TYPE_FLAGS: */
@@ -119,7 +119,8 @@
 	keywords_mask_t remove_keywords;
 
 	/* MAIL_INDEX_SYNC_TYPE_APPEND: */
-        const struct mail_index_record *appends;
+	const struct mail_index_record *appends;
+	size_t appends_count;
 };
 
 struct mail_index;

Index: mail-transaction-log-view.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-log-view.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- a/mail-transaction-log-view.c	20 May 2004 13:43:47 -0000	1.10
+++ b/mail-transaction-log-view.c	22 May 2004 00:48:45 -0000	1.11
@@ -14,8 +14,7 @@
 	uoff_t min_file_offset, max_file_offset;
 
 	enum mail_transaction_type type_mask;
-	buffer_t *expunges_buf, *data_buf;
-        struct mail_transaction_expunge_iter_ctx *exp_ctx;
+	buffer_t *expunges_buf;
 	struct mail_transaction_header tmp_hdr;
 
         struct mail_transaction_log_file *file;
@@ -55,8 +54,6 @@
 	}
 
 	mail_transaction_log_view_unset(view);
-	if (view->data_buf != NULL)
-		buffer_free(view->data_buf);
 	buffer_free(view->expunges_buf);
 	i_free(view);
 }
@@ -314,74 +311,10 @@
 	return 1;
 }
 
-static int seqfix_expunge(const struct mail_transaction_expunge *e,
-			  void *context)
-{
-	struct mail_transaction_log_view *view = context;
-	struct mail_transaction_expunge new_e;
-
-	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;*/
-	}
-
-	new_e.uid1 = new_e.uid2 = 0; // FIXME: this breaks anyway
-
-	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;
-}
-
-static int seqfix_flag_update(const struct mail_transaction_flag_update *u,
-			      void *context)
-{
-	struct mail_transaction_log_view *view = context;
-	struct mail_transaction_flag_update new_u;
-
-	if (!mail_transaction_expunge_iter_seek(view->exp_ctx,
-						u->seq1, u->seq2)) {
-		buffer_append(view->data_buf, u, sizeof(*u));
-		return 1;
-	}
-
-	new_u = *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;
-}
-
-static int seqfix_cache_update(const struct mail_transaction_cache_update *u,
-			       void *context)
-{
-	struct mail_transaction_log_view *view = context;
-	struct mail_transaction_cache_update 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;
-	}
-
-	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;
-}
-
 int mail_transaction_log_view_next(struct mail_transaction_log_view *view,
 				   const struct mail_transaction_header **hdr_r,
 				   const void **data_r, int *skipped_r)
 {
-	struct mail_transaction_map_functions seqfix_funcs = {
-		seqfix_expunge, NULL, seqfix_flag_update, seqfix_cache_update
-	};
 	const struct mail_transaction_header *hdr;
 	const void *data;
 	int ret = 0;
@@ -399,11 +332,6 @@
 		if (skipped_r != NULL)
 			*skipped_r = TRUE;
 
-		if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) != 0) {
-			mail_transaction_log_sort_expunges(view->expunges_buf,
-							   data, hdr->size);
-		}
-
 		/* FIXME: hide flag/cache updates for appends if
 		   append isn't in mask */
 	}
@@ -414,38 +342,7 @@
 	*hdr_r = hdr;
 	*data_r = data;
 
-	if (buffer_get_used_size(view->expunges_buf) > 0) {
-		/* we have to fix sequences in the data */
-		if (view->data_buf == NULL) {
-			view->data_buf =
-				buffer_create_dynamic(default_pool,
-						      hdr->size, (size_t)-1);
-		} else {
-			buffer_set_used_size(view->data_buf, 0);
-		}
-
-		view->exp_ctx =
-			mail_transaction_expunge_iter_init(view->expunges_buf);
-		ret = mail_transaction_map(hdr, data, &seqfix_funcs, view);
-		mail_transaction_expunge_iter_deinit(view->exp_ctx);
-
-		if (ret > 0) {
-			/* 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);
-		}
-	}
-
 	if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) != 0) {
-		mail_transaction_log_sort_expunges(view->expunges_buf,
-						   data, hdr->size);
-
 		/* hide expunge protection */
 		if (*hdr_r != &view->tmp_hdr) {
 			view->tmp_hdr = *hdr;
@@ -456,9 +353,3 @@
 
 	return 1;
 }
-
-buffer_t *
-mail_transaction_log_view_get_expunges(struct mail_transaction_log_view *view)
-{
-	return view->expunges_buf;
-}

Index: mail-transaction-log.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-log.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- a/mail-transaction-log.c	16 May 2004 23:29:27 -0000	1.27
+++ b/mail-transaction-log.c	22 May 2004 00:48:45 -0000	1.28
@@ -853,172 +853,6 @@
 	return ret;
 }
 
-static int get_expunge_buf(struct mail_transaction_log *log,
-			   struct mail_index_view *view, buffer_t *expunges)
-{
-	struct mail_transaction_log_view *sync_view;
-	const struct mail_transaction_header *hdr;
-	const void *data;
-	int ret;
-
-	sync_view = mail_transaction_log_view_open(log);
-	ret = mail_transaction_log_view_set(sync_view, view->log_file_seq,
-					    view->log_file_offset,
-					    log->head->hdr.file_seq,
-					    log->head->hdr.used_size,
-					    MAIL_TRANSACTION_TYPE_MASK);
-	while ((ret = mail_transaction_log_view_next(sync_view,
-						     &hdr, &data, NULL)) == 1) {
-		if ((hdr->type & MAIL_TRANSACTION_TYPE_MASK) ==
-		    MAIL_TRANSACTION_EXPUNGE) {
-			mail_transaction_log_sort_expunges(expunges,
-							   data, hdr->size);
-		}
-	}
-	mail_transaction_log_view_close(sync_view);
-	return ret;
-}
-
-static void
-log_view_fix_sequences(struct mail_index_view *view, buffer_t *view_expunges,
-		       buffer_t *buf, size_t record_size, int two, int uids)
-{
-	// FIXME: make sure this function works correctly
-	const struct mail_transaction_expunge *exp, *exp_end, *exp2;
-	unsigned char *data;
-	uint32_t *seq, expunges_before, count;
-	uint32_t last_exp, last_nonexp, last_nonexp_count;
-	size_t src_idx, dest_idx, size;
-	int ret;
-
-	if (buf == NULL)
-		return;
-
-	exp = buffer_get_data(view_expunges, &size);
-	exp_end = exp + (size / sizeof(*exp));
-	if (exp == exp_end)
-		return;
-
-	data = buffer_get_modifyable_data(buf, &size);
-
-	expunges_before = 0;
-	for (src_idx = dest_idx = 0; src_idx < size; src_idx += record_size) {
-		seq = (uint32_t *)&data[src_idx];
-
-		i_assert(src_idx + record_size == size ||
-			 *seq <= *((uint32_t *) &data[src_idx+record_size]));
-
-		while (exp != exp_end && exp->seq2 < seq[0]) {
-			expunges_before += exp->seq2 - exp->seq1 + 1;
-			exp++;
-		}
-		if (exp != exp_end && exp->seq1 <= seq[0]) {
-			/* this sequence was expunged at least partially */
-			if (!two)
-				continue;
-
-			exp2 = exp;
-			count = 0;
-			do {
-				/* we point to next non-expunged message */
-				seq[0] = exp2->seq2 + 1;
-				count += exp->seq2 - exp->seq1 + 1;
-				exp2++;
-			} while (exp2 != exp_end && exp2->seq1 == seq[0]);
-
-			if (seq[0] > seq[1] ||
-			    seq[0] > view->map->records_count) {
-				/* it's all expunged */
-				continue;
-			}
-
-			if (uids) {
-				/* get new first UID */
-				ret = mail_index_lookup_uid(view, seq[0],
-							    &seq[2]);
-				i_assert(ret == 0);
-			}
-			seq[0] -= count;
-		}
-		seq[0] -= expunges_before;
-
-		if (two) {
-			count = expunges_before;
-			last_exp = 0;
-			last_nonexp = seq[0];
-			last_nonexp_count = count;
-
-			exp2 = exp;
-			while (exp2 != exp_end && exp2->seq1 <= seq[1]) {
-				if (exp2->seq1-1 != last_exp) {
-					last_nonexp = exp2->seq1-1;
-					last_nonexp_count = count;
-				}
-
-				count += exp2->seq2 - exp2->seq1 + 1;
-				last_exp = exp2->seq2;
-				exp2++;
-			}
-
-			if (last_exp >= seq[1]) {
-				seq[1] = last_nonexp;
-				count = last_nonexp_count;
-				if (uids) {
-					/* ending of the range was expunged,
-					   we need to get last UID */
-					ret = mail_index_lookup_uid(view,
-								    seq[1],
-								    &seq[3]);
-					i_assert(ret == 0);
-				}
-			}
-			seq[1] -= count;
-		}
-
-		if (src_idx != dest_idx) {
-			memcpy(&data[dest_idx], &data[src_idx], record_size);
-			i_assert(dest_idx == 0 ||
-				 *((uint32_t *) &data[dest_idx]) >=
-				 *((uint32_t *) &data[dest_idx-record_size]));
-		}
-		dest_idx += record_size;
-	}
-	buffer_set_used_size(buf, dest_idx);
-}
-
-static int
-mail_transaction_log_fix_sequences(struct mail_transaction_log *log,
-                                   struct mail_index_transaction *t)
-{
-	buffer_t *view_expunges;
-
-	if (t->updates == NULL && t->cache_updates == NULL &&
-	    t->expunges == NULL)
-		return 0;
-
-	/* all sequences are currently relative to given view. we have to
-	   find out all the expunges since then, even the ones that aren't
-	   yet synchronized to index file. */
-	view_expunges = buffer_create_dynamic(default_pool, 1024, (size_t)-1);
-	if (get_expunge_buf(log, t->view, view_expunges) < 0) {
-		buffer_free(view_expunges);
-		return -1;
-	}
-
-	log_view_fix_sequences(t->view, view_expunges, t->updates,
-			       sizeof(struct mail_transaction_flag_update),
-			       TRUE, FALSE);
-	log_view_fix_sequences(t->view, view_expunges, t->cache_updates,
-			       sizeof(struct mail_transaction_cache_update),
-			       FALSE, FALSE);
-	log_view_fix_sequences(t->view, view_expunges, t->expunges,
-			       sizeof(struct mail_transaction_expunge),
-			       TRUE, TRUE);
-
-	buffer_free(view_expunges);
-	return 0;
-}
-
 static int mail_transaction_log_fix_appends(struct mail_transaction_log *log,
 					    struct mail_index_transaction *t)
 {
@@ -1155,6 +989,8 @@
 			return -1;
 	}
 
+	/* FIXME: index->hdr may not be up-to-date and so log_file_seq check
+	   might go wrong! sync header before we get here. */
 	if (log->head->hdr.file_seq == index->hdr->log_file_seq &&
 	    log->head->hdr.used_size > MAIL_TRANSACTION_LOG_ROTATE_SIZE &&
 	    log->head->last_mtime <
@@ -1172,8 +1008,7 @@
 	file = log->head;
 	append_offset = file->hdr.used_size;
 
-	if (mail_transaction_log_fix_sequences(log, t) < 0 ||
-	    mail_transaction_log_fix_appends(log, t) < 0) {
+	if (mail_transaction_log_fix_appends(log, t) < 0) {
 		if (!log->index->log_locked)
 			(void)mail_transaction_log_file_lock(file, F_UNLCK);
 		return -1;

Index: mail-transaction-log.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-log.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- a/mail-transaction-log.h	10 May 2004 21:09:15 -0000	1.8
+++ b/mail-transaction-log.h	22 May 2004 00:48:45 -0000	1.9
@@ -37,17 +37,16 @@
 };
 
 struct mail_transaction_expunge {
-	uint32_t seq1, seq2;
-	uint32_t uid1, uid2; /* only to avoid accidental expunges due to bugs */
+	uint32_t uid1, uid2;
 };
 
 struct mail_transaction_cache_update {
-	uint32_t seq;
+	uint32_t uid;
 	uint32_t cache_offset;
 };
 
 struct mail_transaction_flag_update {
-	uint32_t seq1, seq2;
+	uint32_t uid1, uid2;
 	uint8_t add_flags;
 	keywords_mask_t add_keywords;
 	uint8_t remove_flags;
@@ -84,9 +83,6 @@
 				       uint32_t *file_seq_r,
 				       uoff_t *file_offset_r);
 
-buffer_t *
-mail_transaction_log_view_get_expunges(struct mail_transaction_log_view *view);
-
 /* Marks the log file in current position to be corrupted. */
 void
 mail_transaction_log_view_set_corrupted(struct mail_transaction_log_view *view,

Index: mail-transaction-util.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-util.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- a/mail-transaction-util.c	20 May 2004 13:43:47 -0000	1.6
+++ b/mail-transaction-util.c	22 May 2004 00:48:45 -0000	1.7
@@ -130,7 +130,6 @@
 	const struct mail_transaction_expunge *src_end;
 	struct mail_transaction_expunge *dest;
 	struct mail_transaction_expunge new_exp;
-	uint32_t expunges_before, count;
 	size_t first, i, dest_count;
 
 	i_assert(src_buf_size % sizeof(*src) == 0);
@@ -140,43 +139,27 @@
 	dest = buffer_get_modifyable_data(expunges_buf, &dest_count);
 	dest_count /= sizeof(*dest);
 
-	expunges_before = 0;
 	for (i = 0; src != src_end; src++) {
 		/* src[] must be sorted. */
-		i_assert(src+1 == src_end || src->seq1 < src[1].seq1);
+		i_assert(src+1 == src_end || src->uid1 < src[1].uid1);
 
 		for (; i < dest_count; i++) {
-			if (src->seq1 + expunges_before < dest[i].seq1)
+			if (src->uid1 < dest[i].uid1)
 				break;
-
-			i_assert(src->uid2 == 0 || src->uid2 > dest[i].uid1);
-			expunges_before += dest[i].seq2 - dest[i].seq1 + 1;
 		}
 
 		new_exp = *src;
-		new_exp.seq1 += expunges_before;
-		new_exp.seq2 += expunges_before;
-
-		/* if src[] is in format {1,2}{1,2} rather than {1,2}{3,4}:
-		   expunges_before += new_exp.seq2 - new_exp.seq1 + 1;*/
 
 		first = i;
-		while (i < dest_count && new_exp.seq2 >= dest[i].seq1-1) {
+		while (i < dest_count && src->uid2 >= dest[i].uid1-1) {
 			/* we can/must merge with next record */
-			count = dest[i].seq2 - dest[i].seq1 + 1;
-			expunges_before += count;
-
-			new_exp.seq2 += count;
-			if (new_exp.seq2 == dest[i].seq2)
+			if (new_exp.uid2 < dest[i].uid2)
 				new_exp.uid2 = dest[i].uid2;
-			i_assert(new_exp.uid2 == 0 ||
-				 new_exp.uid2 >= dest[i].uid2);
 			i++;
 		}
 
-		if (first > 0 && new_exp.seq1 == dest[first-1].seq2+1) {
+		if (first > 0 && new_exp.uid1 <= dest[first-1].uid2+1) {
 			/* continue previous record */
-			dest[first-1].seq2 = new_exp.seq2;
 			dest[first-1].uid2 = new_exp.uid2;
 		} else if (i == first) {
 			buffer_insert(expunges_buf, i * sizeof(new_exp),
@@ -201,86 +184,3 @@
 		}
 	}
 }
-
-struct mail_transaction_expunge_iter_ctx *
-mail_transaction_expunge_iter_init(const buffer_t *expunges_buf)
-{
-	struct mail_transaction_expunge_iter_ctx *ctx;
-
-	ctx = i_new(struct mail_transaction_expunge_iter_ctx, 1);
-	ctx->cur_seq = 1;
-
-	if (expunges_buf != NULL) {
-		ctx->expunges =
-			buffer_get_data(expunges_buf, &ctx->expunges_count);
-		ctx->expunges_count /= sizeof(*ctx->expunges);
-	}
-	return ctx;
-}
-
-void mail_transaction_expunge_iter_deinit(
-	struct mail_transaction_expunge_iter_ctx *ctx)
-{
-	i_free(ctx);
-}
-
-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;
-
-	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 > seq1)
-			break;
-		ctx->cur_seq += count;
-
-		ctx->expunges_before += ctx->expunges[idx].seq2 -
-			ctx->expunges[idx].seq1 + 1;
-		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 != 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.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/mail-transaction-util.h	20 May 2004 13:43:47 -0000	1.2
+++ b/mail-transaction-util.h	22 May 2004 00:48:45 -0000	1.3
@@ -32,22 +32,4 @@
 				   const struct mail_transaction_expunge *src,
 				   size_t src_buf_size);
 
-/* 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



More information about the dovecot-cvs mailing list