dovecot-2.2: lib-index: Optimize removing large number of expunges.

dovecot at dovecot.org dovecot at dovecot.org
Wed May 28 12:55:06 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/6d2176c558af
changeset: 17416:6d2176c558af
user:      Timo Sirainen <tss at iki.fi>
date:      Wed May 28 15:53:58 2014 +0300
description:
lib-index: Optimize removing large number of expunges.

diffstat:

 src/lib-index/mail-index-sync-update.c |  48 +++++++++++++++++++++------------
 1 files changed, 30 insertions(+), 18 deletions(-)

diffs (96 lines):

diff -r 0f618da2024b -r 6d2176c558af src/lib-index/mail-index-sync-update.c
--- a/src/lib-index/mail-index-sync-update.c	Wed May 28 04:20:58 2014 +0300
+++ b/src/lib-index/mail-index-sync-update.c	Wed May 28 15:53:58 2014 +0300
@@ -231,16 +231,11 @@
 }
 
 static void
-sync_expunge(struct mail_index_sync_map_ctx *ctx, uint32_t uid1, uint32_t uid2)
+sync_expunge(struct mail_index_sync_map_ctx *ctx, uint32_t seq1, uint32_t seq2)
 {
 	struct mail_index_map *map;
 	struct mail_index_record *rec;
-	uint32_t seq_count, seq, seq1, seq2;
-
-	if (!mail_index_lookup_seq_range(ctx->view, uid1, uid2, &seq1, &seq2)) {
-		/* everything expunged already */
-		return;
-	}
+	uint32_t seq_count, seq;
 
 	sync_expunge_call_handlers(ctx, seq1, seq2);
 
@@ -261,6 +256,18 @@
 	mail_index_modseq_expunge(ctx->modseq_ctx, seq1, seq2);
 }
 
+static void
+sync_expunge_range(struct mail_index_sync_map_ctx *ctx, const ARRAY_TYPE(seq_range) *seqs)
+{
+	const struct seq_range *range;
+	unsigned int i, count;
+
+	/* do this in reverse so the memmove()s are smaller */
+	range = array_get(seqs, &count);
+	for (i = count; i > 0; i--)
+		sync_expunge(ctx, range[i-1].seq1, range[i-1].seq2);
+}
+
 static void *sync_append_record(struct mail_index_map *map)
 {
 	size_t append_pos;
@@ -506,38 +513,43 @@
 	case MAIL_TRANSACTION_EXPUNGE:
 	case MAIL_TRANSACTION_EXPUNGE|MAIL_TRANSACTION_EXPUNGE_PROT: {
 		const struct mail_transaction_expunge *rec = data, *end;
+		ARRAY_TYPE(seq_range) seqs;
+		uint32_t seq1, seq2;
 
 		if ((hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0) {
 			/* this is simply a request for expunge */
 			break;
 		}
+		t_array_init(&seqs, 64);
 		end = CONST_PTR_OFFSET(data, hdr->size);
-		for (; rec != end; rec++)
-			sync_expunge(ctx, rec->uid1, rec->uid2);
+		for (; rec != end; rec++) {
+			if (mail_index_lookup_seq_range(ctx->view,
+					rec->uid1, rec->uid2, &seq1, &seq2))
+				seq_range_array_add_range(&seqs, seq1, seq2);
+		}
+		sync_expunge_range(ctx, &seqs);
 		break;
 	}
 	case MAIL_TRANSACTION_EXPUNGE_GUID:
 	case MAIL_TRANSACTION_EXPUNGE_GUID|MAIL_TRANSACTION_EXPUNGE_PROT: {
 		const struct mail_transaction_expunge_guid *rec = data, *end;
-		ARRAY_TYPE(seq_range) uids;
-		const struct seq_range *range;
-		unsigned int i, count;
+		ARRAY_TYPE(seq_range) seqs;
+		uint32_t seq;
 
 		if ((hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0) {
 			/* this is simply a request for expunge */
 			break;
 		}
-		t_array_init(&uids, 64);
+		t_array_init(&seqs, 64);
 		end = CONST_PTR_OFFSET(data, hdr->size);
 		for (; rec != end; rec++) {
 			i_assert(rec->uid != 0);
-			seq_range_array_add(&uids, rec->uid);
+
+			if (mail_index_lookup_seq(ctx->view, rec->uid, &seq))
+				seq_range_array_add(&seqs, seq);
 		}
 
-		/* do this in reverse so the memmove()s are smaller */
-		range = array_get(&uids, &count);
-		for (i = count; i > 0; i--)
-			sync_expunge(ctx, range[i-1].seq1, range[i-1].seq2);
+		sync_expunge_range(ctx, &seqs);
 		break;
 	}
 	case MAIL_TRANSACTION_FLAG_UPDATE: {


More information about the dovecot-cvs mailing list