dovecot-2.2: lib-index: mail_index_attribute_[un]set() adds chan...

dovecot at dovecot.org dovecot at dovecot.org
Thu Mar 14 15:41:49 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/db0136374bb0
changeset: 16023:db0136374bb0
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Mar 14 15:29:18 2013 +0200
description:
lib-index: mail_index_attribute_[un]set() adds changed attributes' keys to transaction log.
This provides them both a modseq (so their changes become visible) as well
as an efficient way to see what attributes have changed by reading the
transaction log. The values themselves aren't written to the log, because
they could be large.

diffstat:

 src/doveadm/doveadm-dump-log.c                 |  14 ++++++++++
 src/lib-index/mail-index-modseq.c              |  10 ++++++-
 src/lib-index/mail-index-sync-update.c         |   5 +++
 src/lib-index/mail-index-transaction-export.c  |   9 ++++++
 src/lib-index/mail-index-transaction-private.h |   1 +
 src/lib-index/mail-index-transaction-update.c  |  27 ++++++++++++++++++++
 src/lib-index/mail-index.h                     |   8 ++++++
 src/lib-index/mail-transaction-log-file.c      |   1 +
 src/lib-index/mail-transaction-log-view.c      |  34 ++++++++++++++++++++++++++
 src/lib-index/mail-transaction-log.h           |   3 +-
 10 files changed, 110 insertions(+), 2 deletions(-)

diffs (260 lines):

diff -r 9a8eaf97559d -r db0136374bb0 src/doveadm/doveadm-dump-log.c
--- a/src/doveadm/doveadm-dump-log.c	Thu Mar 14 15:24:48 2013 +0200
+++ b/src/doveadm/doveadm-dump-log.c	Thu Mar 14 15:29:18 2013 +0200
@@ -52,6 +52,7 @@
 	case MAIL_TRANSACTION_FLAG_UPDATE:
 	case MAIL_TRANSACTION_KEYWORD_UPDATE:
 	case MAIL_TRANSACTION_KEYWORD_RESET:
+	case MAIL_TRANSACTION_ATTRIBUTE_UPDATE:
 		/* these changes increase modseq */
 		return TRUE;
 	}
@@ -114,6 +115,9 @@
 	case MAIL_TRANSACTION_BOUNDARY:
 		name = "boundary";
 		break;
+	case MAIL_TRANSACTION_ATTRIBUTE_UPDATE:
+		name = "attribute-update";
+		break;
 	default:
 		name = t_strdup_printf("unknown: %x", type);
 		break;
@@ -415,6 +419,16 @@
 		printf(" - size=%u\n", rec->size);
 		break;
 	}
+	case MAIL_TRANSACTION_ATTRIBUTE_UPDATE: {
+		const char *keys = data;
+		unsigned int i;
+
+		for (i = 0; i < size && keys[i] != '\0'; ) {
+			printf(" - %s\n", keys+i);
+			i += strlen(keys+i) + 1;
+		}
+		break;
+	}
 	default:
 		break;
 	}
diff -r 9a8eaf97559d -r db0136374bb0 src/lib-index/mail-index-modseq.c
--- a/src/lib-index/mail-index-modseq.c	Thu Mar 14 15:24:48 2013 +0200
+++ b/src/lib-index/mail-index-modseq.c	Thu Mar 14 15:29:18 2013 +0200
@@ -335,6 +335,7 @@
 	buffer_t uid_buf;
 	unsigned int i, count;
 	uint32_t seq1, seq2;
