[dovecot-cvs] dovecot/src/lib-storage/index/maildir maildir-sync.c,
1.57, 1.58
cras at dovecot.org
cras at dovecot.org
Wed Jun 29 01:32:40 EEST 2005
- Previous message: [dovecot-cvs] dovecot/src/lib-index mail-index-sync-ext.c, 1.6,
1.7 mail-index-sync.c, 1.60, 1.61 mail-index-transaction.c,
1.63, 1.64 mail-index.c, 1.201, 1.202
- Next message: [dovecot-cvs]
dovecot/src/lib-storage/index/maildir Makefile.am, 1.3,
1.4 maildir-copy.c, 1.36, 1.37 maildir-keywords.c, NONE,
1.1 maildir-keywords.h, NONE, 1.1 maildir-save.c, 1.51,
1.52 maildir-storage.c, 1.100, 1.101 maildir-storage.h, 1.39,
1.40 maildir-sync.c, 1.58, 1.59 maildir-uidlist.c, 1.37,
1.38 maildir-uidlist.h, 1.13, 1.14 maildir-util.c, 1.12, 1.13
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /var/lib/cvs/dovecot/src/lib-storage/index/maildir
In directory talvi:/tmp/cvs-serv15869/lib-storage/index/maildir
Modified Files:
maildir-sync.c
Log Message:
Merge changes from multiple index sync records into one before actually
renaming maildir files.
Index: maildir-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/maildir/maildir-sync.c,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -d -r1.57 -r1.58
--- maildir-sync.c 16 Jun 2005 19:46:59 -0000 1.57
+++ maildir-sync.c 28 Jun 2005 22:32:38 -0000 1.58
@@ -211,7 +211,7 @@
struct mail_index_sync_ctx *sync_ctx;
struct mail_index_transaction *trans;
- struct mail_index_sync_rec sync_rec;
+ array_t ARRAY_DEFINE(sync_recs, struct mail_index_sync_rec);
uint32_t seq;
int dirty_state;
};
@@ -235,18 +235,39 @@
void *context)
{
struct maildir_index_sync_context *ctx = context;
+ const struct mail_index_sync_rec *recs;
const char *newpath;
enum mail_flags flags;
const char *const *keywords;
+ unsigned int i, count;
uint8_t flags8;
ctx->dirty_state = 0;
(void)maildir_filename_get_flags(path, pool_datastack_create(),
&flags, &keywords);
-
flags8 = flags;
- mail_index_sync_flags_apply(&ctx->sync_rec, &flags8);
+
+ recs = array_get_modifyable(&ctx->sync_recs, &count);
+ for (i = 0; i < count; i++) {
+ if (recs[i].uid1 != ctx->seq)
+ break;
+
+ switch (recs[i].type) {
+ case MAIL_INDEX_SYNC_TYPE_FLAGS:
+ mail_index_sync_flags_apply(&recs[i], &flags8);
+ break;
+ case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD:
+ case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE:
+ case MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET:
+ /*FIXME:mail_index_sync_keywords_apply(&recs[i], &keywords);*/
+ break;
+ case MAIL_INDEX_SYNC_TYPE_APPEND:
+ case MAIL_INDEX_SYNC_TYPE_EXPUNGE:
+ i_unreached();
+ break;
+ }
+ }
newpath = maildir_filename_set_flags(path, flags8, keywords);
if (rename(path, newpath) == 0) {
@@ -270,68 +291,135 @@
return -1;
}
-static int maildir_sync_record(struct maildir_mailbox *mbox,
- struct maildir_index_sync_context *ctx)
+static int
+maildir_sync_record_commit_until(struct maildir_index_sync_context *ctx,
+ uint32_t last_seq)
{
- struct mail_index_sync_rec *sync_rec = &ctx->sync_rec;
- struct mail_index_view *view = ctx->view;
- uint32_t seq, seq1, seq2, uid;
-
- switch (sync_rec->type) {
- case MAIL_INDEX_SYNC_TYPE_APPEND:
- break;
- case MAIL_INDEX_SYNC_TYPE_EXPUNGE:
- /* make it go through sequences to avoid looping through huge
- holes in UID range */
- if (mail_index_lookup_uid_range(view, sync_rec->uid1,
- sync_rec->uid2,
- &seq1, &seq2) < 0)
- return -1;
+ struct mail_index_sync_rec *recs;
+ unsigned int i, count;
+ uint32_t seq, uid;
+ int expunged, flag_changed;
- if (seq1 == 0)
- break;
+ recs = array_get_modifyable(&ctx->sync_recs, &count);
+ for (seq = recs[0].uid1; seq <= last_seq; seq++) {
+ expunged = flag_changed = FALSE;
+ for (i = 0; i < count; i++) {
+ if (recs[i].uid1 > seq)
+ break;
- for (seq = seq1; seq <= seq2; seq++) {
- if (mail_index_lookup_uid(view, seq, &uid) < 0)
- return -1;
- if (maildir_file_do(mbox, uid, maildir_expunge,
- NULL) < 0)
- return -1;
+ i_assert(recs[i].uid1 == seq);
+ switch (recs[i].type) {
+ case MAIL_INDEX_SYNC_TYPE_EXPUNGE:
+ expunged = TRUE;
+ 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:
+ flag_changed = TRUE;
+ break;
+ case MAIL_INDEX_SYNC_TYPE_APPEND:
+ i_unreached();
+ break;
+ }
}
- break;
- case MAIL_INDEX_SYNC_TYPE_FLAGS:
- if (mail_index_lookup_uid_range(view, sync_rec->uid1,
- sync_rec->uid2,
- &seq1, &seq2) < 0)
- return -1;
- if (seq1 == 0)
- break;
+ if (mail_index_lookup_uid(ctx->view, seq, &uid) < 0)
+ return -1;
- for (ctx->seq = seq1; ctx->seq <= seq2; ctx->seq++) {
- if (mail_index_lookup_uid(view, ctx->seq, &uid) < 0)
+ ctx->seq = seq;
+ if (expunged) {
+ if (maildir_file_do(ctx->mbox, uid,
+ maildir_expunge, ctx) < 0)
return -1;
- if (maildir_file_do(mbox, uid,
+ } else if (flag_changed) {
+ if (maildir_file_do(ctx->mbox, uid,
maildir_sync_flags, ctx) < 0)
return -1;
- if (ctx->dirty_state < 0) {
- /* flag isn't dirty anymore */
- mail_index_update_flags(ctx->trans, ctx->seq,
- MODIFY_REMOVE,
- MAIL_INDEX_MAIL_FLAG_DIRTY);
+ }
+
+ for (i = count; i > 0; i--) {
+ if (++recs[i-1].uid1 > recs[i-1].uid2) {
+ array_delete(&ctx->sync_recs, i-1, 1);
+ recs = array_get_modifyable(&ctx->sync_recs,
+ &count);
+ if (count == 0) {
+ /* all sync_recs committed */
+ return 0;
+ }
}
}
- break;
- case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD:
- case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE:
- case MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET:
- // FIXME
- break;
+ }
+ return 0;
+}
+
+static int maildir_sync_record(struct maildir_index_sync_context *ctx,
+ const struct mail_index_sync_rec *sync_rec)
+{
+ struct mail_index_view *view = ctx->view;
+ struct mail_index_sync_rec sync_copy;
+
+ if (sync_rec == NULL) {
+ /* deinit */
+ while (array_count(&ctx->sync_recs) > 0) {
+ if (maildir_sync_record_commit_until(ctx,
+ (uint32_t)-1) < 0)
+ return -1;
+ }
+ return 0;
+ }
+
+ if (sync_rec->type == MAIL_INDEX_SYNC_TYPE_APPEND)
+ return 0; /* ignore */
+
+ /* convert to sequences to avoid looping through huge holes in
+ UID range */
+ sync_copy = *sync_rec;
+ if (mail_index_lookup_uid_range(view, sync_rec->uid1,
+ sync_rec->uid2,
+ &sync_copy.uid1,
+ &sync_copy.uid2) < 0)
+ return -1;
+
+ while (array_count(&ctx->sync_recs) > 0) {
+ const struct mail_index_sync_rec *rec =
+ array_idx(&ctx->sync_recs, 0);
+
+ i_assert(rec->uid1 <= sync_copy.uid1);
+ if (rec->uid1 == sync_copy.uid1)
+ break;
+
+ if (maildir_sync_record_commit_until(ctx, sync_copy.uid1-1) < 0)
+ return -1;
}
+ array_append(&ctx->sync_recs, &sync_copy, 1);
return 0;
}
+static int maildir_sync_index_records(struct maildir_index_sync_context *ctx)
+{
+ struct mail_index_sync_rec sync_rec;
+ int ret;
+
+ ret = mail_index_sync_next(ctx->sync_ctx, &sync_rec);
+ if (ret <= 0)
+ return ret;
+
+ ARRAY_CREATE(&ctx->sync_recs, pool_datastack_create(),
+ struct mail_index_sync_rec, 32);
+ do {
+ if (maildir_sync_record(ctx, &sync_rec) < 0)
+ return -1;
+
+ ret = mail_index_sync_next(ctx->sync_ctx, &sync_rec);
+ } while (ret > 0);
+
+ if (maildir_sync_record(ctx, NULL) < 0)
+ return -1;
+ return ret;
+}
+
int maildir_sync_last_commit(struct maildir_mailbox *mbox)
{
struct maildir_index_sync_context ctx;
@@ -352,14 +440,8 @@
FALSE, FALSE);
if (ret > 0) {
ctx.trans = mail_index_transaction_begin(ctx.view, FALSE, TRUE);
-
- while ((ret = mail_index_sync_next(ctx.sync_ctx,
- &ctx.sync_rec)) > 0) {
- if (maildir_sync_record(mbox, &ctx) < 0) {
- ret = -1;
- break;
- }
- }
+ if (maildir_sync_index_records(&ctx) < 0)
+ ret = -1;
if (mail_index_transaction_commit(ctx.trans, &seq, &offset) < 0)
ret = -1;
if (mail_index_sync_commit(ctx.sync_ctx) < 0)
@@ -623,7 +705,7 @@
enum mail_flags flags;
const char *const *keywords;
uint32_t uid_validity, next_uid;
- int ret, full_rescan = FALSE;
+ int ret = 0, full_rescan = FALSE;
trans = mail_index_transaction_begin(view, FALSE, TRUE);
sync_ctx->trans = trans;
@@ -804,14 +886,9 @@
/* now, sync the index */
mbox->syncing_commit = TRUE;
- while ((ret = mail_index_sync_next(sync_ctx->sync_ctx,
- &sync_ctx->sync_rec)) > 0) {
- if (maildir_sync_record(mbox, sync_ctx) < 0) {
- ret = -1;
- break;
- }
- }
- mbox->syncing_commit = FALSE;
+ if (maildir_sync_index_records(sync_ctx) < 0)
+ ret = -1;
+ mbox->syncing_commit = FALSE;
if (mbox->dirty_cur_time == 0 &&
mbox->last_cur_mtime != (time_t)hdr->sync_stamp) {
- Previous message: [dovecot-cvs] dovecot/src/lib-index mail-index-sync-ext.c, 1.6,
1.7 mail-index-sync.c, 1.60, 1.61 mail-index-transaction.c,
1.63, 1.64 mail-index.c, 1.201, 1.202
- Next message: [dovecot-cvs]
dovecot/src/lib-storage/index/maildir Makefile.am, 1.3,
1.4 maildir-copy.c, 1.36, 1.37 maildir-keywords.c, NONE,
1.1 maildir-keywords.h, NONE, 1.1 maildir-save.c, 1.51,
1.52 maildir-storage.c, 1.100, 1.101 maildir-storage.h, 1.39,
1.40 maildir-sync.c, 1.58, 1.59 maildir-uidlist.c, 1.37,
1.38 maildir-uidlist.h, 1.13, 1.14 maildir-util.c, 1.12, 1.13
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list