[dovecot-cvs] dovecot/src/lib-index Makefile.am, 1.25, 1.26 mail-index-sync.c, 1.48, 1.49 mail-transaction-log-private.h, 1.7, 1.8 mail-transaction-log.c, 1.85, 1.86

cras at dovecot.org cras at dovecot.org
Tue Feb 8 14:28:14 EET 2005


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

Modified Files:
	Makefile.am mail-index-sync.c mail-transaction-log-private.h 
	mail-transaction-log.c 
Log Message:
Moved code into mail-transaction-log-append.c



Index: Makefile.am
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/Makefile.am,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- Makefile.am	22 Jan 2005 16:56:37 -0000	1.25
+++ Makefile.am	8 Feb 2005 12:28:12 -0000	1.26
@@ -25,6 +25,7 @@
         mail-index-view.c \
         mail-index-view-sync.c \
         mail-transaction-log.c \
+        mail-transaction-log-append.c \
         mail-transaction-log-view.c \
         mail-transaction-util.c
 

Index: mail-index-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync.c,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -d -r1.48 -r1.49
--- mail-index-sync.c	5 Feb 2005 18:05:24 -0000	1.48
+++ mail-index-sync.c	8 Feb 2005 12:28:12 -0000	1.49
@@ -44,6 +44,52 @@
 	}
 }
 
