[dovecot-cvs] dovecot/src/lib-index Makefile.am, 1.24, 1.25 mail-index-dummy-view.c, NONE, 1.1 mail-index-sync-private.h, 1.19, 1.20 mail-index-sync.c, 1.45, 1.46 mail-index-transaction.c, 1.43, 1.44 mail-index-view-private.h, 1.16, 1.17

cras at dovecot.org cras at dovecot.org
Sat Jan 22 18:56:39 EET 2005


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

Modified Files:
	Makefile.am mail-index-sync-private.h mail-index-sync.c 
	mail-index-transaction.c mail-index-view-private.h 
Added Files:
	mail-index-dummy-view.c 
Log Message:
Instead of using separate transaction sorting code for syncing, just put the
data from transactions into a temporary transaction and read it from there.



Index: Makefile.am
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/Makefile.am,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- Makefile.am	26 Dec 2004 09:12:40 -0000	1.24
+++ Makefile.am	22 Jan 2005 16:56:37 -0000	1.25
@@ -13,6 +13,7 @@
 	mail-cache-transaction.c \
 	mail-cache-sync-update.c \
         mail-index.c \
+        mail-index-dummy-view.c \
         mail-index-fsck.c \
         mail-index-lock.c \
         mail-index-transaction.c \

--- NEW FILE: mail-index-dummy-view.c ---
/* Copyright (C) 2004 Timo Sirainen */

#include "lib.h"
#include "mail-index-private.h"
#include "mail-index-view-private.h"

static void _dummy_view_close(struct mail_index_view *view __attr_unused__)
{
	i_assert(view->refcount == 0);

	i_free(view);
}

static uint32_t
_dummy_view_get_message_count(struct mail_index_view *view __attr_unused__)
{
	return (uint32_t)-3;
}

static struct mail_index_view_methods dummy_view_methods = {
	_dummy_view_close,
	_dummy_view_get_message_count,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL
};

struct mail_index_view *mail_index_dummy_view_open(void)
{
	struct mail_index_view *view;

	view = i_new(struct mail_index_view, 1);
	view->refcount = 1;
	view->methods = dummy_view_methods;
	return view;
}

Index: mail-index-sync-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync-private.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- mail-index-sync-private.h	10 Jan 2005 17:37:22 -0000	1.19
+++ mail-index-sync-private.h	22 Jan 2005 16:56:37 -0000	1.20
@@ -6,8 +6,7 @@
 struct mail_index_sync_ctx {
 	struct mail_index *index;
 	struct mail_index_view *view;
-
-	buffer_t *expunges_buf, *updates_buf;
+	struct mail_index_transaction *trans;
 
 	const struct mail_transaction_expunge *expunges;
 	const struct mail_transaction_flag_update *updates;

Index: mail-index-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -d -r1.45 -r1.46
--- mail-index-sync.c	26 Dec 2004 09:12:40 -0000	1.45
+++ mail-index-sync.c	22 Jan 2005 16:56:37 -0000	1.46
@@ -4,130 +4,73 @@
 #include "buffer.h"
 #include "mail-index-view-private.h"
 #include "mail-index-sync-private.h"
+#include "mail-index-transaction-private.h"
 #include "mail-transaction-log-private.h"
 #include "mail-transaction-util.h"
 #include "mail-cache.h"
 
 #include <stdlib.h>
 
-static void
-mail_index_sync_sort_flags(buffer_t *dest_buf,
-			   const struct mail_transaction_flag_update *src,
-			   size_t src_size)
+static void mail_index_sync_add_expunge(struct mail_index_sync_ctx *ctx)
 {
-	const struct mail_transaction_flag_update *src_end;
-	struct mail_transaction_flag_update *dest;
-	struct mail_transaction_flag_update new_update, tmp_update;
-	size_t i, dest_count;
-
-	dest = buffer_get_modifyable_data(dest_buf, &dest_count);
-	dest_count /= sizeof(*dest);
+	const struct mail_transaction_expunge *e = ctx->data;
+	size_t i, size = ctx->hdr->size / sizeof(*e);
+	uint32_t uid;
 
-	if (dest_count == 0) {
-		buffer_append(dest_buf, src, src_size);
-		return;
+	for (i = 0; i < size; i++) {
+		for (uid = e[i].uid1; uid <= e[i].uid2; uid++)
+			mail_index_expunge(ctx->trans, uid);
 	}
+}
 
-	src_end = PTR_OFFSET(src, src_size);
-	for (i = 0; src != src_end; src++) {
-		new_update = *src;
-
-		/* insert it into buffer, split and merge it with existing
-		   updates if needed. */
-		for (; i < dest_count; i++) {
-			if (new_update.uid1 > dest[i].uid2)
-				continue;
-
-			if (new_update.uid2 < dest[i].uid1)
-				break;
+static void mail_index_sync_add_flag_update(struct mail_index_sync_ctx *ctx)
+{
+	const struct mail_transaction_flag_update *u = ctx->data;
+	size_t i, size = ctx->hdr->size / sizeof(*u);
 
-			/* at least partially overlapping */
+	for (i = 0; i < size; i++) {
+		if (u[i].add_flags != 0) {
+			mail_index_update_flags_range(ctx->trans,
+						      u[i].uid1, u[i].uid2,
+						      MODIFY_ADD,
+						      u[i].add_flags);
+		}
+		if (u[i].remove_flags != 0) {
+			mail_index_update_flags_range(ctx->trans,
+						      u[i].uid1, u[i].uid2,
+						      MODIFY_REMOVE,
+						      u[i].remove_flags);
+		}
+	}
+}
 
-			if (new_update.uid1 < dest[i].uid1) {
-				/* { 5..6 } + { 1..5 } -> { 1..4 } + { 5..6 } */
-				tmp_update = new_update;
-				tmp_update.uid2 = dest[i].uid1-1;
-				new_update.uid1 = dest[i].uid1;
-				buffer_insert(dest_buf, i * sizeof(tmp_update),
-					      &tmp_update, sizeof(tmp_update));
-				dest = buffer_get_modifyable_data(dest_buf,
-								  NULL);
-				dest_count++; i++;
-			} else if (new_update.uid1 > dest[i].uid1) {
-				/* { 5..7 } + { 6..6 } ->
-				   split old to { 5..5 } + { 6..7 } */
-				tmp_update = dest[i];
-				tmp_update.uid2 = new_update.uid1-1;
-				dest[i].uid1 = new_update.uid1;
-				buffer_insert(dest_buf, i * sizeof(tmp_update),
-					      &tmp_update, sizeof(tmp_update));
-				dest = buffer_get_modifyable_data(dest_buf,
-								  NULL);
-				dest_count++; i++;
-			}
-			i_assert(new_update.uid1 == dest[i].uid1);
+static void mail_index_sync_add_append(struct mail_index_sync_ctx *ctx)
+{
+	const struct mail_index_record *rec = ctx->data;
 
-			if (new_update.uid2 < dest[i].uid2) {
-				/* { 5..7 } + { 5..6 } -> { 5..6 } + { 7..7 } */
-				tmp_update = dest[i];
-				tmp_update.uid1 = new_update.uid2+1;
-				dest[i].uid2 = new_update.uid2;
-				buffer_insert(dest_buf,
-					      (i+1) * sizeof(tmp_update),
-					      &tmp_update, sizeof(tmp_update));
-				dest = buffer_get_modifyable_data(dest_buf,
-								  NULL);
-				dest_count++;
-				new_update.uid2 = 0;
-			} else {
-				/* full match, or continues. */
-				new_update.uid1 = dest[i].uid2+1;
-			}
+	if (ctx->append_uid_first == 0 || rec->uid < ctx->append_uid_first)
+		ctx->append_uid_first = rec->uid;
 
-			/* dest[i] now contains the overlapping area.
-			   merge them - new_update overrides old changes. */
-			dest[i].add_flags |= new_update.add_flags;
-			dest[i].add_flags &= ~new_update.remove_flags;
-			dest[i].remove_flags |= new_update.remove_flags;
-			dest[i].remove_flags &= ~new_update.add_flags;
-		}
+	rec = CONST_PTR_OFFSET(ctx->data, ctx->hdr->size - sizeof(*rec));
+	if (rec->uid > ctx->append_uid_last)
+		ctx->append_uid_last = rec->uid;
 
-		if (new_update.uid1 <= new_update.uid2) {
-			buffer_insert(dest_buf, i * sizeof(new_update),
-				      &new_update, sizeof(new_update));
-			dest = buffer_get_modifyable_data(dest_buf, NULL);
-			dest_count++;
-		}
-	}
+	ctx->sync_appends = TRUE;
 }
 
-static void mail_index_sync_sort_transaction(struct mail_index_sync_ctx *ctx)
+static void mail_index_sync_add_transaction(struct mail_index_sync_ctx *ctx)
 {
 	switch (ctx->hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
 	case MAIL_TRANSACTION_EXPUNGE:
-		mail_transaction_log_sort_expunges(ctx->expunges_buf,
-						   ctx->data, ctx->hdr->size);
+		mail_index_sync_add_expunge(ctx);
 		break;
 	case MAIL_TRANSACTION_FLAG_UPDATE:
-		mail_index_sync_sort_flags(ctx->updates_buf, ctx->data,
-					   ctx->hdr->size);
+                mail_index_sync_add_flag_update(ctx);
 		break;
-	case MAIL_TRANSACTION_APPEND: {
-		const struct mail_index_record *rec = ctx->data;
-
-		if (ctx->append_uid_first == 0 ||
-		    rec->uid < ctx->append_uid_first)
-			ctx->append_uid_first = rec->uid;
-
-		rec = CONST_PTR_OFFSET(ctx->data,
-				       ctx->hdr->size - sizeof(*rec));
-		if (rec->uid > ctx->append_uid_last)
-			ctx->append_uid_last = rec->uid;
-
-                ctx->sync_appends = TRUE;
+	case MAIL_TRANSACTION_APPEND:
+		mail_index_sync_add_append(ctx);
 		break;
 	}
-	}
 }
 
 static int mail_index_sync_add_dirty_updates(struct mail_index_sync_ctx *ctx)
@@ -146,48 +89,26 @@
 		if ((rec->flags & MAIL_INDEX_MAIL_FLAG_DIRTY) == 0)
 			continue;
 
-		update.uid1 = update.uid2 = rec->uid;
-		update.add_flags = rec->flags;
-		update.remove_flags = ~update.add_flags;
-
-		mail_index_sync_sort_flags(ctx->updates_buf,
-					   &update, sizeof(update));
+		mail_index_update_flags(ctx->trans, rec->uid,
+					MODIFY_REPLACE, rec->flags);
 	}
 	return 0;
 }
 
 static int mail_index_sync_add_recent_updates(struct mail_index_sync_ctx *ctx)
 {
-	struct mail_transaction_flag_update update;
 	const struct mail_index_record *rec;
 	uint32_t seq, messages_count;
 
-	memset(&update, 0, sizeof(update));
-
 	messages_count = mail_index_view_get_messages_count(ctx->view);
 	for (seq = 1; seq <= messages_count; seq++) {
 		if (mail_index_lookup(ctx->view, seq, &rec) < 0)
 			return -1;
 
-		if ((rec->flags & MAIL_RECENT) == 0) {
-			if (update.uid1 != 0) {
-				mail_index_sync_sort_flags(ctx->updates_buf,
-							   &update,
-							   sizeof(update));
-				update.uid1 = 0;
-			}
-			continue;
+		if ((rec->flags & MAIL_RECENT) != 0) {
+			mail_index_update_flags(ctx->trans, rec->uid,
+						MODIFY_REMOVE, MAIL_RECENT);
 		}
-
-		/* group updates together as much as possible */
-		if (update.uid1 == 0)
-			update.uid1 = rec->uid;
-                update.uid2 = rec->uid;
-	}
-
-	if (update.uid1 != 0) {
-		mail_index_sync_sort_flags(ctx->updates_buf,
-					   &update, sizeof(update));
 	}
 	return 0;
 }
@@ -219,14 +140,21 @@
 		if ((ctx->hdr->type & MAIL_TRANSACTION_EXTERNAL) != 0)
 			*seen_external_r = TRUE;
 		 else
-			mail_index_sync_sort_transaction(ctx);
+			mail_index_sync_add_transaction(ctx);
 	}
 
