[dovecot-cvs] dovecot/src/lib-index mail-index-sync-private.h, 1.23, 1.24 mail-index-sync.c, 1.51, 1.52 mail-index-view-sync.c, 1.37, 1.38 mail-index.h, 1.143, 1.144 mail-transaction-util.c, 1.23, 1.24

cras at dovecot.org cras at dovecot.org
Mon Mar 14 22:48:27 EET 2005


Update of /var/lib/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv19675/lib-index

Modified Files:
	mail-index-sync-private.h mail-index-sync.c 
	mail-index-view-sync.c mail-index.h mail-transaction-util.c 
Log Message:
mail_index_sync_next() now returns keyword updates (now only thing left to
do is to fix maildir and mbox syncing to use them).



Index: mail-index-sync-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync-private.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- mail-index-sync-private.h	12 Mar 2005 18:16:29 -0000	1.23
+++ mail-index-sync-private.h	14 Mar 2005 20:48:25 -0000	1.24
@@ -8,18 +8,14 @@
 	struct mail_index_view *view;
 	struct mail_index_transaction *trans;
 
-	const struct mail_transaction_expunge *expunges;
-	const struct mail_transaction_flag_update *updates;
-	unsigned int expunges_count, updates_count;
-
-	uint32_t append_uid_first, append_uid_last;
-
 	const struct mail_transaction_header *hdr;
 	const void *data;
 
-	size_t expunge_idx, update_idx;
+	array_t ARRAY_DEFINE(sync_list, struct mail_index_sync_list);
 	uint32_t next_uid;
 
+	uint32_t append_uid_first, append_uid_last;
+
 	unsigned int lock_id;
 
 	unsigned int sync_appends:1;
@@ -27,6 +23,12 @@
 	unsigned int sync_dirty:1;
 };
 
