]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
View's message count shouldn't change until after view is synced.
authorTimo Sirainen <tss@iki.fi>
Sun, 23 May 2004 16:30:24 +0000 (19:30 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 23 May 2004 16:30:24 +0000 (19:30 +0300)
--HG--
branch : HEAD

src/lib-index/mail-index-view-private.h
src/lib-index/mail-index-view-sync.c
src/lib-index/mail-index-view.c

index 024d8829cdc286792332067765a6c332d8366e0d..ebd745bf358c90187c89330d7064c61845c7a128 100644 (file)
@@ -10,6 +10,9 @@ struct mail_index_view {
        unsigned int indexid;
        struct mail_index_map *map;
 
+       struct mail_index_header tmp_hdr_copy;
+       uint32_t messages_count; /* last synced one, map may be different */
+
        uint32_t log_file_seq;
        uoff_t log_file_offset;
         buffer_t *log_syncs;
index e935145107c1afad5f1bc585b78650330c6dd2ad..29f1ca53ca7e2779e401eef386b6417a4fae0780 100644 (file)
@@ -12,7 +12,6 @@ struct mail_index_view_sync_ctx {
        enum mail_index_sync_type sync_mask;
        struct mail_index_map *sync_map;
        buffer_t *expunges;
-       uint32_t messages_count;
 
        const struct mail_transaction_header *hdr;
        const void *data;
@@ -20,6 +19,7 @@ struct mail_index_view_sync_ctx {
        size_t data_offset;
        unsigned int skipped:1;
        unsigned int last_read:1;
+       unsigned int sync_map_update:1;
 };
 
 static int
@@ -79,7 +79,6 @@ int mail_index_view_sync_begin(struct mail_index_view *view,
 {
        const struct mail_index_header *hdr;
        struct mail_index_view_sync_ctx *ctx;
-       struct mail_index_map *map;
        enum mail_transaction_type mask;
        buffer_t *expunges = NULL;
 
@@ -110,20 +109,23 @@ int mail_index_view_sync_begin(struct mail_index_view *view,
                return -1;
        }
 
-       if (sync_mask == MAIL_INDEX_SYNC_MASK_ALL) {
-               map = view->index->map;
-               map->refcount++;
-       } else {
-               map = mail_index_map_to_memory(view->map);
-       }
-       view->syncing = TRUE;
-
        ctx = i_new(struct mail_index_view_sync_ctx, 1);
        ctx->view = view;
        ctx->sync_mask = sync_mask;
-       ctx->sync_map = map;
        ctx->expunges = expunges;
-       ctx->messages_count = mail_index_view_get_message_count(view);
+
+       if ((sync_mask & MAIL_INDEX_SYNC_TYPE_EXPUNGE) != 0) {
+               ctx->sync_map = view->index->map;
+               ctx->sync_map->refcount++;
+       } else {
+               /* we need a private copy of the map if we don't want to
+                  sync expunges */
+               if (MAIL_INDEX_MAP_IS_IN_MEMORY(view->map))
+                       ctx->sync_map_update = TRUE;
+               ctx->sync_map = mail_index_map_to_memory(view->map);
+       }
+
+       view->syncing = TRUE;
 
        *ctx_r = ctx;
        return 0;
@@ -254,8 +256,7 @@ static int mail_index_view_sync_map(struct mail_index_view_sync_ctx *ctx)
                sync_expunge, sync_append, sync_flag_update, sync_cache_update
        };
 
-       return mail_transaction_map(ctx->hdr, ctx->data,
-                                   &map_funcs, ctx);
+       return mail_transaction_map(ctx->hdr, ctx->data, &map_funcs, ctx);
 }
 
 static int mail_index_view_sync_next_trans(struct mail_index_view_sync_ctx *ctx,
@@ -284,7 +285,7 @@ static int mail_index_view_sync_next_trans(struct mail_index_view_sync_ctx *ctx,
        if (view_is_transaction_synced(view, *seq_r, *offset_r))
                return 0;
 
-       if (ctx->sync_mask != MAIL_INDEX_SYNC_MASK_ALL) {
+       if (ctx->sync_map_update) {
                if (mail_index_view_sync_map(ctx) < 0)
                        return -1;
        }
@@ -411,6 +412,9 @@ void mail_index_view_sync_end(struct mail_index_view_sync_ctx *ctx)
        view->map = ctx->sync_map;
        view->map_protected = FALSE;
 
+       if ((ctx->sync_mask & MAIL_INDEX_SYNC_TYPE_APPEND) != 0)
+               view->messages_count = view->map->records_count;
+
         mail_transaction_log_view_unset(view->log_view);
 
        if (ctx->expunges != NULL)
index 6b1a5ed410149f4be9d30c54871a8a1a5191378f..9b7576c7234160aec37c518c4d6815d7c0462b25 100644 (file)
@@ -17,6 +17,7 @@ struct mail_index_view *mail_index_view_open(struct mail_index *index)
        view->indexid = index->indexid;
        view->map = index->map;
        view->map->refcount++;
+       view->messages_count = view->map->records_count;
 
        view->log_file_seq = view->map->log_file_seq;
        view->log_file_offset = view->map->log_file_offset;
@@ -115,7 +116,7 @@ void mail_index_view_unlock(struct mail_index_view *view)
 
 uint32_t mail_index_view_get_message_count(struct mail_index_view *view)
 {
-       return view->map->records_count;
+       return view->messages_count;
 }
 
 int mail_index_view_is_inconsistent(struct mail_index_view *view)
@@ -148,7 +149,14 @@ int mail_index_get_header(struct mail_index_view *view,
        if (mail_index_view_lock(view) < 0)
                return -1;
 
-       *hdr_r = view->map->hdr;
+       if (view->map->hdr->messages_count == view->messages_count)
+               *hdr_r = view->map->hdr;
+       else {
+               /* messages_count differs, use a modified copy */
+               view->tmp_hdr_copy = *view->map->hdr;
+               view->tmp_hdr_copy.messages_count = view->messages_count;
+               *hdr_r = &view->tmp_hdr_copy;
+       }
        return 0;
 }
 
@@ -160,7 +168,7 @@ int mail_index_lookup(struct mail_index_view *view, uint32_t seq,
        uint32_t uid;
 
        i_assert(seq > 0);
-       i_assert(seq <= view->map->records_count);
+       i_assert(seq <= view->messages_count);
 
        if (mail_index_view_lock(view) < 0)
                return -1;
@@ -195,7 +203,7 @@ int mail_index_lookup_uid(struct mail_index_view *view, uint32_t seq,
                          uint32_t *uid_r)
 {
        i_assert(seq > 0);
-       i_assert(seq <= view->map->records_count);
+       i_assert(seq <= view->messages_count);
 
        if (mail_index_view_lock(view) < 0)
                return -1;
@@ -214,7 +222,7 @@ static uint32_t mail_index_bsearch_uid(struct mail_index_view *view,
        rec = view->map->records;
 
        idx = left_idx = *left_idx_p;
-       right_idx = view->map->records_count;
+       right_idx = view->messages_count;
 
        while (left_idx < right_idx) {
                idx = (left_idx + right_idx) / 2;
@@ -227,7 +235,7 @@ static uint32_t mail_index_bsearch_uid(struct mail_index_view *view,
                        break;
        }
 
-       if (idx == view->map->records_count) {
+       if (idx == view->messages_count) {
                /* no messages available */
                return 0;
        }
@@ -237,7 +245,7 @@ static uint32_t mail_index_bsearch_uid(struct mail_index_view *view,
                if (nearest_side > 0) {
                        /* we want uid or larger */
                        return rec[idx].uid > uid ? idx+1 :
-                               idx == view->map->records_count-1 ? 0 : idx+2;
+                               idx == view->messages_count-1 ? 0 : idx+2;
                } else {
                        /* we want uid or smaller */
                        return rec[idx].uid < uid ? idx + 1 : idx;
@@ -313,7 +321,7 @@ int mail_index_lookup_first(struct mail_index_view *view, enum mail_flags flags,
        }
 
        rec = &view->map->records[seq-1];
-       for (; seq <= view->map->records_count; seq++, rec++) {
+       for (; seq <= view->messages_count; seq++, rec++) {
                if ((rec->flags & flags_mask) == (uint8_t)flags) {
                        *seq_r = seq;
                        break;