[dovecot-cvs] dovecot/src/lib-storage/index index-mailbox-check.c, 1.8, 1.9 index-status.c, 1.32, 1.33 index-storage.h, 1.72, 1.73 index-sync.c, 1.37, 1.38

cras at dovecot.org cras at dovecot.org
Mon Jul 12 14:35:53 EEST 2004


Update of /home/cvs/dovecot/src/lib-storage/index
In directory talvi:/tmp/cvs-serv2470/lib-storage/index

Modified Files:
	index-mailbox-check.c index-status.c index-storage.h 
	index-sync.c 
Log Message:
Broke mailbox_sync() into iterator.



Index: index-mailbox-check.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mailbox-check.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- index-mailbox-check.c	27 Apr 2004 20:25:54 -0000	1.8
+++ index-mailbox-check.c	12 Jul 2004 11:35:51 -0000	1.9
@@ -9,31 +9,46 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 
+struct index_notify_file {
+	struct index_notify_file *next;
+
+	char *path;
+	time_t last_stamp;
+};
+
+struct index_notify_io {
+	struct index_notify_io *next;
+	struct io *io;
+	int fd;
+};
+
 static void check_timeout(void *context)
 {
 	struct index_mailbox *ibox = context;
-	struct index_autosync_file *file;
+	struct index_notify_file *file;
 	struct stat st;
-	int sync;
+	time_t last_check;
+	int notify;
 
 	/* check changes only when we can also notify of new mail */
-	if ((unsigned int) (ioloop_time - ibox->sync_last_check) <
-	    ibox->min_newmail_notify_interval)
+	last_check = I_MAX(ibox->sync_last_check, ibox->notify_last_check);
+	if ((unsigned int)(ioloop_time - last_check) <
+	    ibox->min_notify_interval)
 		return;
 
-	ibox->sync_last_check = ioloop_time;
+	ibox->notify_last_check = ioloop_time;
 
-	sync = ibox->autosync_pending;
-	for (file = ibox->autosync_files; file != NULL; file = file->next) {
+	notify = ibox->notify_pending;
+	for (file = ibox->notify_files; file != NULL; file = file->next) {
 		if (stat(file->path, &st) == 0 &&
 		    file->last_stamp != st.st_mtime)
 			file->last_stamp = st.st_mtime;
 	}
 
-	if (sync) {
-		ibox->box.sync(&ibox->box, ibox->autosync_flags);
-		ibox->sync_last_notify = ioloop_time;
-		ibox->autosync_pending = FALSE;
+	if (notify) {
+		ibox->notify_last_sent = ioloop_time;
+		ibox->notify_pending = FALSE;
+		ibox->notify_callback(&ibox->box, ibox->notify_context);
 	}
 }
 
@@ -41,24 +56,24 @@
 {
 	struct index_mailbox *ibox = context;
 
-	ibox->sync_last_check = ioloop_time;
-	if ((unsigned int) (ioloop_time - ibox->sync_last_notify) >=
-	    ibox->min_newmail_notify_interval) {
-		ibox->box.sync(&ibox->box, ibox->autosync_flags);
-		ibox->sync_last_notify = ioloop_time;
-                ibox->autosync_pending = FALSE;
+	ibox->notify_last_check = ioloop_time;
+	if ((unsigned int)(ioloop_time - ibox->notify_last_sent) >=
+	    ibox->min_notify_interval) {
+		ibox->notify_last_sent = ioloop_time;
+                ibox->notify_pending = FALSE;
+		ibox->notify_callback(&ibox->box, ibox->notify_context);
 	} else {
-		ibox->autosync_pending = TRUE;
+		ibox->notify_pending = TRUE;
 	}
 }
 
 void index_mailbox_check_add(struct index_mailbox *ibox,
 			     const char *path, int dir)
 {
-	struct index_autosync_file *file;
+	struct index_notify_file *file;
 	struct stat st;
 	struct io *io;
-	struct index_autosync_io *aio;
+	struct index_notify_io *aio;
 	int fd;
 
 	fd = open(path, O_RDONLY);
@@ -66,56 +81,56 @@
 		io = io_add(fd, dir ? IO_DIR_NOTIFY : IO_FILE_NOTIFY,
 			    notify_callback, ibox);
 		if (io != NULL) {
-			aio = i_new(struct index_autosync_io, 1);
+			aio = i_new(struct index_notify_io, 1);
 			aio->io = io;
 			aio->fd = fd;
-			aio->next = ibox->autosync_ios;
-			ibox->autosync_ios = aio;
+			aio->next = ibox->notify_ios;
+			ibox->notify_ios = aio;
 		}
 	}
 
-	file = i_new(struct index_autosync_file, 1);
+	file = i_new(struct index_notify_file, 1);
 	file->path = i_strdup(path);
 	if (fd < 0)
 		file->last_stamp = stat(path, &st) < 0 ? 0 : st.st_mtime;
 	else
 		file->last_stamp = fstat(fd, &st) < 0 ? 0 : st.st_mtime;
 
-	file->next = ibox->autosync_files;
-        ibox->autosync_files = file;
+	file->next = ibox->notify_files;
+        ibox->notify_files = file;
 
-	if (ibox->autosync_to == NULL)
-		ibox->autosync_to = timeout_add(1000, check_timeout, ibox);
+	if (ibox->notify_to == NULL)
+		ibox->notify_to = timeout_add(1000, check_timeout, ibox);
 }
 
 void index_mailbox_check_remove_all(struct index_mailbox *ibox)
 {
-	struct index_autosync_file *file;
-	struct index_autosync_io *aio;
+	struct index_notify_file *file;
+	struct index_notify_io *aio;
 
 	/* reset notify stamp */
-	ibox->sync_last_notify = 0;
+	ibox->notify_last_sent = 0;
 
-	while (ibox->autosync_files != NULL) {
-		file = ibox->autosync_files;
-		ibox->autosync_files = file->next;
+	while (ibox->notify_files != NULL) {
+		file = ibox->notify_files;
+		ibox->notify_files = file->next;
 
                 i_free(file->path);
 		i_free(file);
 	}
 
-	while (ibox->autosync_ios != NULL) {
-		aio = ibox->autosync_ios;
-		ibox->autosync_ios = aio->next;
+	while (ibox->notify_ios != NULL) {
+		aio = ibox->notify_ios;
+		ibox->notify_ios = aio->next;
 
 		io_remove(aio->io);
 		if (close(aio->fd) < 0)
-			i_error("close(autosync_io) failed: %m");
+			i_error("close(notify_io) failed: %m");
 		i_free(aio);
 	}
 
-	if (ibox->autosync_to != NULL) {
-		timeout_remove(ibox->autosync_to);
-		ibox->autosync_to = NULL;
+	if (ibox->notify_to != NULL) {
+		timeout_remove(ibox->notify_to);
+		ibox->notify_to = NULL;
 	}
 }

Index: index-status.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-status.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- index-status.c	11 Jul 2004 21:04:46 -0000	1.32
+++ index-status.c	12 Jul 2004 11:35:51 -0000	1.33
@@ -3,10 +3,6 @@
 #include "lib.h"
 #include "index-storage.h"
 
-#define STATUS_MESSAGE_COUNTS \
-	(STATUS_MESSAGES | STATUS_RECENT | STATUS_UIDNEXT | \
-	 STATUS_UIDVALIDITY | STATUS_UNSEEN | STATUS_FIRST_UNSEEN_SEQ)
-
 /*static void
 get_keywords(struct mail_keywords *mcf, struct mailbox_status *status)
 {
@@ -21,44 +17,47 @@
 		status->keywords[i] = t_strdup(flags[i]);
 }*/
 
-int index_storage_get_status(struct mailbox *box,
-			     enum mailbox_status_items items,
-			     struct mailbox_status *status)
+int index_storage_get_status_locked(struct index_mailbox *ibox,
+				    enum mailbox_status_items items,
+				    struct mailbox_status *status_r)
 {
-	struct index_mailbox *ibox = (struct index_mailbox *) box;
 	const struct mail_index_header *hdr;
 
-	memset(status, 0, sizeof(struct mailbox_status));
-
-	if ((items & STATUS_MESSAGE_COUNTS) != 0) {
-		/* sync mailbox to update message counts */
-		if (mailbox_sync(box, 0) < 0)
-			return -1;
-	}
+	memset(status_r, 0, sizeof(struct mailbox_status));
 
 	/* we can get most of the status items without any trouble */
 	if (mail_index_get_header(ibox->view, &hdr) < 0)
 		return -1;
-	if ((items & STATUS_MESSAGE_COUNTS) != 0) {
-		status->messages = hdr->messages_count;
-		status->recent = ibox->synced_recent_count;
-		status->unseen = hdr->messages_count - hdr->seen_messages_count;
-		status->uidvalidity = hdr->uid_validity;
-		status->uidnext = hdr->next_uid;
-	}
-	//FIXME:status->diskspace_full = ibox->nodiskspace;
+
+	status_r->messages = hdr->messages_count;
+	status_r->recent = ibox->synced_recent_count;
+	status_r->unseen =
+		hdr->messages_count - hdr->seen_messages_count;
+	status_r->uidvalidity = hdr->uid_validity;
+	status_r->uidnext = hdr->next_uid;
+	//FIXME:status_r->diskspace_full = ibox->nodiskspace;
 
 	if (items & STATUS_FIRST_UNSEEN_SEQ) {
 		if (mail_index_lookup_first(ibox->view, 0, MAIL_SEEN,
-					    &status->first_unseen_seq) < 0) {
+					    &status_r->first_unseen_seq) < 0) {
 			mail_storage_set_index_error(ibox);
 			return -1;
 		}
 	}
 
 	/*FIXME:if (items & STATUS_KEYWORDS)
-		get_keywords(ibox, status);*/
+		get_keywords(ibox, status_r);*/
+	return 0;
+}
+
+int index_storage_get_status(struct mailbox *box,
+			     enum mailbox_status_items items,
+			     struct mailbox_status *status)
+{
+	struct index_mailbox *ibox = (struct index_mailbox *)box;
+	int ret;
 
+	ret = index_storage_get_status_locked(ibox, items, status);
 	mail_index_view_unlock(ibox->view);
-	return 0;
+	return ret;
 }

Index: index-storage.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-storage.h,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -d -r1.72 -r1.73
--- index-storage.h	11 Jul 2004 21:04:46 -0000	1.72
+++ index-storage.h	12 Jul 2004 11:35:51 -0000	1.73
@@ -22,19 +22,6 @@
 	MAILBOX_LOCK_NOTIFY_MAILBOX_OVERRIDE
 };
 
-struct index_autosync_file {
-	struct index_autosync_file *next;
-
-	char *path;
-	time_t last_stamp;
-};
-
-struct index_autosync_io {
-	struct index_autosync_io *next;
-	struct io *io;
-	int fd;
-};
-
 struct index_storage {
 	struct mail_storage storage;
 
@@ -63,12 +50,13 @@
 	void (*mail_deinit)(struct index_mail *mail);
 	int (*is_recent)(struct index_mailbox *ibox, uint32_t uid);
 
-	struct timeout *autosync_to;
-	struct index_autosync_file *autosync_files;
-        struct index_autosync_io *autosync_ios;
-	enum mailbox_sync_flags autosync_flags;
-	time_t sync_last_check, sync_last_notify;
-	unsigned int min_newmail_notify_interval;
+	struct timeout *notify_to;
+	struct index_notify_file *notify_files;
+        struct index_notify_io *notify_ios;
+	time_t notify_last_check, notify_last_sent;
+	unsigned int min_notify_interval;
+	mailbox_notify_callback_t *notify_callback;
+	void *notify_context;
 
 	time_t next_lock_notify; /* temporary */
 	enum mailbox_lock_notify_type last_notify_type;
@@ -78,7 +66,8 @@
 
 	buffer_t *recent_flags;
 	uint32_t recent_flags_start_seq, recent_flags_count;
-	unsigned int synced_recent_count;
+	uint32_t synced_recent_count;
+	time_t sync_last_check;
 
 	/* mbox: */
 	int mbox_fd;
@@ -106,7 +95,7 @@
 	unsigned int recent_flags_synced:1;
 	unsigned int sent_diskspace_warning:1;
 	unsigned int sent_readonly_flags_warning:1;
-	unsigned int autosync_pending:1;
+	unsigned int notify_pending:1;
 	unsigned int mail_read_mmaped:1;
 	unsigned int syncing_commit:1;
 };
@@ -164,6 +153,14 @@
 			     const char *path, int dir);
 void index_mailbox_check_remove_all(struct index_mailbox *ibox);
 
+struct mailbox_sync_context *
+index_mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags,
+			int failed);
+int index_mailbox_sync_next(struct mailbox_sync_context *ctx,
+			    struct mailbox_sync_rec *sync_rec_r);
+int index_mailbox_sync_deinit(struct mailbox_sync_context *ctx,
+			      struct mailbox_status *status_r);
+
 int index_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags);
 
 void index_storage_set_callbacks(struct mail_storage *storage,
@@ -174,6 +171,9 @@
 int index_storage_get_status(struct mailbox *box,
 			     enum mailbox_status_items items,
 			     struct mailbox_status *status);
+int index_storage_get_status_locked(struct index_mailbox *ibox,
+				    enum mailbox_status_items items,
+				    struct mailbox_status *status_r);
 
 struct mail *
 index_storage_fetch(struct mailbox_transaction_context *t, uint32_t seq,

Index: index-sync.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-sync.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- index-sync.c	11 Jul 2004 21:04:46 -0000	1.37
+++ index-sync.c	12 Jul 2004 11:35:51 -0000	1.38
@@ -4,6 +4,17 @@
 #include "buffer.h"
 #include "index-storage.h"
 
+struct index_mailbox_sync_context {
+	struct mailbox_sync_context ctx;
+	struct index_mailbox *ibox;
+	struct mail_index_view_sync_ctx *sync_ctx;
+	uint32_t messages_count;
+
+	const uint32_t *expunges;
+	size_t expunges_count;
+	int failed;
+};
+
 void index_mailbox_set_recent(struct index_mailbox *ibox, uint32_t seq)
 {
 	unsigned char *p;
@@ -97,124 +108,142 @@
 	return 0;
 }
 
-int index_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags)
+struct mailbox_sync_context *
+index_mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags,
+			int failed)
 {
 	struct index_mailbox *ibox = (struct index_mailbox *)box;
-	struct mail_index_view_sync_ctx *ctx;
-        struct mail_full_flags full_flags;
-	const struct mail_index_record *rec;
-	struct mail_index_sync_rec sync;
-	struct mail_storage_callbacks *sc;
-	const uint32_t *expunges;
-	size_t i, expunges_count;
-	void *sc_context;
+        struct index_mailbox_sync_context *ctx;
 	enum mail_index_sync_type sync_mask;
-	uint32_t seq, seq1, seq2;
-	uint32_t messages_count, last_messages_count;
-	int ret;
+
+	ctx = i_new(struct index_mailbox_sync_context, 1);
+	ctx->ctx.box = box;
+	ctx->ibox = ibox;
+
+	if (failed) {
+		ctx->failed = TRUE;
+		return &ctx->ctx;
+	}
+
+	ctx->messages_count = mail_index_view_get_message_count(ibox->view);
 
 	sync_mask = MAIL_INDEX_SYNC_MASK_ALL;
 	if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) != 0)
 		sync_mask &= ~MAIL_INDEX_SYNC_TYPE_EXPUNGE;
 