+static void mail_index_sync_add_keyword_update(struct mail_index_sync_ctx *ctx)
+{
+	const struct mail_transaction_keyword_update *u = ctx->data;
+	const char *keyword_names[2];
+	struct mail_keywords *keywords;
+	const uint32_t *uids;
+	uint32_t uid;
+	size_t uidset_offset, i, size;
+
+	uidset_offset = sizeof(*u) + u->name_size;
+	if ((uidset_offset % 4) != 0)
+		uidset_offset += 4 - (uidset_offset % 4);
+	uids = CONST_PTR_OFFSET(u, uidset_offset);
+
+	t_push();
+	keyword_names[0] = t_strndup(u + 1, u->name_size);
+	keyword_names[1] = NULL;
+	keywords = mail_index_keywords_create(ctx->trans, keyword_names);
+
+	size = (ctx->hdr->size - uidset_offset) / sizeof(uint32_t);
+	for (i = 0; i < size; i += 2) {
+		/* FIXME: mail_index_update_keywords_range() */
+		for (uid = uids[i]; uid <= uids[i+1]; uid++) {
+			mail_index_update_keywords(ctx->trans, uid,
+						   u->modify_type, keywords);
+		}
+	}
+
+	mail_index_keywords_free(keywords);
+	t_pop();
+}
+
+static void mail_index_sync_add_keyword_reset(struct mail_index_sync_ctx *ctx)
+{
+	const struct mail_transaction_keyword_reset *u = ctx->data;
+	size_t i, size = ctx->hdr->size / sizeof(*u);
+	uint32_t uid;
+
+	for (i = 0; i < size; i++) {
+		for (uid = u[i].uid1; uid <= u[i].uid2; uid++) {
+			mail_index_update_keywords(ctx->trans, uid,
+						   MODIFY_REPLACE, NULL);
+		}
+	}
+}
+
 static void mail_index_sync_add_append(struct mail_index_sync_ctx *ctx)
 {
 	const struct mail_index_record *rec = ctx->data;
@@ -67,6 +113,12 @@
 	case MAIL_TRANSACTION_FLAG_UPDATE:
                 mail_index_sync_add_flag_update(ctx);
 		break;
+	case MAIL_TRANSACTION_KEYWORD_UPDATE:
+                mail_index_sync_add_keyword_update(ctx);
+		break;
+	case MAIL_TRANSACTION_KEYWORD_RESET:
+                mail_index_sync_add_keyword_reset(ctx);
+		break;
 	case MAIL_TRANSACTION_APPEND:
 		mail_index_sync_add_append(ctx);
 		break;

Index: mail-transaction-log-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-transaction-log-private.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- mail-transaction-log-private.h	16 Jan 2005 19:18:24 -0000	1.7
+++ mail-transaction-log-private.h	8 Feb 2005 12:28:12 -0000	1.8
@@ -52,4 +52,8 @@
 
 void mail_transaction_logs_clean(struct mail_transaction_log *log);
 
+int mail_transaction_log_rotate(struct mail_transaction_log *log, int lock);
+int mail_transaction_log_lock_head(struct mail_transaction_log *log);
+void mail_transaction_log_file_unlock(struct mail_transaction_log_file *file);
+
 #endif

Index: mail-transaction-log.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-transaction-log.c,v
retrieving revision 1.85
retrieving revision 1.86
diff -u -d -r1.85 -r1.86
--- mail-transaction-log.c	5 Feb 2005 12:01:49 -0000	1.85
+++ mail-transaction-log.c	8 Feb 2005 12:28:12 -0000	1.86
@@ -28,9 +28,6 @@
 static struct mail_transaction_log_file *
 mail_transaction_log_file_open_or_create(struct mail_transaction_log *log,
 					 const char *path);
-static int mail_transaction_log_rotate(struct mail_transaction_log *log,
-				       int lock_type);
-static int mail_transaction_log_lock_head(struct mail_transaction_log *log);
 
 void
 mail_transaction_log_file_set_corrupted(struct mail_transaction_log_file *file,
@@ -145,8 +142,7 @@
 	return -1;
 }
 
-static void
-mail_transaction_log_file_unlock(struct mail_transaction_log_file *file)
+void mail_transaction_log_file_unlock(struct mail_transaction_log_file *file)
 {
 	int ret;
 
@@ -550,8 +546,7 @@
 		log->head = NULL;
 }
 
-static int
-mail_transaction_log_rotate(struct mail_transaction_log *log, int lock)
+int mail_transaction_log_rotate(struct mail_transaction_log *log, int lock)
 {
 	struct mail_transaction_log_file *file;
 	struct stat st;
@@ -892,7 +887,7 @@
 	return 1;
 }
 
-static int mail_transaction_log_lock_head(struct mail_transaction_log *log)
+int mail_transaction_log_lock_head(struct mail_transaction_log *log)
 {
 	struct mail_transaction_log_file *file;
 	int ret = 0;
@@ -934,446 +929,6 @@
 	return ret;
 }
 
-static int log_append_buffer(struct mail_transaction_log_file *file,
-			     const buffer_t *buf, const buffer_t *hdr_buf,
-			     enum mail_transaction_type type, int external)
-{
-	struct mail_transaction_header hdr;
-	const void *data, *hdr_data;
-	size_t size, hdr_data_size;
-	uint32_t hdr_size;
-
-	i_assert((type & MAIL_TRANSACTION_TYPE_MASK) != 0);
-
-	data = buffer_get_data(buf, &size);
-	if (size == 0)
-		return 0;
-
-	i_assert((size % 4) == 0);
-
-	if (hdr_buf != NULL) {
-		hdr_data = buffer_get_data(hdr_buf, &hdr_data_size);
-		i_assert((hdr_data_size % 4) == 0);
-	} else {
-		hdr_data = NULL;
-		hdr_data_size = 0;
-	}
-
-	memset(&hdr, 0, sizeof(hdr));
-	hdr.type = type;
-	if (type == MAIL_TRANSACTION_EXPUNGE)
-		hdr.type |= MAIL_TRANSACTION_EXPUNGE_PROT;
-	if (external)
-		hdr.type |= MAIL_TRANSACTION_EXTERNAL;
-
-	hdr_size =
-		mail_index_uint32_to_offset(sizeof(hdr) + size + hdr_data_size);
-	if (file->first_append_size == 0) {
-		/* size will be written later once everything is in disk */
-		file->first_append_size = hdr_size;
-	} else {
-		hdr.size = hdr_size;
-	}
-
-	if (pwrite_full(file->fd, &hdr, sizeof(hdr), file->sync_offset) < 0)
-		return -1;
-	file->sync_offset += sizeof(hdr);
-
-	if (hdr_data_size > 0) {
-		if (pwrite_full(file->fd, hdr_data, hdr_data_size,
-				file->sync_offset) < 0)
-			return -1;
-		file->sync_offset += hdr_data_size;
-	}
-
-	if (pwrite_full(file->fd, data, size, file->sync_offset) < 0)
-		return -1;
-	file->sync_offset += size;
-	return 0;
-}
-
-static const buffer_t *
-log_get_hdr_update_buffer(struct mail_index_transaction *t)
-{
-	buffer_t *buf;
-	struct mail_transaction_header_update u;
-	uint16_t offset;
-	int state = 0;
-
-	memset(&u, 0, sizeof(u));
-
-	buf = buffer_create_dynamic(pool_datastack_create(), 256);
-	for (offset = 0; offset <= sizeof(t->hdr_change); offset++) {
-		if (offset < sizeof(t->hdr_change) && t->hdr_mask[offset]) {
-			if (state == 0) {
-				u.offset = offset;
-				state++;
-			}
-		} else {
-			if (state > 0) {
-				u.size = offset - u.offset;
-				buffer_append(buf, &u, sizeof(uint16_t)*2);
-				buffer_append(buf, t->hdr_change + u.offset,
-					      u.size);
-				state = 0;
-			}
-		}
-	}
-	return buf;
-}
-
-static int log_append_ext_intro(struct mail_transaction_log_file *file,
-				struct mail_index_transaction *t,
-				uint32_t ext_id, uint32_t reset_id)
-{
-	const struct mail_index_ext *ext;
-        struct mail_transaction_ext_intro *intro;
-	buffer_t *buf;
-	uint32_t idx;
-	size_t size;
-
-	if (!mail_index_map_get_ext_idx(t->view->map, ext_id, &idx)) {
-		/* new extension */
-		idx = (uint32_t)-1;
-	}
-
-	ext = t->view->index->extensions->data;
-	ext += ext_id;
-
-	if (t->ext_resizes == NULL) {
-		intro = NULL;
-		size = 0;
-	} else {
-		intro = buffer_get_modifyable_data(t->ext_resizes, &size);
-		size /= sizeof(*intro);
-	}
-
-	buf = buffer_create_dynamic(pool_datastack_create(), 128);
-	if (ext_id < size && intro[ext_id].name_size != 0) {
-		/* we're resizing it */
-		intro += ext_id;
-
-		i_assert(intro->ext_id == idx);
-		intro->name_size = idx != (uint32_t)-1 ? 0 :
-			strlen(ext->name);
-		buffer_append(buf, intro, sizeof(*intro));
-	} else {
-		/* generate a new intro structure */
-		intro = buffer_append_space_unsafe(buf, sizeof(*intro));
-		intro->ext_id = idx;
-		intro->hdr_size = ext->hdr_size;
-		intro->record_size = ext->record_size;
-		intro->record_align = ext->record_align;
-		intro->name_size = idx != (uint32_t)-1 ? 0 :
-			strlen(ext->name);
-	}
-	if (reset_id != 0) {
-		/* we're going to reset this extension in this transaction */
-		intro->reset_id = reset_id;
-	} else if (idx != (uint32_t)-1) {
-		/* use the existing reset_id */
-		const struct mail_index_ext *map_ext =
-			t->view->map->extensions->data;
-		map_ext += idx;
-
-		intro->reset_id = map_ext->reset_id;
-	} else {
-		/* new extension, reset_id defaults to 0 */
-	}
-	buffer_append(buf, ext->name, intro->name_size);
-
-	if ((buf->used % 4) != 0)
-		buffer_append_zero(buf, 4 - (buf->used % 4));
-
-	return log_append_buffer(file, buf, NULL, MAIL_TRANSACTION_EXT_INTRO,
-				 t->external);
-}
-
-static int
-mail_transaction_log_append_ext_intros(struct mail_transaction_log_file *file,
-				       struct mail_index_transaction *t)
-{
-        const struct mail_transaction_ext_intro *resize;
-	struct mail_transaction_ext_reset ext_reset;
-	uint32_t ext_id, ext_count, update_count, resize_count, reset_count;
-	const uint32_t *reset;
-	const buffer_t *const *update;
-	buffer_t *buf;
-	size_t size;
-
-	if (t->ext_rec_updates == NULL) {
-		update = NULL;
-		update_count = 0;
-	} else {
-		update = buffer_get_data(t->ext_rec_updates, &size);
-		update_count = size / sizeof(*update);
-	}
-
-	if (t->ext_resizes == NULL) {
-		resize = NULL;
-		resize_count = 0;
-	} else {
-		resize = buffer_get_data(t->ext_resizes, &size);
-		resize_count = size / sizeof(*resize);
-	}
-
-	if (t->ext_resets == NULL) {
-		reset = NULL;
-		reset_count = 0;
-	} else {
-		reset = buffer_get_data(t->ext_resets, &size);
-		reset_count = size / sizeof(*reset);
-	}
-
-	memset(&ext_reset, 0, sizeof(ext_reset));
-
-	buf = buffer_create_data(pool_datastack_create(),
-				 &ext_reset, sizeof(ext_reset));
-	buffer_set_used_size(buf, sizeof(ext_reset));
-	ext_count = I_MAX(I_MAX(update_count, resize_count), reset_count);
-
-	for (ext_id = 0; ext_id < ext_count; ext_id++) {
-		ext_reset.new_reset_id =
-			ext_id < reset_count && reset[ext_id] != 0 ?
-			reset[ext_id] : 0;
-		if ((ext_id < resize_count && resize[ext_id].name_size) ||
-		    (ext_id < update_count && update[ext_id] != NULL) ||
-		    ext_reset.new_reset_id != 0) {
-			if (log_append_ext_intro(file, t, ext_id, 0) < 0)
-				return -1;
-		}
-		if (ext_reset.new_reset_id != 0) {
-			if (log_append_buffer(file, buf, NULL,
-					      MAIL_TRANSACTION_EXT_RESET,
-					      t->external) < 0)
-				return -1;
-		}
-	}
-
-	return 0;
-}
-
-static int log_append_ext_rec_updates(struct mail_transaction_log_file *file,
-				      struct mail_index_transaction *t)
-{
-	buffer_t **updates;
-	const uint32_t *reset;
-	uint32_t ext_id, reset_id, reset_count;
-	size_t size;
-
-	if (t->ext_rec_updates == NULL) {
-		updates = NULL;
-		size = 0;
-	} else {
-		updates = buffer_get_modifyable_data(t->ext_rec_updates, &size);
-		size /= sizeof(*updates);
-	}
-
-	if (t->ext_resets == NULL) {
-		reset = NULL;
-		reset_count = 0;
-	} else {
-		reset = buffer_get_data(t->ext_resets, &size);
-		reset_count = size / sizeof(*reset);
-	}
-
-	for (ext_id = 0; ext_id < size; ext_id++) {
-		if (updates[ext_id] == NULL)
-			continue;
-
-		reset_id = ext_id < reset_count && reset[ext_id] != 0 ?
-			reset[ext_id] : 0;
-		if (log_append_ext_intro(file, t, ext_id, reset_id) < 0)
-			return -1;
-
-		if (log_append_buffer(file, updates[ext_id], NULL,
-				      MAIL_TRANSACTION_EXT_REC_UPDATE,
-				      t->external) < 0)
-			return -1;
-	}
-	return 0;
-}
-
-static int log_append_keyword_updates(struct mail_transaction_log_file *file,
-				      struct mail_index_transaction *t)
-{
-	struct mail_index *index = t->view->index;
-	struct mail_transaction_keyword_update kt_hdr;
-	buffer_t *hdr_buf, **buf;
-	size_t i, size;
-
-	hdr_buf = buffer_create_dynamic(pool_datastack_create(), 64);
-
-	buf = buffer_get_modifyable_data(t->keyword_updates, &size);
-	size /= sizeof(*buf);
-	for (i = 0; i < size; i++) {
-		if (buf[i] == NULL)
-			continue;
-
-		buffer_set_used_size(hdr_buf, 0);
-
-		memset(&kt_hdr, 0, sizeof(kt_hdr));
-		kt_hdr.modify_type = (i & 1) == 0 ? MODIFY_ADD : MODIFY_REMOVE;
-		kt_hdr.name_size = strlen(index->keywords[i / 2]);
-		buffer_append(hdr_buf, &kt_hdr, sizeof(kt_hdr));
-		buffer_append(hdr_buf, index->keywords[i / 2],
-			      kt_hdr.name_size);
-		if ((hdr_buf->used % 4) != 0)
-			buffer_append_zero(hdr_buf, 4 - (hdr_buf->used % 4));
-
-		if (log_append_buffer(file, buf[i], hdr_buf,
-				      MAIL_TRANSACTION_KEYWORD_UPDATE,
-				      t->external) < 0)
-			return -1;
-	}
-
-	return 0;
-}
-
-int mail_transaction_log_append(struct mail_index_transaction *t,
-				uint32_t *log_file_seq_r,
-				uoff_t *log_file_offset_r)
-{
-	struct mail_index_view *view = t->view;
-	struct mail_index *index;
-	struct mail_transaction_log *log;
-	struct mail_transaction_log_file *file;
-	struct mail_index_header idx_hdr;
-	uoff_t append_offset;
-	unsigned int lock_id;
-	int ret;
-
-	index = mail_index_view_get_index(view);
-	log = index->log;
-
-	if (!t->log_updates) {
-		/* nothing to append */
-		*log_file_seq_r = 0;
-		*log_file_offset_r = 0;
-		return 0;
-	}
-
-	if (log->index->log_locked) {
-		i_assert(t->external);
-	} else {
-		if (mail_transaction_log_lock_head(log) < 0)
-			return -1;
-
-		/* update sync_offset */
-		if (mail_transaction_log_file_map(log->head,
-						  log->head->sync_offset,
-						  (uoff_t)-1) < 0) {
-			mail_transaction_log_file_unlock(log->head);
-			return -1;
-		}
-	}
-
-	if (log->head->sync_offset > MAIL_TRANSACTION_LOG_ROTATE_SIZE &&
-	    log->head->last_mtime <
-	    ioloop_time - MAIL_TRANSACTION_LOG_ROTATE_MIN_TIME) {
-		/* we might want to rotate, but check first that everything is
-		   synced in index. */
-		if (mail_index_lock_shared(log->index, TRUE, &lock_id) < 0) {
-			if (!log->index->log_locked)
-				mail_transaction_log_file_unlock(log->head);
-			return -1;
-		}
-		idx_hdr = *log->index->hdr;
-		mail_index_unlock(log->index, lock_id);
-
-		if (log->head->hdr.file_seq == idx_hdr.log_file_seq &&
-		    log->head->sync_offset == idx_hdr.log_file_int_offset &&
-		    log->head->sync_offset == idx_hdr.log_file_ext_offset) {
-			if (mail_transaction_log_rotate(log, TRUE) < 0) {
-				/* that didn't work. well, try to continue
-				   anyway */
-			}
-		}
-	}
-
-	file = log->head;
-	file->first_append_size = 0;
-	append_offset = file->sync_offset;
-
-	ret = 0;
-
-	/* send all extension introductions and resizes before appends
-	   to avoid resize overhead as much as possible */
-        ret = mail_transaction_log_append_ext_intros(file, t);
-
-	if (t->appends != NULL && ret == 0) {
-		ret = log_append_buffer(file, t->appends, NULL,
-					MAIL_TRANSACTION_APPEND, t->external);
-	}
-	if (t->updates != NULL && ret == 0) {
-		ret = log_append_buffer(file, t->updates, NULL,
-					MAIL_TRANSACTION_FLAG_UPDATE,
-					t->external);
-	}
-
-	if (t->ext_rec_updates != NULL && ret == 0)
-		ret = log_append_ext_rec_updates(file, t);
-
-	/* keyword resets before updates */
-	if (t->keyword_resets != NULL && ret == 0) {
-		ret = log_append_buffer(file, t->keyword_resets, NULL,
-					MAIL_TRANSACTION_KEYWORD_RESET,
-					t->external);
-	}
-	if (t->keyword_updates != NULL && ret == 0)
-		ret = log_append_keyword_updates(file, t);
-
-	if (t->expunges != NULL && ret == 0) {
-		ret = log_append_buffer(file, t->expunges, NULL,
-					MAIL_TRANSACTION_EXPUNGE, t->external);
-	}
-	if (t->hdr_changed && ret == 0) {
-		ret = log_append_buffer(file, log_get_hdr_update_buffer(t),
-					NULL, MAIL_TRANSACTION_HEADER_UPDATE,
-					t->external);
-	}
-
-	if (ret < 0) {
-		mail_index_file_set_syscall_error(log->index, file->filepath,
-						  "pwrite()");
-	}
-
-	if (ret == 0 && (t->updates != NULL || t->appends != NULL) &&
-	    t->hide_transaction) {
-		mail_index_view_add_synced_transaction(view, file->hdr.file_seq,
-						       append_offset);
-	}
-
-	if (ret == 0 && fsync(file->fd) < 0) {
-		/* we don't know how much of it got written,
-		   it may be corrupted now.. */
-		mail_index_file_set_syscall_error(log->index, file->filepath,
-						  "fsync()");
-		ret = -1;
-	}
-
-	if (ret == 0 && file->first_append_size != 0) {
-		/* synced - rewrite first record's header */
-		ret = pwrite_full(file->fd, &file->first_append_size,
-				  sizeof(uint32_t), append_offset);
-		if (ret < 0) {
-			mail_index_file_set_syscall_error(log->index,
-							  file->filepath,
-							  "pwrite()");
-		}
-	}
-
-	if (ret < 0)
-		file->sync_offset = append_offset;
-
-	*log_file_seq_r = file->hdr.file_seq;
-	*log_file_offset_r = file->sync_offset;
-
-	if (!log->index->log_locked)
-		mail_transaction_log_file_unlock(file);
-	return ret;
-}
-
 int mail_transaction_log_sync_lock(struct mail_transaction_log *log,
 				   uint32_t *file_seq_r, uoff_t *file_offset_r)
 {



More information about the dovecot-cvs mailing list