mail-index-sync.c revision a24f6b02ed8d0dde933a715be1c86f01977bf610
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainenstatic void mail_index_sync_sort_flags(struct mail_index_sync_ctx *ctx)
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen const struct mail_transaction_flag_update *src, *src_end;
550d2fe097e95f12e8fa60ef52753ea7fe53d4eaTimo Sirainen const struct mail_transaction_flag_update *dest;
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen struct mail_transaction_flag_update new_update;
ae32667c54480d329eed994b3defab89cd76c077Timo Sirainen dest = buffer_get_data(ctx->updates_buf, &dest_count);
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen /* insert it into buffer, split it in multiple parts if needed
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen to make sure the ordering stays the same */
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen for (; i < dest_count; i++) {
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen /* partial */
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen buffer_insert(ctx->updates_buf, i * sizeof(new_update),
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen dest = buffer_get_data(ctx->updates_buf, NULL);
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen buffer_insert(ctx->updates_buf, i * sizeof(new_update),
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen dest = buffer_get_data(ctx->updates_buf, NULL);
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainenstatic void mail_index_sync_sort_transaction(struct mail_index_sync_ctx *ctx)
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen switch (ctx->hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen if (buffer_get_used_size(ctx->expunges_buf) == 0) {
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen mail_transaction_log_sort_expunges(ctx->expunges_buf,
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen if (buffer_get_used_size(ctx->expunges_buf) == 0 &&
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen buffer_get_used_size(ctx->updates_buf) == 0) {
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen buffer_append(ctx->appends_buf, ctx->data, ctx->hdr->size);
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainenstatic int mail_index_sync_read_and_sort(struct mail_index_sync_ctx *ctx,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen flag = external ? MAIL_TRANSACTION_EXTERNAL : 0;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen while ((ret = mail_transaction_log_view_next(ctx->view->log_view,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if ((ctx->hdr->type & MAIL_TRANSACTION_EXTERNAL) == flag)
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen ctx->expunges = buffer_get_data(ctx->expunges_buf, &size);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ctx->expunges_count = size / sizeof(*ctx->expunges);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen ctx->updates = buffer_get_data(ctx->updates_buf, &size);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen ctx->updates_count = size / sizeof(*ctx->updates);
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainenstatic int mail_index_need_lock(struct mail_index *index,
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen uint32_t log_file_seq, uoff_t log_file_offset)
3ee8a7ee6912c7caa4e83d3ce5a5db1590a7ffcdTimo Sirainen if (index->hdr->log_file_seq > log_file_seq ||
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen index->hdr->log_file_offset >= log_file_offset)) {
cf9d67e4a9bfee31cf3be05244555d51a3d1b9feTimo Sirainen /* already synced */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenint mail_index_sync_begin(struct mail_index *index,
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen uint32_t log_file_seq, uoff_t log_file_offset)
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen unsigned int lock_id;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (mail_transaction_log_sync_lock(index->log, &seq, &offset) < 0)
58b8a301b7b36047f10a592751094fbed86d6f0cTimo Sirainen if (mail_index_lock_shared(index, TRUE, &lock_id) < 0) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (!mail_index_need_lock(index, log_file_seq, log_file_offset)) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (mail_transaction_log_view_set(ctx->view->log_view,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* we need to have all the transactions sorted to optimize
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen caller's mailbox access patterns */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ctx->expunges_buf = buffer_create_dynamic(default_pool,
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen ctx->updates_buf = buffer_create_dynamic(default_pool,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ctx->appends_buf = buffer_create_dynamic(default_pool,
468c28dfb03613ab8d487b5aebc985a969193aceTimo Sirainen if (mail_index_sync_read_and_sort(ctx, FALSE) < 0) {
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainenmail_index_sync_get_expunge(struct mail_index_sync_rec *rec,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenmail_index_sync_get_update(struct mail_index_sync_rec *rec,
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen const struct mail_transaction_flag_update *update)
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen memcpy(rec->add_keywords, update->add_keywords,
550d2fe097e95f12e8fa60ef52753ea7fe53d4eaTimo Sirainen memcpy(rec->remove_keywords, update->remove_keywords,
bfef6891565ff9018ac92add6eae401e9352c657Timo Sirainenstatic int mail_index_sync_rec_check(struct mail_index_view *view,
15ab2452b0220a115f4351ad9d7fd5ec70ae7966Timo Sirainen if (rec->uid1 > rec->uid2 || rec->uid1 == 0) {
15ab2452b0220a115f4351ad9d7fd5ec70ae7966Timo Sirainen mail_transaction_log_view_set_corrupted(view->log_view,
15ab2452b0220a115f4351ad9d7fd5ec70ae7966Timo Sirainen "Broken UID range: %u..%u (type 0x%x)",
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenint mail_index_sync_next(struct mail_index_sync_ctx *ctx,
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen const struct mail_transaction_expunge *next_exp;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const struct mail_transaction_flag_update *next_update;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen next_exp = ctx->expunge_idx == ctx->expunges_count ? NULL :
de92873c366becfaea1554642f89b9169d7955e2Timo Sirainen next_update = ctx->update_idx == ctx->updates_count ? NULL :
c3a2a487e23a282e59254b82deb9344ed0306bb2Timo Sirainen // FIXME: return dirty flagged records as flag updates
c3a2a487e23a282e59254b82deb9344ed0306bb2Timo Sirainen /* the ugliness here is to avoid returning overlapping expunge
1df39b899804fd1dbc560f75382364822935c857Timo Sirainen and update areas. For example:
1f7f4294207557edf83171642ef62ce4922ffc9dTimo Sirainen updates[] = A { 1, 7 }, B { 1, 3 }
1f7f4294207557edf83171642ef62ce4922ffc9dTimo Sirainen expunges[] = { 5, 6 }
1f7f4294207557edf83171642ef62ce4922ffc9dTimo Sirainen will make us return
next_update++;
int ret = 0;
if (ret == 0) {
if (ret == 0) {
return ret;
for (i = 0; i < INDEX_KEYWORDS_BYTE_COUNT; i++) {