mail-index-view-sync.c revision 3b80595fcf2001cf7b2fcc6290823e38f4a142fc
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen#include "array.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "buffer.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-index-view-private.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-index-sync-private.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-transaction-log.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
463e82bdf0e990f4f2252d2b53ea23a5abe5883cTimo Sirainenstruct mail_index_view_sync_ctx {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_view *view;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen enum mail_index_view_sync_flags flags;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen struct mail_index_sync_map_ctx sync_map_ctx;
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen ARRAY_TYPE(seq_range) expunges;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen unsigned int finish_min_msg_count;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen const struct mail_transaction_header *hdr;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen const void *data;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen size_t data_offset;
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen unsigned int failed:1;
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen unsigned int sync_map_update:1;
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen unsigned int skipped_expunges:1;
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen unsigned int last_read:1;
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen};
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainenstatic int
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainenmail_transaction_log_sort_expunges(ARRAY_TYPE(seq_range) *expunges,
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen const struct seq_range *src, size_t src_size)
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen{
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen /* Note that all the sequences are actually still UIDs at this point */
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen const struct seq_range *src_end;
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen struct seq_range *dest, new_exp;
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen unsigned int first, i, dest_count;
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen i_assert(src_size % sizeof(*src) == 0);
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen /* @UNSAFE */
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen dest = array_get_modifiable(expunges, &dest_count);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen if (dest_count == 0) {
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen array_append(expunges, src, src_size / sizeof(*src));
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen return 0;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen }
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen src_end = CONST_PTR_OFFSET(src, src_size);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen for (i = 0; src != src_end; src++) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* src[] must be sorted. */
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen if (src->seq1 > src->seq2 ||
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen (src+1 != src_end && src->seq2 >= src[1].seq1))
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen for (; i < dest_count; i++) {
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen if (src->seq1 < dest[i].seq1)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen break;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen new_exp = *src;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen first = i;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen while (i < dest_count && src->seq2 >= dest[i].seq1-1) {
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen /* we can/must merge with next record */
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen if (new_exp.seq2 < dest[i].seq2)
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen new_exp.seq2 = dest[i].seq2;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen i++;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (first > 0 && new_exp.seq1 <= dest[first-1].seq2+1) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* continue previous record */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen if (dest[first-1].seq2 < new_exp.seq2)
e6d7d19c328e7043ad35d5a52c1617bde915a16fTimo Sirainen dest[first-1].seq2 = new_exp.seq2;
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen } else if (i == first) {
153de7823e64c67678b3fc95719c41a8ec5b864dTimo Sirainen array_insert(expunges, i, &new_exp, 1);
153de7823e64c67678b3fc95719c41a8ec5b864dTimo Sirainen i++; first++;
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen dest = array_get_modifiable(expunges, &dest_count);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen } else {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* use next record */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen dest[first] = new_exp;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen first++;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen if (i > first) {
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen array_delete(expunges, first, i - first);
e6d7d19c328e7043ad35d5a52c1617bde915a16fTimo Sirainen
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen dest = array_get_modifiable(expunges, &dest_count);
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen i = first;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
538c58fc95200fcc5e91abdda8b912b574a2f968Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainenstatic int
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenview_sync_set_log_view_range(struct mail_index_view *view, bool sync_expunges)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen const struct mail_index_header *hdr = &view->index->map->hdr;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uint32_t start_seq, end_seq;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uoff_t start_offset, end_offset;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen bool reset;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen int ret;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen start_seq = view->log_file_expunge_seq;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen start_offset = view->log_file_expunge_offset;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen end_seq = hdr->log_file_seq;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen end_offset = hdr->log_file_head_offset;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen for (;;) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* the view begins from the first non-synced transaction */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen ret = mail_transaction_log_view_set(view->log_view,
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen start_seq, start_offset,
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen end_seq, end_offset,
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen &reset);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen if (ret <= 0) {
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen if (ret < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen /* FIXME: use the new index to get needed
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen changes */
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen mail_index_set_error(view->index,
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen "Transaction log got desynced for index %s",
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen view->index->filepath);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen view->inconsistent = TRUE;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen return -1;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen }
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen if (!reset || sync_expunges)
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen break;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen /* we can't do this. sync only up to reset. */
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen mail_transaction_log_view_get_prev_pos(view->log_view,
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen &end_seq, &end_offset);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen end_seq--; end_offset = (uoff_t)-1;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen if (end_seq < start_seq) {
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen /* we have only this reset log */
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen mail_transaction_log_view_clear(view->log_view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen }
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen return 0;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen}
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainenview_sync_get_expunges(struct mail_index_view *view,
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen ARRAY_TYPE(seq_range) *expunges_r,
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen unsigned int *expunge_count_r)
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen{
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen const struct mail_transaction_header *hdr;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen struct seq_range *src, *src_end, *dest;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen const void *data;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen unsigned int count, expunge_count = 0;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen uint32_t prev_seq = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (view_sync_set_log_view_range(view, TRUE) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* get a list of expunge transactions. there may be some that we have
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen already synced, but it doesn't matter because they'll get dropped
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen out when converting to sequences */
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen i_array_init(expunges_r, 64);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen while ((ret = mail_transaction_log_view_next(view->log_view,
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen &hdr, &data)) > 0) {
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0)
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen continue;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0) {
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen /* this is simply a request for expunge */
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen continue;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen }
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen if (mail_transaction_log_sort_expunges(expunges_r, data,
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen hdr->size) < 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_transaction_log_view_set_corrupted(view->log_view,
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen "Corrupted expunge record");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (ret < 0) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen array_free(expunges_r);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
9bc6e10d9c6d6ffb4a2ed49a3b3d2a180f2a87a3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* convert UIDs to sequences */
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen src = dest = array_get_modifiable(expunges_r, &count);
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen src_end = src + count;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen for (; src != src_end; src++) {
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen mail_index_lookup_uid_range(view, src->seq1, src->seq2,
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen &dest->seq1, &dest->seq2);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (dest->seq1 == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen count--;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(dest->seq1 > prev_seq);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen prev_seq = dest->seq2;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen expunge_count += dest->seq2 - dest->seq1 + 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dest++;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen array_delete(expunges_r, count, array_count(expunges_r) - count);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *expunge_count_r = expunge_count;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic bool have_existing_expunges(struct mail_index_view *view,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen const struct seq_range *range, size_t size)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen const struct seq_range *range_end;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen uint32_t seq1, seq2;
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen range_end = CONST_PTR_OFFSET(range, size);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen for (; range < range_end; range++) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_index_lookup_uid_range(view, range->seq1, range->seq2,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen &seq1, &seq2);
7889c9f65e23c83fc31cecf304cab4ab070d6aa1Timo Sirainen if (seq1 != 0)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return TRUE;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return FALSE;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenstatic bool view_sync_have_expunges(struct mail_index_view *view)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen const struct mail_transaction_header *hdr;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen const void *data;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uint32_t seq;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uoff_t offset;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen bool have_expunges = FALSE;
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen int ret;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_transaction_log_view_get_prev_pos(view->log_view,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen &seq, &offset);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen while ((ret = mail_transaction_log_view_next(view->log_view,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen &hdr, &data)) > 0) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen continue;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* this is simply a request for expunge */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen continue;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* we have an expunge. see if it still exists. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (have_existing_expunges(view, data, hdr->size)) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen have_expunges = TRUE;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen break;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_transaction_log_view_seek(view->log_view, seq, offset);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* handle failures as having expunges (which is safer).
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen we'll probably fail later. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return ret < 0 || have_expunges;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenint mail_index_view_sync_begin(struct mail_index_view *view,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen enum mail_index_view_sync_flags flags,
9bc6e10d9c6d6ffb4a2ed49a3b3d2a180f2a87a3Timo Sirainen struct mail_index_view_sync_ctx **ctx_r)
9bc6e10d9c6d6ffb4a2ed49a3b3d2a180f2a87a3Timo Sirainen{
9bc6e10d9c6d6ffb4a2ed49a3b3d2a180f2a87a3Timo Sirainen struct mail_index_view_sync_ctx *ctx;
9bc6e10d9c6d6ffb4a2ed49a3b3d2a180f2a87a3Timo Sirainen struct mail_index_map *map;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen ARRAY_TYPE(seq_range) expunges = ARRAY_INIT;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen unsigned int expunge_count = 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen bool sync_expunges;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen i_assert(!view->syncing);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen i_assert(view->transactions == 0);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (mail_index_view_is_inconsistent(view)) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_index_set_error(view->index, "%s view is inconsistent",
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->index->filepath);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen sync_expunges = (flags & MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES) == 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (sync_expunges) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* get list of all expunges first */
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen if (view_sync_get_expunges(view, &expunges,
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen &expunge_count) < 0)
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (view_sync_set_log_view_range(view, sync_expunges) < 0) {
abfcd9f73b9ad1eeef4fe6e9940383defabf68c3Timo Sirainen if (array_is_created(&expunges))
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen array_free(&expunges);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
abfcd9f73b9ad1eeef4fe6e9940383defabf68c3Timo Sirainen ctx = i_new(struct mail_index_view_sync_ctx, 1);
abfcd9f73b9ad1eeef4fe6e9940383defabf68c3Timo Sirainen ctx->view = view;
abfcd9f73b9ad1eeef4fe6e9940383defabf68c3Timo Sirainen ctx->flags = flags;
abfcd9f73b9ad1eeef4fe6e9940383defabf68c3Timo Sirainen ctx->expunges = expunges;
abfcd9f73b9ad1eeef4fe6e9940383defabf68c3Timo Sirainen ctx->finish_min_msg_count =
abfcd9f73b9ad1eeef4fe6e9940383defabf68c3Timo Sirainen view->map->hdr.messages_count - expunge_count;
abfcd9f73b9ad1eeef4fe6e9940383defabf68c3Timo Sirainen mail_index_sync_map_init(&ctx->sync_map_ctx, view,
cd5ee8630497fdbd853ef588a858b4ef619a5e03Timo Sirainen MAIL_INDEX_SYNC_HANDLER_VIEW);
cd5ee8630497fdbd853ef588a858b4ef619a5e03Timo Sirainen
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen if (sync_expunges || !view_sync_have_expunges(view)) {
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen view->sync_new_map = view->index->map;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen view->sync_new_map->refcount++;
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen i_assert(view->index->map->hdr.messages_count >=
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen ctx->finish_min_msg_count);
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen /* keep the old mapping without expunges until we're
9887c39c5ba429169389153ca99de49e084a73f0Timo Sirainen fully synced */
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen } else {
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen /* We need a private copy of the map if we don't want to
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen sync expunges.
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen If view's map is the head map, it means that it contains
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen already all the latest changes and there's no need for us
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen to apply any changes to it. This can only happen if there
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen hadn't been any expunges. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (view->map != view->index->map) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* Using non-head mapping. We have to apply
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen transactions to it to get latest changes into it. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen ctx->sync_map_update = TRUE;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (view->map->refcount > 1) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen map = mail_index_map_clone(view->map);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_index_unmap(&view->map);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->map = map;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen } else {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen map = view->map;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen }
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen }
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen#ifdef DEBUG
ace3c14e47a5a865df8aeea2fabc993b609dd163Timo Sirainen mail_index_map_check(view->map);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen#endif
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* Syncing the view invalidates all previous looked up records.
41bb0aa8e357876bc9a1916a37c9e3e78e5f8185Timo Sirainen Unreference the mappings this view keeps because of them. */
dd8de60250511cc729b67249e61dfc6b4debff11Timo Sirainen mail_index_view_unref_maps(view);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen view->syncing = TRUE;
dd8de60250511cc729b67249e61dfc6b4debff11Timo Sirainen
51920d00fa50edf7b2e9b1019288d64b7abee7f3Timo Sirainen *ctx_r = ctx;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return 0;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic bool
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainenview_sync_is_hidden(struct mail_index_view *view, uint32_t seq, uoff_t offset)
cd5ee8630497fdbd853ef588a858b4ef619a5e03Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_index_view_log_sync_area *syncs;
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen unsigned int i, count;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (!array_is_created(&view->syncs_hidden))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return FALSE;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
659fe5d24825b160cae512538088020d97a60239Timo Sirainen syncs = array_get(&view->syncs_hidden, &count);
567e57b09a49bbb2a146b13f8617698eb56237feTimo Sirainen for (i = 0; i < count; i++) {
567e57b09a49bbb2a146b13f8617698eb56237feTimo Sirainen if (syncs[i].log_file_offset <= offset &&
567e57b09a49bbb2a146b13f8617698eb56237feTimo Sirainen offset - syncs[i].log_file_offset < syncs[i].length &&
659fe5d24825b160cae512538088020d97a60239Timo Sirainen syncs[i].log_file_seq == seq)
659fe5d24825b160cae512538088020d97a60239Timo Sirainen return TRUE;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return FALSE;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
41bb0aa8e357876bc9a1916a37c9e3e78e5f8185Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainenstatic bool
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainenmail_index_view_sync_want(struct mail_index_view_sync_ctx *ctx,
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen const struct mail_transaction_header *hdr)
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen{
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen struct mail_index_view *view = ctx->view;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t seq;
51920d00fa50edf7b2e9b1019288d64b7abee7f3Timo Sirainen uoff_t offset, next_offset;
51920d00fa50edf7b2e9b1019288d64b7abee7f3Timo Sirainen
51920d00fa50edf7b2e9b1019288d64b7abee7f3Timo Sirainen mail_transaction_log_view_get_prev_pos(view->log_view, &seq, &offset);
21ec6628c567eeff025af35d8027be01044b0b1aTimo Sirainen next_offset = offset + sizeof(*hdr) + hdr->size;
21ec6628c567eeff025af35d8027be01044b0b1aTimo Sirainen
21ec6628c567eeff025af35d8027be01044b0b1aTimo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) != 0 &&
21ec6628c567eeff025af35d8027be01044b0b1aTimo Sirainen (hdr->type & MAIL_TRANSACTION_EXTERNAL) != 0) {
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen if ((ctx->flags & MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES) != 0) {
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen i_assert(!LOG_IS_BEFORE(seq, offset,
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen view->log_file_expunge_seq,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->log_file_expunge_offset));
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen if (!ctx->skipped_expunges) {
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen view->log_file_expunge_seq = seq;
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen view->log_file_expunge_offset = offset;
51920d00fa50edf7b2e9b1019288d64b7abee7f3Timo Sirainen ctx->skipped_expunges = TRUE;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return FALSE;
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (LOG_IS_BEFORE(seq, offset, view->log_file_expunge_seq,
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen view->log_file_expunge_offset)) {
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen /* already synced */
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen return FALSE;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen }
cd5ee8630497fdbd853ef588a858b4ef619a5e03Timo Sirainen }
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if (LOG_IS_BEFORE(seq, offset, view->log_file_head_seq,
5a7b52012bf77132bb8f466d07e0e88c63fdba42Timo Sirainen view->log_file_head_offset)) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen /* already synced */
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen return FALSE;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen }
9887c39c5ba429169389153ca99de49e084a73f0Timo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen view->log_file_head_seq = seq;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen view->log_file_head_offset = next_offset;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen return TRUE;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen}
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainenstatic int
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainenmail_index_view_sync_get_next_transaction(struct mail_index_view_sync_ctx *ctx)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen struct mail_transaction_log_view *log_view = ctx->view->log_view;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen struct mail_index_view *view = ctx->view;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen const struct mail_transaction_header *hdr;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen uint32_t seq;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen uoff_t offset;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen int ret;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen bool synced_to_map;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen for (;;) {
5a7b52012bf77132bb8f466d07e0e88c63fdba42Timo Sirainen /* Get the next transaction from log. */
5a7b52012bf77132bb8f466d07e0e88c63fdba42Timo Sirainen ret = mail_transaction_log_view_next(log_view, &ctx->hdr,
5a7b52012bf77132bb8f466d07e0e88c63fdba42Timo Sirainen &ctx->data);
5a7b52012bf77132bb8f466d07e0e88c63fdba42Timo Sirainen if (ret <= 0) {
5a7b52012bf77132bb8f466d07e0e88c63fdba42Timo Sirainen if (ret < 0)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen return -1;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen ctx->hdr = NULL;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen ctx->last_read = TRUE;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen return 0;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen }
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen hdr = ctx->hdr;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen if (!mail_index_view_sync_want(ctx, hdr)) {
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen /* This is a visible record that we don't want to
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen sync. */
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen continue;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen }
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen mail_transaction_log_view_get_prev_pos(log_view, &seq, &offset);
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen /* If we started from a map that we didn't create ourself,
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen some of the transactions may already be synced. at the end
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen of this view sync we'll update file_seq=0 so that this check
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen always becomes FALSE for subsequent syncs. */
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen synced_to_map = view->map->hdr.log_file_seq != 0 &&
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen LOG_IS_BEFORE(seq, offset,
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen view->map->hdr.log_file_seq,
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen view->map->hdr.log_file_head_offset);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen /* Apply transaction to view's mapping if needed (meaning we
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen didn't just re-map the view to head mapping). */
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen if (ctx->sync_map_update && !synced_to_map) {
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen i_assert((hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0 ||
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen (hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0);
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (mail_index_sync_record(&ctx->sync_map_ctx,
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen hdr, ctx->data) < 0)
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen return -1;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen }
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen /* skip changes committed by hidden transactions (eg. in IMAP
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen store +flags.silent command) */
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen if (view_sync_is_hidden(view, seq, offset))
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen continue;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen break;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen }
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen return 1;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen}
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen#define FLAG_UPDATE_IS_INTERNAL(u) \
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen ((((u)->add_flags | (u)->remove_flags) & \
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen ~MAIL_INDEX_MAIL_FLAG_DIRTY) == 0)
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainenstatic bool
d143077bd518de129b8d446fb58e003903e50867Timo Sirainenmail_index_view_sync_get_rec(struct mail_index_view_sync_ctx *ctx,
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen struct mail_index_view_sync_rec *rec)
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen{
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen const struct mail_transaction_header *hdr = ctx->hdr;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen const void *data = ctx->data;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen case MAIL_TRANSACTION_APPEND: {
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen /* data contains the appended records, but we don't care */
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_APPEND;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen rec->uid1 = rec->uid2 = 0;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen ctx->data_offset += hdr->size;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen break;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen }
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen case MAIL_TRANSACTION_EXPUNGE: {
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen const struct mail_transaction_expunge *exp =
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen CONST_PTR_OFFSET(data, ctx->data_offset);
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0) {
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen /* this is simply a request for expunge */
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen ctx->data_offset = ctx->hdr->size;
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen return 0;
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen }
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen /* data contains mail_transaction_expunge[] */
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_EXPUNGE;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen rec->uid1 = exp->uid1;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen rec->uid2 = exp->uid2;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen ctx->data_offset += sizeof(*exp);
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen break;
c91de2744f8c1e61e91082ff5e214450f28a0e7cTimo Sirainen }
c91de2744f8c1e61e91082ff5e214450f28a0e7cTimo Sirainen case MAIL_TRANSACTION_FLAG_UPDATE: {
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen const struct mail_transaction_flag_update *update =
c91de2744f8c1e61e91082ff5e214450f28a0e7cTimo Sirainen CONST_PTR_OFFSET(data, ctx->data_offset);
c91de2744f8c1e61e91082ff5e214450f28a0e7cTimo Sirainen
c91de2744f8c1e61e91082ff5e214450f28a0e7cTimo Sirainen /* data contains mail_transaction_flag_update[] */
c91de2744f8c1e61e91082ff5e214450f28a0e7cTimo Sirainen for (;;) {
a0d34d3982507f513a9d800082481e9faeb9a943Timo Sirainen ctx->data_offset += sizeof(*update);
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen if (!FLAG_UPDATE_IS_INTERNAL(update))
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen break;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen /* skip internal flag changes */
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen if (ctx->data_offset == ctx->hdr->size)
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen return 0;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen update = CONST_PTR_OFFSET(data, ctx->data_offset);
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_FLAGS;
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen rec->uid1 = update->uid1;
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen rec->uid2 = update->uid2;
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen break;
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen }
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen case MAIL_TRANSACTION_KEYWORD_UPDATE: {
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen const struct mail_transaction_keyword_update *update = data;
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen const uint32_t *uids;
a0d34d3982507f513a9d800082481e9faeb9a943Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen /* data contains mail_transaction_keyword_update header,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen the keyword name and an array of { uint32_t uid1, uid2; } */
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen if (ctx->data_offset == 0) {
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen /* skip over the header and name */
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen ctx->data_offset = sizeof(*update) + update->name_size;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen if ((ctx->data_offset % 4) != 0)
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen ctx->data_offset += 4 - (ctx->data_offset % 4);
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen }
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen uids = CONST_PTR_OFFSET(data, ctx->data_offset);
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD;
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen rec->uid1 = uids[0];
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen rec->uid2 = uids[1];
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen ctx->data_offset += sizeof(uint32_t) * 2;
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen break;
a0d34d3982507f513a9d800082481e9faeb9a943Timo Sirainen }
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen case MAIL_TRANSACTION_KEYWORD_RESET: {
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen const struct mail_transaction_keyword_reset *reset =
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen CONST_PTR_OFFSET(data, ctx->data_offset);
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen /* data contains mail_transaction_keyword_reset[] */
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen rec->uid1 = reset->uid1;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen rec->uid2 = reset->uid2;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen ctx->data_offset += sizeof(*reset);
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen break;
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen }
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen default:
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen ctx->hdr = NULL;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen return FALSE;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
2d79e603e20a32bdae4c2b516ead5c5c9169545aTimo Sirainen return TRUE;
86d52f310fe939090c66b780a3b6ffe5d10dc8faTimo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenbool mail_index_view_sync_next(struct mail_index_view_sync_ctx *ctx,
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen struct mail_index_view_sync_rec *sync_rec)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen int ret;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen do {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (ctx->hdr == NULL || ctx->data_offset == ctx->hdr->size) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen ret = mail_index_view_sync_get_next_transaction(ctx);
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen if (ret <= 0) {
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen if (ret < 0)
2d79e603e20a32bdae4c2b516ead5c5c9169545aTimo Sirainen ctx->failed = TRUE;
2d79e603e20a32bdae4c2b516ead5c5c9169545aTimo Sirainen return FALSE;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen }
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen ctx->data_offset = 0;
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen }
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen } while (!mail_index_view_sync_get_rec(ctx, sync_rec));
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen return TRUE;
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen}
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainenvoid mail_index_view_sync_get_expunges(struct mail_index_view_sync_ctx *ctx,
a5b331e18b220fac557480b569b85215a1b3bd8eTimo Sirainen const ARRAY_TYPE(seq_range) **expunges_r)
a0d34d3982507f513a9d800082481e9faeb9a943Timo Sirainen{
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen *expunges_r = &ctx->expunges;
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen}
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainenstatic void
d143077bd518de129b8d446fb58e003903e50867Timo Sirainenmail_index_view_sync_clean_log_syncs(struct mail_index_view *view)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen{
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen const struct mail_index_view_log_sync_area *syncs;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen unsigned int i, count;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if (!array_is_created(&view->syncs_hidden))
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return;
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen /* Clean up to view's tail */
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen syncs = array_get(&view->syncs_hidden, &count);
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen for (i = 0; i < count; i++) {
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen if ((syncs[i].log_file_offset +
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen syncs[i].length > view->log_file_expunge_offset &&
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen syncs[i].log_file_seq == view->log_file_expunge_seq) ||
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen syncs[i].log_file_seq > view->log_file_expunge_seq)
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen break;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen }
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen if (i > 0)
20c26f4fcf9ef87434761829cc209c2f84ff5716Timo Sirainen array_delete(&view->syncs_hidden, 0, i);
20c26f4fcf9ef87434761829cc209c2f84ff5716Timo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainenint mail_index_view_sync_commit(struct mail_index_view_sync_ctx **_ctx)
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen{
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen struct mail_index_view_sync_ctx *ctx = *_ctx;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen struct mail_index_view *view = ctx->view;
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen int ret = ctx->failed ? -1 : 0;
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen i_assert(view->syncing);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen *_ctx = NULL;
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen if (!ctx->last_read) {
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen /* we didn't sync everything */
190237ce467d2389dfb809874b0fec86d3c7968dTimo Sirainen view->inconsistent = TRUE;
190237ce467d2389dfb809874b0fec86d3c7968dTimo Sirainen ret = -1;
190237ce467d2389dfb809874b0fec86d3c7968dTimo Sirainen }
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen if (view->sync_new_map != NULL) {
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen mail_index_unmap(&view->map);
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen view->map = view->sync_new_map;
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen view->sync_new_map = NULL;
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen }
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen i_assert(view->map->hdr.messages_count >= ctx->finish_min_msg_count);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (!ctx->skipped_expunges) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->log_file_expunge_seq = view->log_file_head_seq;
ccffbed92cb02c24fd717808a84138240bf1885bTimo Sirainen view->log_file_expunge_offset = view->log_file_head_offset;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
ccffbed92cb02c24fd717808a84138240bf1885bTimo Sirainen if (ctx->sync_map_update) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* log offsets have no meaning in views. make sure they're not
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen tried to be used wrong by setting them to zero. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->map->hdr.log_file_seq = 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->map->hdr.log_file_head_offset = 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->map->hdr.log_file_tail_offset = 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_index_sync_map_deinit(&ctx->sync_map_ctx);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_index_view_sync_clean_log_syncs(ctx->view);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen#ifdef DEBUG
ccffbed92cb02c24fd717808a84138240bf1885bTimo Sirainen mail_index_map_check(view->map);
ccffbed92cb02c24fd717808a84138240bf1885bTimo Sirainen#endif
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen /* set log view to empty range so unneeded memory gets freed */
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen mail_transaction_log_view_clear(view->log_view);
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen if (array_is_created(&ctx->expunges))
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen array_free(&ctx->expunges);
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen view->syncing = FALSE;
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen i_free(ctx);
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen return ret;
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen}
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainenvoid mail_index_view_add_hidden_transaction(struct mail_index_view *view,
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen uint32_t log_file_seq,
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen uoff_t log_file_offset,
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen unsigned int length)
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen{
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen struct mail_index_view_log_sync_area *area;
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen if (!array_is_created(&view->syncs_hidden))
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen i_array_init(&view->syncs_hidden, 32);
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen area = array_append_space(&view->syncs_hidden);
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen area->log_file_seq = log_file_seq;
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen area->log_file_offset = log_file_offset;
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen area->length = length;
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen}
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen