Mercurial > dovecot > original-hg > dovecot-1.2
diff src/lib-storage/index/index-sync.c @ 453:0f6fd6802265 HEAD
Modify log now stores the changes in ranges, so store 1:100 doesn't
generate 100 entries but just one. For single message changes this takes 8
bytes unneededly though, that could be fixed but for extra complexity so
I don't think it's worth it.
Also a change in sync-interface, expunge event no longer gets UID. It's not
currently needed and I don't see any rfcs/drafts wanting it either. It's
removed mostly because the log ranges makes it impossible to get it.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 20 Oct 2002 02:09:56 +0300 |
parents | b5d9ce840177 |
children | 7b140cb09a2e |
line wrap: on
line diff
--- a/src/lib-storage/index/index-sync.c Sat Oct 19 19:40:17 2002 +0300 +++ b/src/lib-storage/index/index-sync.c Sun Oct 20 02:09:56 2002 +0300 @@ -6,18 +6,35 @@ #include "mail-modifylog.h" #include "mail-custom-flags.h" -/* may leave the index locked */ -int index_storage_sync_index_if_possible(IndexMailbox *ibox) +static void index_storage_sync_size(IndexMailbox *ibox) { unsigned int messages, recent; - if (ibox->index->sync(ibox->index)) { + messages = ibox->index->get_header(ibox->index)->messages_count; + messages += mail_modifylog_get_expunge_count(ibox->index->modifylog); + + if (messages != ibox->synced_messages_count) { + i_assert(messages > ibox->synced_messages_count); + + /* new messages in mailbox */ + recent = index_storage_get_recent_count(ibox->index); + ibox->sync_callbacks.new_messages(&ibox->box, messages, recent, + ibox->sync_context); + ibox->synced_messages_count = messages; + } +} + +/* may leave the index locked */ +int index_storage_sync_index_if_possible(IndexMailbox *ibox, int sync_size) +{ + MailIndex *index = ibox->index; + + if (index->sync(index)) { /* reset every time it has worked */ ibox->sent_diskspace_warning = FALSE; } else { - if (!ibox->index->is_diskspace_error(ibox->index)) { - (void)ibox->index->set_lock(ibox->index, - MAIL_LOCK_UNLOCK); + if (!index->is_diskspace_error(index)) { + (void)index->set_lock(index, MAIL_LOCK_UNLOCK); return mail_storage_set_index_error(ibox); } @@ -28,29 +45,20 @@ &ibox->box, ibox->sync_context); } - index_reset_error(ibox->index); + index_reset_error(index); } /* notify about changes in mailbox size. */ - if (ibox->index->lock_type == MAIL_LOCK_UNLOCK) + if (index->lock_type == MAIL_LOCK_UNLOCK) return TRUE; /* no changes - must be no new mail either */ - messages = ibox->index->get_header(ibox->index)->messages_count; - messages += mail_modifylog_get_expunge_count(ibox->index->modifylog); - if (messages != ibox->synced_messages_count) { - i_assert(messages > ibox->synced_messages_count); - - /* new messages in mailbox */ - recent = index_storage_get_recent_count(ibox->index); - ibox->sync_callbacks.new_messages(&ibox->box, messages, recent, - ibox->sync_context); - ibox->synced_messages_count = messages; - } + if (sync_size) + index_storage_sync_size(ibox); /* notify changes in custom flags */ - if (mail_custom_flags_has_changes(ibox->index->custom_flags)) { + if (mail_custom_flags_has_changes(index->custom_flags)) { ibox->sync_callbacks.new_custom_flags(&ibox->box, - mail_custom_flags_list_get(ibox->index->custom_flags), + mail_custom_flags_list_get(index->custom_flags), MAIL_CUSTOM_FLAGS_COUNT, ibox->sync_context); } @@ -59,13 +67,13 @@ int index_storage_sync_modifylog(IndexMailbox *ibox) { - ModifyLogRecord *log; + const ModifyLogRecord *log; MailIndexRecord *rec; MailFlags flags; MailboxSyncCallbacks *sc; void *sc_context; const char **custom_flags; - unsigned int count, seq; + unsigned int count, seq, seq_count, i, first_flag_change, messages; /* show the log */ log = mail_modifylog_get_nonsynced(ibox->index->modifylog, &count); @@ -75,37 +83,69 @@ sc = &ibox->sync_callbacks; sc_context = ibox->sync_context; - custom_flags = mail_custom_flags_list_get(ibox->index->custom_flags); - for (; count > 0; count--, log++) { - if (log->seq > ibox->synced_messages_count) { + /* first show expunges. this makes it easier to deal with sequence + numbers. */ + messages = ibox->synced_messages_count; + first_flag_change = count; + for (i = 0; i < count; i++) { + if (log[i].seq1 > messages) { /* client doesn't know about this message yet */ continue; } - switch (log->type) { + switch (log[i].type) { case RECORD_TYPE_EXPUNGE: - sc->expunge(&ibox->box, log->seq, - log->uid, sc_context); - ibox->synced_messages_count--; + seq_count = (log[i].seq2 - log[i].seq1) + 1; + messages -= seq_count; + + for (; seq_count > 0; seq_count--) { + sc->expunge(&ibox->box, log[i].seq1, + sc_context); + } + break; + case RECORD_TYPE_FLAGS_CHANGED: + if (first_flag_change == count) + first_flag_change = i; + break; + } + } + + /* now show the flags */ + messages = ibox->synced_messages_count; + custom_flags = mail_custom_flags_list_get(ibox->index->custom_flags); + for (i = first_flag_change; i < count; i++) { + if (log[i].seq1 > messages) { + /* client doesn't know about this message yet */ + continue; + } + + switch (log[i].type) { + case RECORD_TYPE_EXPUNGE: + messages -= (log[i].seq2 - log[i].seq1) + 1; break; case RECORD_TYPE_FLAGS_CHANGED: rec = ibox->index->lookup_uid_range(ibox->index, - log->uid, log->uid, - &seq); - if (rec == NULL) - break; + log[i].uid1, + log[i].uid2, &seq); + while (rec != NULL && rec->uid <= log[i].uid2) { + flags = rec->msg_flags; + if (rec->uid >= ibox->index->first_recent_uid) + flags |= MAIL_RECENT; - flags = rec->msg_flags; - if (rec->uid >= ibox->index->first_recent_uid) - flags |= MAIL_RECENT; + sc->update_flags(&ibox->box, seq, rec->uid, + flags, custom_flags, + MAIL_CUSTOM_FLAGS_COUNT, + sc_context); - sc->update_flags(&ibox->box, log->seq, log->uid, flags, - custom_flags, MAIL_CUSTOM_FLAGS_COUNT, - sc_context); + seq++; + rec = ibox->index->next(ibox->index, rec); + } break; } } + ibox->synced_messages_count = messages; + /* mark synced */ if (!mail_modifylog_mark_synced(ibox->index->modifylog)) return mail_storage_set_index_error(ibox); @@ -118,7 +158,7 @@ IndexMailbox *ibox = (IndexMailbox *) box; int failed; - if (!index_storage_sync_index_if_possible(ibox)) + if (!index_storage_sync_index_if_possible(ibox, FALSE)) return FALSE; if (!sync_expunges) { @@ -131,6 +171,10 @@ failed = !index_storage_sync_modifylog(ibox); } + /* check size only if we're locked (== at least something changed) */ + if (ibox->index->lock_type != MAIL_LOCK_UNLOCK) + index_storage_sync_size(ibox); + if (!ibox->index->set_lock(ibox->index, MAIL_LOCK_UNLOCK)) return mail_storage_set_index_error(ibox);