dovecot: Moved index sync record grouping from mbox to generic c...

dovecot at dovecot.org dovecot at dovecot.org
Sun Jul 8 20:03:36 EEST 2007


details:   http://hg.dovecot.org/dovecot/rev/54ef7dccdfc7
changeset: 5898:54ef7dccdfc7
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Jul 08 19:57:09 2007 +0300
description:
Moved index sync record grouping from mbox to generic code.

diffstat:

5 files changed, 285 insertions(+), 177 deletions(-)
src/lib-storage/index/index-sync-changes.c     |  213 ++++++++++++++++++++++++
src/lib-storage/index/index-sync-changes.h     |   27 +++
src/lib-storage/index/mbox/mbox-sync-private.h |    8 
src/lib-storage/index/mbox/mbox-sync-update.c  |   21 +-
src/lib-storage/index/mbox/mbox-sync.c         |  193 +++------------------

diffs (truncated from 623 to 300 lines):

diff -r 3ec9ce7cd5e7 -r 54ef7dccdfc7 src/lib-storage/index/index-sync-changes.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/index-sync-changes.c	Sun Jul 08 19:57:09 2007 +0300
@@ -0,0 +1,213 @@
+/* Copyright (C) 2007 Timo Sirainen */
+
+#include "lib.h"
+#include "array.h"
+#include "index-storage.h"
+#include "index-sync-changes.h"
+
+struct index_sync_changes_context {
+	struct index_mailbox *ibox;
+	struct mail_index_sync_ctx *index_sync_ctx;
+	struct mail_index_view *sync_view;
+	struct mail_index_transaction *sync_trans;
+
+	ARRAY_DEFINE(syncs, struct mail_index_sync_rec);
+	struct mail_index_sync_rec sync_rec;
+	bool dirty_flag_updates;
+};
+
+struct index_sync_changes_context *
+index_sync_changes_init(struct index_mailbox *ibox,
+			struct mail_index_sync_ctx *index_sync_ctx,
+			struct mail_index_view *sync_view,
+			struct mail_index_transaction *sync_trans,
+			bool dirty_flag_updates)
+{
+	struct index_sync_changes_context *ctx;
+
+	ctx = i_new(struct index_sync_changes_context, 1);
+	ctx->ibox = ibox;
+	ctx->index_sync_ctx = index_sync_ctx;
+	ctx->sync_view = sync_view;
+	ctx->sync_trans = sync_trans;
+	ctx->dirty_flag_updates = dirty_flag_updates;
+	i_array_init(&ctx->syncs, 16);
+	return ctx;
+}
+
+void index_sync_changes_deinit(struct index_sync_changes_context **_ctx)
+{
+	struct index_sync_changes_context *ctx = *_ctx;
+
+	*_ctx = NULL;
+	array_free(&ctx->syncs);
+	i_free(ctx);
+}
+
+void index_sync_changes_reset(struct index_sync_changes_context *ctx)
+{
+	array_clear(&ctx->syncs);
+	memset(&ctx->sync_rec, 0, sizeof(ctx->sync_rec));
+}
+
+void index_sync_changes_delete_to(struct index_sync_changes_context *ctx,
+				  uint32_t last_uid)
+{
+	struct mail_index_sync_rec *syncs;
+	unsigned int src, dest, count;
+
+	syncs = array_get_modifiable(&ctx->syncs, &count);
+
+	for (src = dest = 0; src < count; src++) {
+		i_assert(last_uid >= syncs[src].uid1);
+		if (last_uid <= syncs[src].uid2) {
+			/* keep it */
+			if (src != dest)
+				syncs[dest] = syncs[src];
+			dest++;
+		}
+	}
+
+	array_delete(&ctx->syncs, dest, count - dest);
+}
+
+static bool
+index_sync_changes_have_expunges(struct index_sync_changes_context *ctx,
+				 unsigned int count)
+{
+	const struct mail_index_sync_rec *syncs;
+	unsigned int i;
+
+	syncs = array_idx(&ctx->syncs, 0);
+	for (i = 0; i < count; i++) {
+		if (syncs[i].type == MAIL_INDEX_SYNC_TYPE_EXPUNGE)
+			return TRUE;
+	}
+	return FALSE;
+}
+
+int index_sync_changes_read(struct index_sync_changes_context *ctx,
+			    uint32_t uid, bool *sync_expunge_r)
+{
+	struct mail_index_sync_rec *sync_rec = &ctx->sync_rec;
+	uint32_t seq1, seq2;
+	unsigned int orig_count;
+	int ret;
+
+	*sync_expunge_r = FALSE;
+
+	index_sync_changes_delete_to(ctx, uid);
+	orig_count = array_count(&ctx->syncs);
+
+	while (uid >= sync_rec->uid1) {
+		if (uid <= sync_rec->uid2 &&
+		    sync_rec->type != MAIL_INDEX_SYNC_TYPE_APPEND) {
+			array_append(&ctx->syncs, sync_rec, 1);
+
+			if (sync_rec->type == MAIL_INDEX_SYNC_TYPE_EXPUNGE)
+				*sync_expunge_r = TRUE;
+		}
+
+		ret = mail_index_sync_next(ctx->index_sync_ctx, sync_rec);
+		if (ret < 0) {
+			mail_storage_set_index_error(ctx->ibox);
+			return -1;
+		}
+
+		if (ret == 0) {
+			memset(sync_rec, 0, sizeof(*sync_rec));
+			break;
+		}
+
+		switch (sync_rec->type) {
+		case MAIL_INDEX_SYNC_TYPE_APPEND:
+			/* ignore */
+			memset(sync_rec, 0, sizeof(*sync_rec));
+			break;
+		case MAIL_INDEX_SYNC_TYPE_EXPUNGE:
+			break;
+		case MAIL_INDEX_SYNC_TYPE_FLAGS:
+		case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD:
+		case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE:
+		case MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET:
+			if (!ctx->dirty_flag_updates)
+				break;
+
+			/* mark the changes as dirty */
+			if (mail_index_lookup_uid_range(ctx->sync_view,
+							sync_rec->uid1,
+							sync_rec->uid2,
+							&seq1, &seq2) < 0) {
+				mail_storage_set_index_error(ctx->ibox);
+				return -1;
+			}
+			memset(sync_rec, 0, sizeof(*sync_rec));
+
+			if (seq1 == 0)
+				break;
+
+			mail_index_update_flags_range(ctx->sync_trans,
+				seq1, seq2, MODIFY_ADD,
+				(enum mail_flags)MAIL_INDEX_MAIL_FLAG_DIRTY);
+			break;
+		}
+	}
+
+	if (!*sync_expunge_r && orig_count > 0) {
+		*sync_expunge_r =
+			index_sync_changes_have_expunges(ctx, orig_count);
+	}
+
+	return 0;
+}
+
+bool index_sync_changes_have(struct index_sync_changes_context *ctx)
+{
+	return array_count(&ctx->syncs) > 0;
+}
+
+uint32_t
+index_sync_changes_get_next_uid(struct index_sync_changes_context *ctx)
+{
+	return ctx->sync_rec.uid1;
+}
+
+void index_sync_changes_apply(struct index_sync_changes_context *ctx,
+			      pool_t pool, uint8_t *flags,
+			      ARRAY_TYPE(keyword_indexes) *keywords,
+			      enum mailbox_sync_type *sync_type_r)
+{
+	const struct mail_index_sync_rec *syncs;
+	unsigned int i, count;
+	enum mailbox_sync_type sync_type = 0;
+
+	syncs = array_get(&ctx->syncs, &count);
+	for (i = 0; i < count; i++) {
+		switch (syncs[i].type) {
+		case MAIL_INDEX_SYNC_TYPE_FLAGS:
+			mail_index_sync_flags_apply(&syncs[i], flags);
+			sync_type |= MAILBOX_SYNC_TYPE_FLAGS;
+			break;
+		case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD:
+		case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE:
+		case MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET:
+			if (!array_is_created(keywords)) {
+				/* no existing keywords */
+				if (syncs[i].type !=
+				    MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD)
+					break;
+
+				/* adding, create the array */
+				p_array_init(keywords, pool,
+					     I_MIN(10, count - i));
+			}
+			if (mail_index_sync_keywords_apply(&syncs[i], keywords))
+				sync_type |= MAILBOX_SYNC_TYPE_KEYWORDS;
+			break;
+		default:
+			break;
+		}
+	}
+
+	*sync_type_r = sync_type;
+}
diff -r 3ec9ce7cd5e7 -r 54ef7dccdfc7 src/lib-storage/index/index-sync-changes.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/index-sync-changes.h	Sun Jul 08 19:57:09 2007 +0300
@@ -0,0 +1,27 @@
+#ifndef __INDEX_SYNC_CHANGES_H
+#define __INDEX_SYNC_CHANGES_H
+
+struct index_sync_changes_context *
+index_sync_changes_init(struct index_mailbox *ibox,
+			struct mail_index_sync_ctx *index_sync_ctx,
+			struct mail_index_view *sync_view,
+			struct mail_index_transaction *sync_trans,
+			bool dirty_flag_updates);
+void index_sync_changes_deinit(struct index_sync_changes_context **_ctx);
+
+void index_sync_changes_reset(struct index_sync_changes_context *ctx);
+void index_sync_changes_delete_to(struct index_sync_changes_context *ctx,
+				  uint32_t last_uid);
+
+int index_sync_changes_read(struct index_sync_changes_context *ctx,
+			    uint32_t uid, bool *sync_expunge_r);
+bool index_sync_changes_have(struct index_sync_changes_context *ctx);
+uint32_t
+index_sync_changes_get_next_uid(struct index_sync_changes_context *ctx);
+
+void index_sync_changes_apply(struct index_sync_changes_context *ctx,
+			      pool_t pool, uint8_t *flags,
+			      ARRAY_TYPE(keyword_indexes) *keywords,
+			      enum mailbox_sync_type *sync_type_r);
+
+#endif
diff -r 3ec9ce7cd5e7 -r 54ef7dccdfc7 src/lib-storage/index/mbox/mbox-sync-private.h
--- a/src/lib-storage/index/mbox/mbox-sync-private.h	Sun Jul 08 19:46:31 2007 +0300
+++ b/src/lib-storage/index/mbox/mbox-sync-private.h	Sun Jul 08 19:57:09 2007 +0300
@@ -3,8 +3,6 @@
 
 #include "md5.h"
 #include "mail-index.h"