-	if (mail_index_view_sync_begin(ibox->view, sync_mask, &ctx) < 0) {
-                mail_storage_set_index_error(ibox);
-		return -1;
+	if (mail_index_view_sync_begin(ibox->view, sync_mask,
+				       &ctx->sync_ctx) < 0) {
+		mail_storage_set_index_error(ibox);
+		ctx->failed = TRUE;
+		return &ctx->ctx;
 	}
 
-	last_messages_count = mail_index_view_get_message_count(ibox->view);
-
 	if (!ibox->recent_flags_synced) {
 		ibox->recent_flags_synced = TRUE;
-                index_mailbox_update_recent(ibox, 1, last_messages_count);
+                index_mailbox_update_recent(ibox, 1, ctx->messages_count);
 	}
 
-	if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) != 0) {
-		expunges_count = 0;
-		expunges = NULL;
-	} else {
-		expunges =
-			mail_index_view_sync_get_expunges(ctx, &expunges_count);
+	if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) == 0) {
+		ctx->expunges =
+			mail_index_view_sync_get_expunges(ctx->sync_ctx,
+							  &ctx->expunges_count);
 	}
+	return &ctx->ctx;
+}
 
-	sc = ibox->storage->callbacks;
-	sc_context = ibox->storage->callback_context;
+int index_mailbox_sync_next(struct mailbox_sync_context *_ctx,
+			    struct mailbox_sync_rec *sync_rec_r)
+{
+	struct index_mailbox_sync_context *ctx =
+		(struct index_mailbox_sync_context *)_ctx;
+	struct mail_index_sync_rec sync;
+	int ret;
 
-	memset(&full_flags, 0, sizeof(full_flags));
-	while ((ret = mail_index_view_sync_next(ctx, &sync)) > 0) {
+	if (ctx->failed)
+		return -1;
+
+	while ((ret = mail_index_view_sync_next(ctx->sync_ctx, &sync)) > 0) {
 		switch (sync.type) {
 		case MAIL_INDEX_SYNC_TYPE_APPEND:
+			/* not interested */
 			break;
 		case MAIL_INDEX_SYNC_TYPE_EXPUNGE:
 			/* later */
 			break;
 		case MAIL_INDEX_SYNC_TYPE_FLAGS:
-			if (sc->update_flags == NULL)
-				break;
-
 			/* FIXME: hide the flag updates for expunged messages */
-
-			if (mail_index_lookup_uid_range(ibox->view,
-							sync.uid1, sync.uid2,
-							&seq1, &seq2) < 0) {
-				ret = -1;
-				break;
+			if (mail_index_lookup_uid_range(ctx->ibox->view,
+						sync.uid1, sync.uid2,
+						&sync_rec_r->seq1,
+						&sync_rec_r->seq2) < 0) {
+				ctx->failed = TRUE;
+				return -1;
 			}
 
-			if (seq1 == 0)
+			if (sync_rec_r->seq1 == 0)
 				break;
 
-			for (seq = seq1; seq <= seq2; seq++) {
-				if (mail_index_lookup(ibox->view,
-						      seq, &rec) < 0) {
-					ret = -1;
-					break;
-				}
-				full_flags.flags = rec->flags; // FIXME
-				if (index_mailbox_is_recent(ibox, seq))
-					full_flags.flags |= MAIL_RECENT;
-				sc->update_flags(&ibox->box, seq,
-						 &full_flags, sc_context);
-			}
-			break;
+			sync_rec_r->type = MAILBOX_SYNC_TYPE_FLAGS;
+			return 1;
 		}
 	}
 
-	if (ret < 0)
-		mail_storage_set_index_error(ibox);
-
-	if (sc->expunge != NULL) {
+	if (ret == 0 && ctx->expunges_count > 0) {
 		/* expunges[] is a sorted array of sequences. it's easiest for
 		   us to print them from end to beginning. */
-		messages_count = mail_index_view_get_message_count(ibox->view);
-		for (i = expunges_count*2; i > 0; i -= 2) {
-			seq = expunges[i-1];
-			index_mailbox_expunge_recent(ibox, expunges[i-2], seq);
-			if (seq > messages_count)
-				seq = messages_count;
-			for (; seq >= expunges[i-2]; seq--) {
-				sc->expunge(&ibox->box, seq, sc_context);
-				last_messages_count--;
-			}
-		}
-	}
+		sync_rec_r->seq1 = ctx->expunges[ctx->expunges_count*2-2];
+		sync_rec_r->seq2 = ctx->expunges[ctx->expunges_count*2-1];
+		index_mailbox_expunge_recent(ctx->ibox, sync_rec_r->seq1,
+					     sync_rec_r->seq2);
 
-	mail_index_view_sync_end(ctx);
+		if (sync_rec_r->seq2 > ctx->messages_count)
+			sync_rec_r->seq2 = ctx->messages_count;
 
-	messages_count = mail_index_view_get_message_count(ibox->view);
-	if (messages_count != last_messages_count) {
-		index_mailbox_update_recent(ibox, last_messages_count+1,
-					    messages_count);
-		sc->message_count_changed(&ibox->box, messages_count,
-					  sc_context);
+		ctx->messages_count -= sync_rec_r->seq2 - sync_rec_r->seq1 + 1;
+		ctx->expunges_count--;
+
+		sync_rec_r->type = MAILBOX_SYNC_TYPE_EXPUNGE;
+		return 1;
 	}
 
-	if (ibox->recent_flags_count != ibox->synced_recent_count) {
-                ibox->synced_recent_count = ibox->recent_flags_count;
-		sc->recent_count_changed(&ibox->box, ibox->synced_recent_count,
-					 sc_context);
+	if (ret < 0)
+		mail_storage_set_index_error(ctx->ibox);
+	return ret;
+}
+
+#define SYNC_STATUS_FLAGS \
+	(STATUS_MESSAGES | STATUS_RECENT | STATUS_UIDNEXT | \
+	 STATUS_UIDVALIDITY | STATUS_UNSEEN | STATUS_KEYWORDS)
+
+int index_mailbox_sync_deinit(struct mailbox_sync_context *_ctx,
+			      struct mailbox_status *status_r)
+{
+	struct index_mailbox_sync_context *ctx =
+		(struct index_mailbox_sync_context *)_ctx;
+	struct index_mailbox *ibox = ctx->ibox;
+	uint32_t messages_count;
+	int ret = ctx->failed ? -1 : 0;
+
+	if (ctx->sync_ctx != NULL)
+		mail_index_view_sync_end(ctx->sync_ctx);
+
+	if (ret == 0) {
+		messages_count = mail_index_view_get_message_count(ibox->view);
+		if (messages_count != ctx->messages_count) {
+			index_mailbox_update_recent(ibox,
+						    ctx->messages_count+1,
+						    messages_count);
+		}
+
+		if (ibox->recent_flags_count != ibox->synced_recent_count)
+			ibox->synced_recent_count = ibox->recent_flags_count;
+
+		ret = index_storage_get_status_locked(ctx->ibox,
+						      SYNC_STATUS_FLAGS,
+						      status_r);
 	}
 
-	mail_index_view_unlock(ibox->view);
+	mail_index_view_unlock(ctx->ibox->view);
+	i_free(ctx);
 	return ret;
 }



More information about the dovecot-cvs mailing list