-	ctx->expunges = buffer_get_data(ctx->expunges_buf, &size);
-	ctx->expunges_count = size / sizeof(*ctx->expunges);
-	ctx->updates = buffer_get_data(ctx->updates_buf, &size);
-	ctx->updates_count = size / sizeof(*ctx->updates);
-
+	if (ctx->trans->expunges == NULL)
+		ctx->expunges_count = 0;
+	else {
+		ctx->expunges = buffer_get_data(ctx->trans->expunges, &size);
+		ctx->expunges_count = size / sizeof(*ctx->expunges);
+	}
+	if (ctx->trans->updates == NULL)
+		ctx->updates_count = 0;
+	else {
+		ctx->updates = buffer_get_data(ctx->trans->updates, &size);
+		ctx->updates_count = size / sizeof(*ctx->updates);
+	}
 	return ret;
 }
 
@@ -284,6 +212,7 @@
 			  int sync_recent, int sync_dirty)
 {
 	struct mail_index_sync_ctx *ctx;
+	struct mail_index_view *dummy_view;
 	uint32_t seq;
 	uoff_t offset;
 	unsigned int lock_id = 0;
@@ -325,6 +254,10 @@
 
 	ctx->view = mail_index_view_open(index);
 
+	dummy_view = mail_index_dummy_view_open();
+	ctx->trans = mail_index_transaction_begin(dummy_view, FALSE, TRUE);
+	mail_index_view_close(dummy_view);
+
 	if (index->hdr->log_file_seq == seq &&
 	    index->hdr->log_file_int_offset > offset) {
 		/* synced offset is greater than what we have available.
@@ -378,8 +311,6 @@
 
 	/* we need to have all the transactions sorted to optimize
 	   caller's mailbox access patterns */
-	ctx->expunges_buf = buffer_create_dynamic(default_pool, 1024);
-	ctx->updates_buf = buffer_create_dynamic(default_pool, 1024);
 	if (mail_index_sync_read_and_sort(ctx, sync_recent,
 					  &seen_external) < 0) {
                 mail_index_sync_rollback(ctx);
@@ -497,14 +428,12 @@
 static void mail_index_sync_end(struct mail_index_sync_ctx *ctx)
 {
 	mail_index_unlock(ctx->index, ctx->lock_id);
-        i_assert(!ctx->index->map->write_to_disk);
+
+	i_assert(!ctx->index->map->write_to_disk);
 	mail_transaction_log_sync_unlock(ctx->index->log);
-	mail_index_view_close(ctx->view);
 
-	if (ctx->expunges_buf != NULL)
-		buffer_free(ctx->expunges_buf);
-	if (ctx->updates_buf != NULL)
-		buffer_free(ctx->updates_buf);
+	mail_index_view_close(ctx->view);
+	mail_index_transaction_rollback(ctx->trans);
 	i_free(ctx);
 }
 

Index: mail-index-transaction.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-transaction.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- mail-index-transaction.c	22 Jan 2005 16:45:24 -0000	1.43
+++ mail-index-transaction.c	22 Jan 2005 16:56:37 -0000	1.44
@@ -22,6 +22,7 @@
 
 	/* don't allow syncing view while there's ongoing transactions */
 	mail_index_view_transaction_ref(view);
+ 	mail_index_view_ref(view);
 
 	t = i_new(struct mail_index_transaction, 1);
 	t->refcount = 1;
@@ -66,8 +67,6 @@
 	buffer_t **recs;
 	size_t i, size;
 
-	mail_index_view_transaction_unref(t->view);
-
 	if (t->ext_rec_updates != NULL) {
 		recs = buffer_get_modifyable_data(t->ext_rec_updates, &size);
 		size /= sizeof(*recs);
@@ -100,6 +99,9 @@
 		buffer_free(t->ext_resizes);
 	if (t->ext_resets != NULL)
 		buffer_free(t->ext_resets);
+
+	mail_index_view_transaction_unref(t->view);
+	mail_index_view_close(t->view);
 	i_free(t);
 }
 

Index: mail-index-view-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-view-private.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- mail-index-view-private.h	28 Nov 2004 23:19:53 -0000	1.16
+++ mail-index-view-private.h	22 Jan 2005 16:56:37 -0000	1.17
@@ -54,7 +54,6 @@
 void mail_index_view_clone(struct mail_index_view *dest,
 			   const struct mail_index_view *src);
 void mail_index_view_ref(struct mail_index_view *view);
-void mail_index_view_unref(struct mail_index_view *view);
 int mail_index_view_lock(struct mail_index_view *view);
 int mail_index_view_lock_head(struct mail_index_view *view, int update_index);
 void mail_index_view_unref_maps(struct mail_index_view *view);
@@ -62,4 +61,6 @@
 					    uint32_t log_file_seq,
 					    uoff_t log_file_offset);
 
+struct mail_index_view *mail_index_dummy_view_open(void);
+
 #endif



More information about the dovecot-cvs mailing list