+struct mail_index_sync_list {
+	const array_t *ARRAY_DEFINE(array, struct uid_range *);
+	unsigned int idx;
+	unsigned int keyword_num;
+};
+
 struct mail_index_expunge_handler {
 	mail_index_expunge_handler_t *handler;
 	void **context;

Index: mail-index-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync.c,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -r1.51 -r1.52
--- mail-index-sync.c	12 Mar 2005 18:16:29 -0000	1.51
+++ mail-index-sync.c	14 Mar 2005 20:48:25 -0000	1.52
@@ -11,6 +11,10 @@
 
 #include <stdlib.h>
 
+struct uid_range {
+	uint32_t uid1, uid2;
+};
+
 static void mail_index_sync_add_expunge(struct mail_index_sync_ctx *ctx)
 {
 	const struct mail_transaction_expunge *e = ctx->data;
@@ -181,6 +185,8 @@
 mail_index_sync_read_and_sort(struct mail_index_sync_ctx *ctx,
 			      int *seen_external_r)
 {
+        struct mail_index_sync_list *synclist;
+	unsigned int i, keyword_count;
 	int ret;
 
 	*seen_external_r = FALSE;
@@ -197,6 +203,7 @@
 			return -1;
 	}
 
+	/* read all transactions from log into a transaction in memory */
 	while ((ret = mail_transaction_log_view_next(ctx->view->log_view,
 						     &ctx->hdr,
 						     &ctx->data, NULL)) > 0) {
@@ -206,18 +213,35 @@
 			mail_index_sync_add_transaction(ctx);
 	}
 
-	if (!array_is_created(&ctx->trans->expunges))
-		ctx->expunges_count = 0;
-	else {
-		ctx->expunges = array_get(&ctx->trans->expunges,
-					  &ctx->expunges_count);
+	/* create an array containing all expunge, flag and keyword update
+	   arrays so we can easily go through all of the changes. */
+	keyword_count = !array_is_created(&ctx->trans->keyword_updates) ? 0 :
+		array_count(&ctx->trans->keyword_updates);
+	ARRAY_CREATE(&ctx->sync_list, default_pool,
+		     struct mail_index_sync_list, keyword_count + 2);
+
+	if (array_is_created(&ctx->trans->expunges)) {
+		synclist = array_modifyable_append(&ctx->sync_list);
+		synclist->array = &ctx->trans->expunges;
 	}
-	if (!array_is_created(&ctx->trans->updates))
-		ctx->updates_count = 0;
-	else {
-		ctx->updates = array_get(&ctx->trans->updates,
-					 &ctx->updates_count);
+
+	if (array_is_created(&ctx->trans->updates)) {
+		synclist = array_modifyable_append(&ctx->sync_list);
+		synclist->array = &ctx->trans->updates;
+	}
+
+	/* we must return resets before keyword additions or they get lost */
+	if (array_is_created(&ctx->trans->keyword_resets)) {
+		synclist = array_modifyable_append(&ctx->sync_list);
+		synclist->array = &ctx->trans->keyword_resets;
 	}
+
+	for (i = 0; i < keyword_count; i++) {
+		synclist = array_modifyable_append(&ctx->sync_list);
+		synclist->array = array_idx(&ctx->trans->keyword_updates, i);
+		synclist->keyword_num = i;
+	}
+
 	return ret;
 }
 
@@ -406,13 +430,35 @@
 	rec->remove_flags = update->remove_flags;
 }
 
+static void mail_index_sync_get_keyword_update(struct mail_index_sync_rec *rec,
+					       const struct uid_range *range,
+					       unsigned int num)
+{
+	rec->type = num % 2 == 0 ?
+		MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD :
+		MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE;
+	rec->uid1 = range->uid1;
+	rec->uid2 = range->uid2;
+	rec->keyword_idx = num / 2;
+}
+
+static void mail_index_sync_get_keyword_reset(struct mail_index_sync_rec *rec,
+					       const struct uid_range *range)
+{
+	rec->type = MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET;
+	rec->uid1 = range->uid1;
+	rec->uid2 = range->uid2;
+}
+
 static int mail_index_sync_rec_check(struct mail_index_view *view,
 				     struct mail_index_sync_rec *rec)
 {
 	switch (rec->type) {
 	case MAIL_INDEX_SYNC_TYPE_EXPUNGE:
 	case MAIL_INDEX_SYNC_TYPE_FLAGS:
-	case MAIL_INDEX_SYNC_TYPE_KEYWORDS:
+	case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD:
+	case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE:
+	case MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET:
 		if (rec->uid1 > rec->uid2 || rec->uid1 == 0) {
 			mail_transaction_log_view_set_corrupted(view->log_view,
 				"Broken UID range: %u..%u (type 0x%x)",
@@ -429,63 +475,85 @@
 int mail_index_sync_next(struct mail_index_sync_ctx *ctx,
 			 struct mail_index_sync_rec *sync_rec)
 {
-	const struct mail_transaction_expunge *next_exp;
-	const struct mail_transaction_flag_update *next_update;
+	struct mail_index_sync_list *sync_list;
+	const struct uid_range *uid_range = NULL;
+	unsigned int i, count, next_i;
+	uint32_t next_found_uid;
 
-	next_exp = ctx->expunge_idx == ctx->expunges_count ? NULL :
-		&ctx->expunges[ctx->expunge_idx];
-	next_update = ctx->update_idx == ctx->updates_count ? NULL :
-		&ctx->updates[ctx->update_idx];
+	next_i = (unsigned int)-1;
+	next_found_uid = (uint32_t)-1;
 
-	if (next_update != NULL &&
-	    (next_exp == NULL || next_update->uid1 < next_exp->uid1)) {
-		mail_index_sync_get_update(sync_rec, next_update);
-		if (next_exp != NULL && next_exp->uid1 <= next_update->uid2) {
-			/* it's overlapping with next expunge */
-			sync_rec->uid2 = next_exp->uid1-1;
-		}
+	/* FIXME: replace with a priority queue so we don't have to go
+	   through the whole list constantly. and remember to make sure that
+	   keyword resets are sent before adds! */
+	sync_list = array_get(&ctx->sync_list, &count);
+	for (i = 0; i < count; i++) {
+		if (!array_is_created(sync_list[i].array) ||
+		    sync_list[i].idx == array_count(sync_list[i].array))
+			continue;
 
-		if (sync_rec->uid1 < ctx->next_uid) {
-			/* overlapping with previous expunge */
-			if (ctx->next_uid > sync_rec->uid2) {
-				/* hide this update completely */
-				ctx->update_idx++;
-                                return mail_index_sync_next(ctx, sync_rec);
-			}
-			sync_rec->uid1 = ctx->next_uid;
+		uid_range = array_idx(sync_list[i].array, sync_list[i].idx);
+		if (uid_range->uid1 == ctx->next_uid) {
+			/* use this one. */
+			break;
+		}
+		if (uid_range->uid1 < next_found_uid) {
+			next_i = i;
+                        next_found_uid = uid_range->uid1;
 		}
-
-		i_assert(sync_rec->uid1 <= sync_rec->uid2);
-		ctx->update_idx++;
-		return mail_index_sync_rec_check(ctx->view, sync_rec);
 	}
 
-	if (next_exp != NULL) {
-		mail_index_sync_get_expunge(sync_rec, next_exp);
-		if (mail_index_sync_rec_check(ctx->view, sync_rec) < 0)
-			return -1;
-
-		ctx->expunge_idx++;
-		ctx->next_uid = next_exp->uid2+1;
-		return 1;
+	if (i == count) {
+		if (next_i == (unsigned int)-1) {
+			/* nothing left in sync_list */
+			if (ctx->sync_appends) {
+				ctx->sync_appends = FALSE;
+				sync_rec->type = MAIL_INDEX_SYNC_TYPE_APPEND;
+				sync_rec->uid1 = ctx->append_uid_first;
+				sync_rec->uid2 = ctx->append_uid_last;
+				return 1;
+			}
+			return 0;
+		}
+                ctx->next_uid = next_found_uid;
+		i = next_i;
+		uid_range = array_idx(sync_list[i].array, sync_list[i].idx);
 	}
 
-	if (ctx->sync_appends) {
-		ctx->sync_appends = FALSE;
-		sync_rec->type = MAIL_INDEX_SYNC_TYPE_APPEND;
-		sync_rec->uid1 = ctx->append_uid_first;
-		sync_rec->uid2 = ctx->append_uid_last;
-		return 1;
+	if (sync_list[i].array == &ctx->trans->expunges) {
+		mail_index_sync_get_expunge(sync_rec,
+			(const struct mail_transaction_expunge *)uid_range);
+	} else if (sync_list[i].array == &ctx->trans->updates) {
+		mail_index_sync_get_update(sync_rec,
+			(const struct mail_transaction_flag_update *)uid_range);
+	} else if (sync_list[i].array == &ctx->trans->keyword_resets) {
+		mail_index_sync_get_keyword_reset(sync_rec, uid_range);
+	} else {
+		mail_index_sync_get_keyword_update(sync_rec, uid_range,
+						   sync_list[i].keyword_num);
 	}
+	sync_list[i].idx++;
 
-	return 0;
+	if (mail_index_sync_rec_check(ctx->view, sync_rec) < 0)
+		return -1;
+	return 1;
 }
 
 int mail_index_sync_have_more(struct mail_index_sync_ctx *ctx)
 {
-	return (ctx->update_idx != ctx->updates_count) ||
-		(ctx->expunge_idx != ctx->expunges_count) ||
-		ctx->sync_appends;
+	struct mail_index_sync_list *sync_list;
+	unsigned int i, count;
+
+	if (ctx->sync_appends)
+		return TRUE;
+
+	sync_list = array_get(&ctx->sync_list, &count);
+	for (i = 0; i < count; i++) {
+		if (array_is_created(sync_list[i].array) &&
+		    sync_list[i].idx != array_count(sync_list[i].array))
+			return TRUE;
+	}
+	return FALSE;
 }
 
 static void mail_index_sync_end(struct mail_index_sync_ctx *ctx)

Index: mail-index-view-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-view-sync.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- mail-index-view-sync.c	12 Mar 2005 12:04:18 -0000	1.37
+++ mail-index-view-sync.c	14 Mar 2005 20:48:25 -0000	1.38
@@ -79,7 +79,8 @@
 
 #define MAIL_INDEX_VIEW_VISIBLE_SYNC_MASK \
 	(MAIL_TRANSACTION_EXPUNGE | MAIL_TRANSACTION_APPEND | \
-	 MAIL_TRANSACTION_FLAG_UPDATE | MAIL_TRANSACTION_KEYWORD_UPDATE)
+	 MAIL_TRANSACTION_FLAG_UPDATE | MAIL_TRANSACTION_KEYWORD_UPDATE | \
+	 MAIL_TRANSACTION_KEYWORD_RESET)
 
 int mail_index_view_sync_begin(struct mail_index_view *view,
                                enum mail_index_sync_type sync_mask,
@@ -297,12 +298,23 @@
 		}
 
 		uids = CONST_PTR_OFFSET(data, ctx->data_offset);
-		rec->type = MAIL_INDEX_SYNC_TYPE_KEYWORDS;
+		/* FIXME: this isn't exactly correct.. but no-one cares? */
+		rec->type = MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD;
 		rec->uid1 = uids[0];
 		rec->uid2 = uids[1];
 		ctx->data_offset += sizeof(uint32_t) * 2;
 		break;
 	}
+	case MAIL_TRANSACTION_KEYWORD_RESET: {
+		const struct mail_transaction_keyword_reset *reset =
+			CONST_PTR_OFFSET(data, ctx->data_offset);
+
+		rec->type = MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET;
+		rec->uid1 = reset->uid1;
+		rec->uid2 = reset->uid2;
+		ctx->data_offset += sizeof(*reset);
+		break;
+	}
 	default:
 		i_unreached();
 	}

Index: mail-index.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index.h,v
retrieving revision 1.143
retrieving revision 1.144
diff -u -d -r1.143 -r1.144
--- mail-index.h	5 Feb 2005 12:01:49 -0000	1.143
+++ mail-index.h	14 Mar 2005 20:48:25 -0000	1.144
@@ -107,10 +107,12 @@
 };
 
 enum mail_index_sync_type {
-	MAIL_INDEX_SYNC_TYPE_APPEND	= 0x01,
-	MAIL_INDEX_SYNC_TYPE_EXPUNGE	= 0x02,
-	MAIL_INDEX_SYNC_TYPE_FLAGS	= 0x04,
-	MAIL_INDEX_SYNC_TYPE_KEYWORDS	= 0x08
+	MAIL_INDEX_SYNC_TYPE_APPEND		= 0x01,
+	MAIL_INDEX_SYNC_TYPE_EXPUNGE		= 0x02,
+	MAIL_INDEX_SYNC_TYPE_FLAGS		= 0x04,
+	MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD	= 0x08,
+	MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE	= 0x10,
+	MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET	= 0x20
 };
 #define MAIL_INDEX_SYNC_MASK_ALL 0xff
 
@@ -121,6 +123,9 @@
 	/* MAIL_INDEX_SYNC_TYPE_FLAGS: */
 	uint8_t add_flags;
 	uint8_t remove_flags;
+
+	/* MAIL_INDEX_SYNC_TYPE_KEYWORDS: */
+	unsigned int keyword_idx;
 };
 
 struct mail_keywords;

Index: mail-transaction-util.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-transaction-util.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- mail-transaction-util.c	5 Feb 2005 12:01:49 -0000	1.23
+++ mail-transaction-util.c	14 Mar 2005 20:48:25 -0000	1.24
@@ -19,8 +19,11 @@
 	  sizeof(struct mail_transaction_ext_reset) },
 	{ MAIL_TRANSACTION_EXT_HDR_UPDATE, 0, 1 },
 	{ MAIL_TRANSACTION_EXT_REC_UPDATE, 0, 1 },
-	{ MAIL_TRANSACTION_KEYWORD_UPDATE, MAIL_INDEX_SYNC_TYPE_KEYWORDS, 1 },
-	{ MAIL_TRANSACTION_KEYWORD_RESET, 0, 1 },
+	{ MAIL_TRANSACTION_KEYWORD_UPDATE,
+	  MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD |
+	  MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE, 1 },
+	{ MAIL_TRANSACTION_KEYWORD_RESET,
+	  MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET, 1 },
 	{ 0, 0, 0 }
 };
 



More information about the dovecot-cvs mailing list