+	uint64_t modseq;
 
 	switch (thdr->type & MAIL_TRANSACTION_TYPE_MASK) {
 	case MAIL_TRANSACTION_APPEND: {
@@ -374,12 +375,19 @@
 		array_create_from_buffer(&uids, &uid_buf,
 			sizeof(struct mail_transaction_keyword_reset));
 		break;
+	case MAIL_TRANSACTION_ATTRIBUTE_UPDATE:
+		break;
 	default:
 		return;
 	}
 
+	/* update highestmodseq regardless of whether any mails were updated */
+	modseq = mail_transaction_log_view_get_prev_modseq(ctx->log_view);
+	if (modseq > ctx->highest_modseq)
+		ctx->highest_modseq = modseq;
+
 	/* update modseqs */
-	count = array_count(&uids);
+	count = array_is_created(&uids) ? array_count(&uids) : 0;
 	for (i = 0; i < count; i++) {
 		rec = array_idx(&uids, i);
 		if (mail_index_lookup_seq_range(ctx->view, rec->seq1, rec->seq2,
diff -r 9a8eaf97559d -r db0136374bb0 src/lib-index/mail-index-sync-update.c
--- a/src/lib-index/mail-index-sync-update.c	Thu Mar 14 15:24:48 2013 +0200
+++ b/src/lib-index/mail-index-sync-update.c	Thu Mar 14 15:29:18 2013 +0200
@@ -495,6 +495,7 @@
 			    const struct mail_transaction_header *hdr,
 			    const void *data)
 {
+	uint64_t modseq;
 	int ret = 0;
 
 	switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
@@ -767,6 +768,10 @@
 		break;
 	case MAIL_TRANSACTION_BOUNDARY:
 		break;
+	case MAIL_TRANSACTION_ATTRIBUTE_UPDATE:
+		modseq = mail_transaction_log_view_get_prev_modseq(ctx->view->log_view);
+		mail_index_modseq_update_highest(ctx->modseq_ctx, modseq);
+		break;
 	default:
 		mail_index_sync_set_corrupted(ctx,
 			"Unknown transaction record type 0x%x",
diff -r 9a8eaf97559d -r db0136374bb0 src/lib-index/mail-index-transaction-export.c
--- a/src/lib-index/mail-index-transaction-export.c	Thu Mar 14 15:24:48 2013 +0200
+++ b/src/lib-index/mail-index-transaction-export.c	Thu Mar 14 15:29:18 2013 +0200
@@ -393,6 +393,15 @@
 		log_append_buffer(&ctx, log_get_hdr_update_buffer(t, TRUE),
 				  MAIL_TRANSACTION_HEADER_UPDATE);
 	}
+	if (t->attribute_updates != NULL) {
+		/* need to have 32bit alignment */
+		if (t->attribute_updates->used % 4 != 0) {
+			buffer_append_zero(t->attribute_updates,
+					   4 - t->attribute_updates->used % 4);
+		}
+		log_append_buffer(&ctx, t->attribute_updates,
+				  MAIL_TRANSACTION_ATTRIBUTE_UPDATE);
+	}
 	if (array_is_created(&t->appends)) {
 		change_mask |= MAIL_INDEX_FSYNC_MASK_APPENDS;
 		log_append_buffer(&ctx, t->appends.arr.buffer,
diff -r 9a8eaf97559d -r db0136374bb0 src/lib-index/mail-index-transaction-private.h
--- a/src/lib-index/mail-index-transaction-private.h	Thu Mar 14 15:24:48 2013 +0200
+++ b/src/lib-index/mail-index-transaction-private.h	Thu Mar 14 15:29:18 2013 +0200
@@ -70,6 +70,7 @@
 	ARRAY(uint32_t) ext_reset_atomic;
 
 	ARRAY(struct mail_index_transaction_keyword_update) keyword_updates;
+	buffer_t *attribute_updates; /* [+-][ps]key\0.. */
 
 	uint64_t min_highest_modseq;
 	uint64_t max_modseq;
diff -r 9a8eaf97559d -r db0136374bb0 src/lib-index/mail-index-transaction-update.c
--- a/src/lib-index/mail-index-transaction-update.c	Thu Mar 14 15:24:48 2013 +0200
+++ b/src/lib-index/mail-index-transaction-update.c	Thu Mar 14 15:29:18 2013 +0200
@@ -76,6 +76,8 @@
 		array_free(&t->ext_reset_ids);
 	if (array_is_created(&t->ext_reset_atomic))
 		array_free(&t->ext_reset_atomic);
+	if (t->attribute_updates != NULL)
+		buffer_free(&t->attribute_updates);
 
 	t->first_new_seq = mail_index_view_get_messages_count(t->view)+1;
 	t->last_new_seq = 0;
@@ -106,6 +108,7 @@
 		array_is_created(&t->modseq_updates) ||
 		array_is_created(&t->expunges) ||
 		array_is_created(&t->keyword_updates) ||
+		t->attribute_updates != NULL ||
 		t->pre_hdr_changed || t->post_hdr_changed ||
 		t->min_highest_modseq != 0;
 }
@@ -647,6 +650,30 @@
 	mail_index_update_flags_range(t, seq, seq, modify_type, flags);
 }
 
+static void
+mail_index_attribute_set_full(struct mail_index_transaction *t,
+			      const char *key, bool pvt, char prefix)
+{
+	if (t->attribute_updates == NULL)
+		t->attribute_updates = buffer_create_dynamic(default_pool, 64);
+	buffer_append_c(t->attribute_updates, prefix);
+	buffer_append_c(t->attribute_updates, pvt ? 'p' : 's');
+	buffer_append(t->attribute_updates, key, strlen(key)+1);
+	t->log_updates = TRUE;
+}
+
+void mail_index_attribute_set(struct mail_index_transaction *t,
+			      bool pvt, const char *key)
+{
+	mail_index_attribute_set_full(t, key, pvt, '+');
+}
+
+void mail_index_attribute_unset(struct mail_index_transaction *t,
+				bool pvt, const char *key)
+{
+	mail_index_attribute_set_full(t, key, pvt, '-');
+}
+
 void mail_index_update_header(struct mail_index_transaction *t,
 			      size_t offset, const void *data, size_t size,
 			      bool prepend)
diff -r 9a8eaf97559d -r db0136374bb0 src/lib-index/mail-index.h
--- a/src/lib-index/mail-index.h	Thu Mar 14 15:24:48 2013 +0200
+++ b/src/lib-index/mail-index.h	Thu Mar 14 15:29:18 2013 +0200
@@ -464,6 +464,14 @@
 				   uint32_t seq1, uint32_t seq2,
 				   enum modify_type modify_type,
 				   enum mail_flags flags);
+/* Specified attribute's value was changed. This is just a notification so the
+   change gets assigned its own modseq and any log readers can find out about
+   this change. */
+void mail_index_attribute_set(struct mail_index_transaction *t,
+			      bool pvt, const char *key);
+/* Attribute was deleted. */
+void mail_index_attribute_unset(struct mail_index_transaction *t,
+				bool pvt, const char *key);
 /* Update message's modseq to be at least min_modseq. */
 void mail_index_update_modseq(struct mail_index_transaction *t, uint32_t seq,
 			      uint64_t min_modseq);
diff -r 9a8eaf97559d -r db0136374bb0 src/lib-index/mail-transaction-log-file.c
--- a/src/lib-index/mail-transaction-log-file.c	Thu Mar 14 15:24:48 2013 +0200
+++ b/src/lib-index/mail-transaction-log-file.c	Thu Mar 14 15:29:18 2013 +0200
@@ -1022,6 +1022,7 @@
 	case MAIL_TRANSACTION_FLAG_UPDATE:
 	case MAIL_TRANSACTION_KEYWORD_UPDATE:
 	case MAIL_TRANSACTION_KEYWORD_RESET:
+	case MAIL_TRANSACTION_ATTRIBUTE_UPDATE:
 		/* these changes increase modseq */
 		*cur_modseq += 1;
 		break;
diff -r 9a8eaf97559d -r db0136374bb0 src/lib-index/mail-transaction-log-view.c
--- a/src/lib-index/mail-transaction-log-view.c	Thu Mar 14 15:24:48 2013 +0200
+++ b/src/lib-index/mail-transaction-log-view.c	Thu Mar 14 15:29:18 2013 +0200
@@ -608,6 +608,40 @@
 			if ((i % 4) != 0)
 				i += 4 - (i % 4);
 		}
+		break;
+	}
+	case MAIL_TRANSACTION_ATTRIBUTE_UPDATE: {
+		const char *attr_changes = data;
+		unsigned int i;
+
+		for (i = 0; i+2 < rec_size && attr_changes[i] != '\0'; ) {
+			if (attr_changes[i] != '+' && attr_changes[i] != '-') {
+				mail_transaction_log_file_set_corrupted(file,
+					"attribute update: Invalid prefix 0x%02x",
+					attr_changes[i]);
+				return FALSE;
+			}
+			i++;
+			if (attr_changes[i] != 'p' && attr_changes[i] != 's') {
+				mail_transaction_log_file_set_corrupted(file,
+					"attribute update: Invalid type 0x%02x",
+					attr_changes[i]);
+				return FALSE;
+			}
+			i++;
+			if (attr_changes[i] == '\0') {
+				mail_transaction_log_file_set_corrupted(file,
+					"attribute update: Empty key");
+				return FALSE;
+			}
+			i += strlen(attr_changes+i) + 1;
+		}
+		if (i == 0 || (i < rec_size && attr_changes[i] != '\0')) {
+			mail_transaction_log_file_set_corrupted(file,
+				"attribute update doesn't end with NUL");
+			return FALSE;
+		}
+		break;
 	}
 	default:
 		break;
diff -r 9a8eaf97559d -r db0136374bb0 src/lib-index/mail-transaction-log.h
--- a/src/lib-index/mail-transaction-log.h	Thu Mar 14 15:24:48 2013 +0200
+++ b/src/lib-index/mail-transaction-log.h	Thu Mar 14 15:29:18 2013 +0200
@@ -44,8 +44,9 @@
 	MAIL_TRANSACTION_INDEX_DELETED		= 0x00020000,
 	MAIL_TRANSACTION_INDEX_UNDELETED	= 0x00040000,
 	MAIL_TRANSACTION_BOUNDARY		= 0x00080000,
+	MAIL_TRANSACTION_ATTRIBUTE_UPDATE       = 0x00100000,
 
-	MAIL_TRANSACTION_TYPE_MASK		= 0x000fffff,
+	MAIL_TRANSACTION_TYPE_MASK		= 0x0fffffff,
 
 #define MAIL_TRANSACTION_EXT_MASK \
 	(MAIL_TRANSACTION_EXT_INTRO | MAIL_TRANSACTION_EXT_RESET | \


More information about the dovecot-cvs mailing list