-
-ARRAY_DEFINE_TYPE(sync_recs, struct mail_index_sync_rec);
 
 #include <sys/stat.h>
 
@@ -124,8 +122,7 @@ struct mbox_sync_context {
 
 	/* mail state: */
 	ARRAY_DEFINE(mails, struct mbox_sync_mail);
-	ARRAY_TYPE(sync_recs) syncs;
-	struct mail_index_sync_rec sync_rec;
+	struct index_sync_changes_context *sync_changes;
 
 	/* per-mail pool */
 	pool_t mail_keyword_pool;
@@ -166,9 +163,6 @@ int mbox_sync_rewrite(struct mbox_sync_c
 		      uoff_t end_offset, off_t move_diff, uoff_t extra_space,
 		      uint32_t first_seq, uint32_t last_seq);
 
-void mbox_sync_apply_index_syncs(struct mbox_sync_context *sync_ctx,
-				 struct mbox_sync_mail *mail,
-				 enum mailbox_sync_type *sync_type_r);
 int mbox_sync_seek(struct mbox_sync_context *sync_ctx, uoff_t from_offset);
 void mbox_sync_file_update_ext_modified(struct mbox_sync_context *sync_ctx);
 void mbox_sync_file_updated(struct mbox_sync_context *sync_ctx, bool dirty);
diff -r 3ec9ce7cd5e7 -r 54ef7dccdfc7 src/lib-storage/index/mbox/mbox-sync-update.c
--- a/src/lib-storage/index/mbox/mbox-sync-update.c	Sun Jul 08 19:46:31 2007 +0300
+++ b/src/lib-storage/index/mbox/mbox-sync-update.c	Sun Jul 08 19:57:09 2007 +0300
@@ -6,6 +6,7 @@
 #include "str.h"
 #include "message-parser.h"
 #include "index-storage.h"
+#include "index-sync-changes.h"
 #include "mbox-storage.h"
 #include "mbox-sync-private.h"
 
@@ -388,16 +389,16 @@ void mbox_sync_update_header(struct mbox
 
 	old_flags = ctx->mail.flags;
 
-	if (array_count(&ctx->sync_ctx->syncs) > 0) {
-		mbox_sync_apply_index_syncs(ctx->sync_ctx, &ctx->mail,
-					    &sync_type);
-
-		if ((old_flags & XSTATUS_FLAGS_MASK) !=


More information about the dovecot-cvs mailing list