]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added mail_index_transaction_get_updated_view() which can be used to access
authorTimo Sirainen <tss@iki.fi>
Tue, 22 Jun 2004 07:36:33 +0000 (10:36 +0300)
committerTimo Sirainen <tss@iki.fi>
Tue, 22 Jun 2004 07:36:33 +0000 (10:36 +0300)
uncommitted messages.

--HG--
branch : HEAD

20 files changed:
src/lib-index/Makefile.am
src/lib-index/mail-cache-lookup.c
src/lib-index/mail-cache-transaction.c
src/lib-index/mail-index-transaction-private.h
src/lib-index/mail-index-transaction-view.c [new file with mode: 0644]
src/lib-index/mail-index-transaction.c
src/lib-index/mail-index-view-private.h
src/lib-index/mail-index-view.c
src/lib-index/mail-index.h
src/lib-storage/index/index-fetch.c
src/lib-storage/index/index-mail-headers.c
src/lib-storage/index/index-mail.c
src/lib-storage/index/index-search.c
src/lib-storage/index/index-storage.c
src/lib-storage/index/index-storage.h
src/lib-storage/index/index-transaction.c
src/lib-storage/index/maildir/maildir-transaction.c
src/lib-storage/index/mbox/mbox-mail.c
src/lib-storage/index/mbox/mbox-save.c
src/lib-storage/index/mbox/mbox-transaction.c

index 9860919d790ac1db363f39d7a075e0ac9ad4a880..f2bae4cefeab427ac08424250555a1efdbe57b5e 100644 (file)
@@ -12,6 +12,7 @@ libindex_a_SOURCES = \
         mail-index-fsck.c \
         mail-index-lock.c \
         mail-index-transaction.c \
+        mail-index-transaction-view.c \
         mail-index-sync.c \
         mail-index-sync-update.c \
         mail-index-view.c \
index 8ad0050c02b33af2ab41a6f368d56f3935a4edef..c28ccedc494fdc1757e1b9d4bdc9f5aaa059479b 100644 (file)
@@ -175,11 +175,6 @@ mail_cache_lookup(struct mail_cache_view *view, uint32_t seq,
        if (view->cache->disabled)
                return NULL;
 
-       if (seq > mail_index_view_get_message_count(view->view)) {
-               /* it's being appended in some transaction */
-               return NULL;
-       }
-
        if (mail_index_lookup_full(view->view, seq, &map, &rec) < 0)
                return NULL;
 
index 3c63de017cdb78d9de80cae1364e409d75f9deed..251ff9dfa72cceac8cff08b2c554ab73e96d45f0 100644 (file)
@@ -220,7 +220,7 @@ static int mail_cache_write(struct mail_cache_transaction_ctx *ctx)
        struct mail_cache_record *cache_rec, *next;
        const struct mail_index_record *rec;
        struct mail_index_map *map;
-       uint32_t messages_count, write_offset, update_offset;
+       uint32_t write_offset, update_offset;
        const void *buf;
        size_t size, buf_size;
        int ret;
@@ -230,15 +230,8 @@ static int mail_cache_write(struct mail_cache_transaction_ctx *ctx)
        size = sizeof(*cache_rec) + buf_size;
        ctx->cache_rec.size = uint32_to_nbo(size);
 
-        messages_count = mail_index_view_get_message_count(ctx->view->view);
-       if (ctx->prev_seq <= messages_count) {
-               ret = mail_index_lookup_full(ctx->view->view, ctx->prev_seq,
-                                            &map, &rec);
-       } else {
-               ret = mail_index_transaction_lookup(ctx->trans,
-                                                   ctx->prev_seq, &rec);
-               map = cache->index->map;
-       }
+       ret = mail_index_lookup_full(ctx->view->view, ctx->prev_seq,
+                                    &map, &rec);
        if (ret < 0)
                return -1;
 
index d0efb4e31c837357a32eab8497de12eb682d79a5..f22ac491ca375e99f2c487f32799e9f9dd41b4be 100644 (file)
@@ -1,8 +1,10 @@
 #ifndef __MAIL_INDEX_TRANSACTION_PRIVATE_H
 #define __MAIL_INDEX_TRANSACTION_PRIVATE_H
 
+#include "mail-transaction-log.h"
+
 struct mail_index_transaction {
-       struct mail_index_view *view;
+       struct mail_index_view *view, *updated_view;
 
         buffer_t *appends;
        uint32_t first_new_seq, last_new_seq;
@@ -24,4 +26,7 @@ struct mail_index_transaction {
        unsigned int hdr_changed:1;
 };
 
+struct mail_index_record *
+mail_index_transaction_lookup(struct mail_index_transaction *t, uint32_t seq);
+
 #endif
diff --git a/src/lib-index/mail-index-transaction-view.c b/src/lib-index/mail-index-transaction-view.c
new file mode 100644 (file)
index 0000000..30c1bb0
--- /dev/null
@@ -0,0 +1,165 @@
+/* Copyright (C) 2004 Timo Sirainen */
+
+#include "lib.h"
+#include "buffer.h"
+#include "mail-index-private.h"
+#include "mail-index-view-private.h"
+#include "mail-index-transaction-private.h"
+
+struct mail_index_view_transaction {
+       struct mail_index_view view;
+       struct mail_index_view_methods *parent;
+       struct mail_index_transaction *t;
+};
+
+static void _tview_close(struct mail_index_view *view)
+{
+       struct mail_index_view_transaction *tview =
+               (struct mail_index_view_transaction *)view;
+
+       tview->t->updated_view = NULL;
+
+       return tview->parent->close(view);
+}
+
+static uint32_t _tview_get_message_count(struct mail_index_view *view)
+{
+       struct mail_index_view_transaction *tview =
+                (struct mail_index_view_transaction *)view;
+
+       return view->messages_count +
+               (tview->t->last_new_seq == 0 ? 0 :
+                tview->t->last_new_seq - tview->t->first_new_seq);
+}
+
+static int _tview_get_header(struct mail_index_view *view,
+                            const struct mail_index_header **hdr_r)
+{
+       struct mail_index_view_transaction *tview =
+                (struct mail_index_view_transaction *)view;
+
+       if (tview->parent->get_header(view, hdr_r) < 0)
+               return -1;
+
+       if ((*hdr_r)->messages_count != view->messages_count) {
+               /* messages_count differs, use a modified copy.
+                  FIXME: same problems as with _view_get_header().. */
+               view->tmp_hdr_copy = **hdr_r;
+               view->tmp_hdr_copy.messages_count = view->messages_count;
+               *hdr_r = &view->tmp_hdr_copy;
+       }
+       return 0;
+}
+
+static int _tview_lookup_full(struct mail_index_view *view, uint32_t seq,
+                             struct mail_index_map **map_r,
+                             const struct mail_index_record **rec_r)
+{
+       struct mail_index_view_transaction *tview =
+                (struct mail_index_view_transaction *)view;
+
+       if (seq >= tview->t->first_new_seq) {
+               /* FIXME: is this right to return index map..?
+                  it's not there yet. */
+               *map_r = view->index->map;
+               *rec_r = mail_index_transaction_lookup(tview->t, seq);
+               return 1;
+       } else {
+               return tview->parent->lookup_full(view, seq, map_r, rec_r);
+       }
+}
+
+static int _tview_lookup_uid(struct mail_index_view *view, uint32_t seq,
+                            uint32_t *uid_r)
+{
+       struct mail_index_view_transaction *tview =
+               (struct mail_index_view_transaction *)view;
+
+       if (seq >= tview->t->first_new_seq) {
+               *uid_r = mail_index_transaction_lookup(tview->t, seq)->uid;
+               return 0;
+       } else {
+               return tview->parent->lookup_uid(view, seq, uid_r);
+       }
+}
+
+static int _tview_lookup_uid_range(struct mail_index_view *view,
+                                  uint32_t first_uid, uint32_t last_uid,
+                                  uint32_t *first_seq_r, uint32_t *last_seq_r)
+{
+       struct mail_index_view_transaction *tview =
+               (struct mail_index_view_transaction *)view;
+
+       if (tview->parent->lookup_uid_range(view, first_uid, last_uid,
+                                           first_seq_r, last_seq_r) < 0)
+               return -1;
+
+       /* FIXME: we don't need this function yet.. new UIDs might be 0 as
+          well.. */
+
+       if (*first_seq_r == 0) {
+               /* nothing found, either doesn't exist or it's completely
+                  newly appended. */
+       } else if (*last_seq_r + 1 == tview->t->first_new_seq) {
+               /* last_seq_r may be growed from transactions */
+       }
+
+       return 0;
+}
+
+static int _tview_lookup_first(struct mail_index_view *view,
+                              enum mail_flags flags, uint8_t flags_mask,
+                              uint32_t *seq_r)
+{
+       struct mail_index_view_transaction *tview =
+               (struct mail_index_view_transaction *)view;
+       const struct mail_index_record *rec;
+       uint32_t seq, message_count;
+
+       if (tview->parent->lookup_first(view, flags, flags_mask, seq_r) < 0)
+               return -1;
+
+       if (*seq_r != 0)
+               return 0;
+
+       rec = buffer_get_data(tview->t->appends, NULL);
+       seq = tview->t->first_new_seq;
+       message_count = tview->t->last_new_seq;
+       for (; seq <= message_count; seq++) {
+               if ((rec->flags & flags_mask) == (uint8_t)flags) {
+                       *seq_r = seq;
+                       break;
+               }
+               rec = CONST_PTR_OFFSET(rec, view->index->record_size);
+       }
+
+       return 0;
+}
+
+static struct mail_index_view_methods view_methods = {
+       _tview_close,
+        _tview_get_message_count,
+       _tview_get_header,
+       _tview_lookup_full,
+       _tview_lookup_uid,
+       _tview_lookup_uid_range,
+       _tview_lookup_first
+};
+
+struct mail_index_view *
+mail_index_transaction_get_updated_view(struct mail_index_transaction *t)
+{
+       struct mail_index_view_transaction *tview;
+
+       if (t->updated_view == NULL) {
+               tview = i_new(struct mail_index_view_transaction, 1);
+               mail_index_view_clone(&tview->view, t->view);
+               tview->view.methods = view_methods;
+               tview->parent = &t->view->methods;
+               tview->t = t;
+
+               t->updated_view = &tview->view;
+       }
+
+       return t->updated_view;
+}
index 35a003990a7afac7dcc04f484ae33ea1c843956d..58e7766388a70bd605fc20d8ad304cae8312deeb 100644 (file)
@@ -25,6 +25,7 @@ mail_index_transaction_begin(struct mail_index_view *view, int hide)
        t = i_new(struct mail_index_transaction, 1);
        t->view = view;
        t->hide_transaction = hide;
+       t->first_new_seq = mail_index_view_get_message_count(t->view)+1;
        return t;
 }
 
@@ -47,6 +48,8 @@ static void mail_index_transaction_free(struct mail_index_transaction *t)
                buffer_free(t->updates);
        if (t->cache_updates != NULL)
                buffer_free(t->cache_updates);
+       if (t->updated_view != NULL)
+               mail_index_view_close(t->updated_view);
        i_free(t);
 }
 
@@ -136,8 +139,8 @@ void mail_index_transaction_rollback(struct mail_index_transaction *t)
         mail_index_transaction_free(t);
 }
 
-static struct mail_index_record *
-mail_index_lookup_append(struct mail_index_transaction *t, uint32_t seq)
+struct mail_index_record *
+mail_index_transaction_lookup(struct mail_index_transaction *t, uint32_t seq)
 {
        size_t pos;
 
@@ -148,18 +151,6 @@ mail_index_lookup_append(struct mail_index_transaction *t, uint32_t seq)
                                       t->view->index->record_size);
 }
 
-int mail_index_transaction_lookup(struct mail_index_transaction *t,
-                                 uint32_t seq,
-                                 const struct mail_index_record **rec_r)
-{
-       if (t->first_new_seq != 0 && seq >= t->first_new_seq) {
-               *rec_r = mail_index_lookup_append(t, seq);
-               return 1;
-       } else {
-               return mail_index_lookup(t->view, seq, rec_r);
-       }
-}
-
 void mail_index_append(struct mail_index_transaction *t, uint32_t uid,
                       uint32_t *seq_r)
 {
@@ -174,10 +165,8 @@ void mail_index_append(struct mail_index_transaction *t, uint32_t uid,
           so let it generate it */
        if (t->last_new_seq != 0)
                *seq_r = ++t->last_new_seq;
-       else {
-               *seq_r = t->first_new_seq = t->last_new_seq =
-                       mail_index_view_get_message_count(t->view)+1;
-       }
+       else
+               *seq_r = t->last_new_seq = t->first_new_seq;
 
        rec = buffer_append_space_unsafe(t->appends,
                                         t->view->index->record_size);
@@ -313,9 +302,9 @@ void mail_index_update_flags(struct mail_index_transaction *t, uint32_t seq,
 {
        struct mail_index_record *rec;
 
-       if (t->first_new_seq != 0 && seq >= t->first_new_seq) {
+       if (seq >= t->first_new_seq) {
                /* just appended message, modify it directly */
-                rec = mail_index_lookup_append(t, seq);
+                rec = mail_index_transaction_lookup(t, seq);
                mail_index_record_modify_flags(rec, modify_type,
                                               flags, keywords);
                return;
@@ -497,9 +486,9 @@ void mail_index_update_cache(struct mail_index_transaction *t,
 {
        struct mail_index_record *rec;
 
-       if (t->first_new_seq != 0 && seq >= t->first_new_seq) {
+       if (seq >= t->first_new_seq) {
                /* just appended message, modify it directly */
-               rec = mail_index_lookup_append(t, seq);
+               rec = mail_index_transaction_lookup(t, seq);
                rec->cache_offset = offset;
        } else {
                mail_index_update_seq_buffer(&t->cache_updates, seq,
@@ -516,10 +505,10 @@ void mail_index_update_extra_rec(struct mail_index_transaction *t,
 
        i_assert(data_id < index->extra_records_count);
 
-       if (t->first_new_seq != 0 && seq >= t->first_new_seq) {
+       if (seq >= t->first_new_seq) {
                /* just appended message, modify it directly */
                /* FIXME: do data_id mapping conversion */
-               rec = mail_index_lookup_append(t, seq);
+               rec = mail_index_transaction_lookup(t, seq);
                memcpy(PTR_OFFSET(rec, index->extra_records[data_id].offset),
                       data, index->extra_records[data_id].size);
        } else {
index 7dba3058cec52cc63fd34fa993a58eaea6da871a..15de0963aef586e3702cd62ba0682e613ca621bb 100644 (file)
@@ -3,7 +3,25 @@
 
 #include "mail-index-private.h"
 
+struct mail_index_view_methods {
+       void (*close)(struct mail_index_view *view);
+       uint32_t (*get_message_count)(struct mail_index_view *view);
+       int (*get_header)(struct mail_index_view *view,
+                         const struct mail_index_header **hdr_r);
+       int (*lookup_full)(struct mail_index_view *view, uint32_t seq,
+                          struct mail_index_map **map_r,
+                          const struct mail_index_record **rec_r);
+       int (*lookup_uid)(struct mail_index_view *view, uint32_t seq,
+                         uint32_t *uid_r);
+       int (*lookup_uid_range)(struct mail_index_view *view,
+                               uint32_t first_uid, uint32_t last_uid,
+                               uint32_t *first_seq_r, uint32_t *last_seq_r);
+       int (*lookup_first)(struct mail_index_view *view, enum mail_flags flags,
+                           uint8_t flags_mask, uint32_t *seq_r);
+};
+
 struct mail_index_view {
+       struct mail_index_view_methods methods;
        struct mail_index *index;
         struct mail_transaction_log_view *log_view;
 
@@ -27,6 +45,8 @@ struct mail_index_view {
        unsigned int map_protected:1;
 };
 
+void mail_index_view_clone(struct mail_index_view *dest,
+                          const struct mail_index_view *src);
 int mail_index_view_lock(struct mail_index_view *view);
 int mail_index_view_lock_head(struct mail_index_view *view, int update_index);
 void mail_index_view_add_synced_transaction(struct mail_index_view *view,
index 3d8fc5d924e093f271f7091e310a711545d87f7c..479249a13e800b488882a36d0106a5f11cf1dabc 100644 (file)
@@ -6,25 +6,24 @@
 #include "mail-index-view-private.h"
 #include "mail-transaction-log.h"
 
-struct mail_index_view *mail_index_view_open(struct mail_index *index)
+void mail_index_view_clone(struct mail_index_view *dest,
+                          const struct mail_index_view *src)
 {
-       struct mail_index_view *view;
-
-       view = i_new(struct mail_index_view, 1);
-       view->index = index;
-       view->log_view = mail_transaction_log_view_open(index->log);
-
-       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;
-       return view;
+       memset(dest, 0, sizeof(dest));
+       dest->methods = src->methods;
+       dest->index = src->index;
+       dest->log_view = mail_transaction_log_view_open(src->index->log);
+
+       dest->indexid = src->indexid;
+       dest->map = src->map;
+       dest->map->refcount++;
+       dest->messages_count = src->messages_count;
+
+       dest->log_file_seq = src->log_file_seq;
+       dest->log_file_offset = src->log_file_offset;
 }
 
-void mail_index_view_close(struct mail_index_view *view)
+static void _view_close(struct mail_index_view *view)
 {
        mail_index_view_unlock(view);
        mail_transaction_log_view_close(view->log_view);
@@ -117,11 +116,6 @@ 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->messages_count;
-}
-
 int mail_index_view_is_inconsistent(struct mail_index_view *view)
 {
        if (view->index->indexid != view->indexid)
@@ -146,8 +140,13 @@ void mail_index_view_transaction_unref(struct mail_index_view *view)
        view->transactions--;
 }
 
-int mail_index_get_header(struct mail_index_view *view,
-                         const struct mail_index_header **hdr_r)
+static uint32_t _view_get_message_count(struct mail_index_view *view)
+{
+       return view->messages_count;
+}
+
+static int _view_get_header(struct mail_index_view *view,
+                           const struct mail_index_header **hdr_r)
 {
        if (mail_index_view_lock(view) < 0)
                return -1;
@@ -155,7 +154,10 @@ int mail_index_get_header(struct mail_index_view *view,
        if (view->map->hdr->messages_count == view->messages_count)
                *hdr_r = view->map->hdr;
        else {
-               /* messages_count differs, use a modified copy */
+               /* messages_count differs, use a modified copy.
+                  FIXME: so might seen_messages_count, etc. and they're
+                  more difficult to fix. maybe grab a copy of the header
+                  when opening the view initially?.. */
                view->tmp_hdr_copy = *view->map->hdr;
                view->tmp_hdr_copy.messages_count = view->messages_count;
                *hdr_r = &view->tmp_hdr_copy;
@@ -163,16 +165,15 @@ int mail_index_get_header(struct mail_index_view *view,
        return 0;
 }
 
-int mail_index_lookup_full(struct mail_index_view *view, uint32_t seq,
-                          struct mail_index_map **map_r,
-                          const struct mail_index_record **rec_r)
+static int _view_lookup_full(struct mail_index_view *view, uint32_t seq,
+                            struct mail_index_map **map_r,
+                            const struct mail_index_record **rec_r)
 {
        struct mail_index_map *map;
        const struct mail_index_record *rec, *n_rec;
        uint32_t uid;
 
-       i_assert(seq > 0);
-       i_assert(seq <= view->messages_count);
+       i_assert(seq > 0 && seq <= mail_index_view_get_message_count(view));
 
        if (mail_index_view_lock(view) < 0)
                return -1;
@@ -216,19 +217,10 @@ int mail_index_lookup_full(struct mail_index_view *view, uint32_t seq,
        }
 }
 
-int mail_index_lookup(struct mail_index_view *view, uint32_t seq,
-                     const struct mail_index_record **rec_r)
-{
-       struct mail_index_map *map;
-
-       return mail_index_lookup_full(view, seq, &map, rec_r);
-}
-
-int mail_index_lookup_uid(struct mail_index_view *view, uint32_t seq,
-                         uint32_t *uid_r)
+static int _view_lookup_uid(struct mail_index_view *view, uint32_t seq,
+                           uint32_t *uid_r)
 {
-       i_assert(seq > 0);
-       i_assert(seq <= view->messages_count);
+       i_assert(seq > 0 && seq <= mail_index_view_get_message_count(view));
 
        if (mail_index_view_lock(view) < 0)
                return -1;
@@ -237,29 +229,6 @@ int mail_index_lookup_uid(struct mail_index_view *view, uint32_t seq,
        return 0;
 }
 
-int mail_index_lookup_extra(struct mail_index_view *view, uint32_t seq,
-                           uint32_t data_id, const void **data_r)
-{
-       const struct mail_index_record *rec;
-       struct mail_index_map *map;
-       uint32_t offset;
-       int ret;
-
-       if ((ret = mail_index_lookup_full(view, seq, &map, &rec)) < 0)
-               return -1;
-
-       if (rec == NULL) {
-               *data_r = NULL;
-               return ret;
-       }
-
-       /* FIXME: do data_id mapping conversion */
-
-       offset = view->index->extra_records[data_id].offset;
-       *data_r = CONST_PTR_OFFSET(rec, offset);
-       return ret;
-}
-
 static uint32_t mail_index_bsearch_uid(struct mail_index_view *view,
                                       uint32_t uid, uint32_t *left_idx_p,
                                       int nearest_side)
@@ -267,6 +236,8 @@ static uint32_t mail_index_bsearch_uid(struct mail_index_view *view,
        const struct mail_index_record *rec_base, *rec;
        uint32_t idx, left_idx, right_idx, record_size;
 
+       i_assert(view->messages_count <= view->map->records_count);
+
        rec_base = view->map->records;
        record_size = view->index->record_size;
 
@@ -306,9 +277,9 @@ static uint32_t mail_index_bsearch_uid(struct mail_index_view *view,
        return idx+1;
 }
 
-int mail_index_lookup_uid_range(struct mail_index_view *view,
-                               uint32_t first_uid, uint32_t last_uid,
-                               uint32_t *first_seq_r, uint32_t *last_seq_r)
+static int _view_lookup_uid_range(struct mail_index_view *view,
+                                 uint32_t first_uid, uint32_t last_uid,
+                                 uint32_t *first_seq_r, uint32_t *last_seq_r)
 {
        uint32_t left_idx;
 
@@ -347,8 +318,9 @@ int mail_index_lookup_uid_range(struct mail_index_view *view,
        return 0;
 }
 
-int mail_index_lookup_first(struct mail_index_view *view, enum mail_flags flags,
-                           uint8_t flags_mask, uint32_t *seq_r)
+static int _view_lookup_first(struct mail_index_view *view,
+                             enum mail_flags flags, uint8_t flags_mask,
+                             uint32_t *seq_r)
 {
 #define LOW_UPDATE(x) \
        STMT_START { if ((x) > low_uid) low_uid = x; } STMT_END
@@ -378,7 +350,7 @@ int mail_index_lookup_first(struct mail_index_view *view, enum mail_flags flags,
                        return 0;
        }
 
-       for (; seq <= view->messages_count; seq++, rec++) {
+       for (; seq <= view->messages_count; seq++) {
                rec = MAIL_INDEX_MAP_IDX(view->index, view->map, seq-1);
                if ((rec->flags & flags_mask) == (uint8_t)flags) {
                        *seq_r = seq;
@@ -388,3 +360,106 @@ int mail_index_lookup_first(struct mail_index_view *view, enum mail_flags flags,
 
        return 0;
 }
+
+void mail_index_view_close(struct mail_index_view *view)
+{
+       view->methods.close(view);
+}
+
+uint32_t mail_index_view_get_message_count(struct mail_index_view *view)
+{
+       return view->messages_count;
+}
+
+int mail_index_get_header(struct mail_index_view *view,
+                         const struct mail_index_header **hdr_r)
+{
+       return view->methods.get_header(view, hdr_r);
+}
+
+int mail_index_lookup(struct mail_index_view *view, uint32_t seq,
+                     const struct mail_index_record **rec_r)
+{
+       struct mail_index_map *map;
+
+       return mail_index_lookup_full(view, seq, &map, rec_r);
+}
+
+int mail_index_lookup_uid(struct mail_index_view *view, uint32_t seq,
+                         uint32_t *uid_r)
+{
+       return view->methods.lookup_uid(view, seq, uid_r);
+}
+
+int mail_index_lookup_extra(struct mail_index_view *view, uint32_t seq,
+                           uint32_t data_id, const void **data_r)
+{
+       const struct mail_index_record *rec;
+       struct mail_index_map *map;
+       uint32_t offset;
+       int ret;
+
+       if ((ret = mail_index_lookup_full(view, seq, &map, &rec)) < 0)
+               return -1;
+
+       if (rec == NULL) {
+               *data_r = NULL;
+               return ret;
+       }
+
+       /* FIXME: do data_id mapping conversion */
+
+       offset = view->index->extra_records[data_id].offset;
+       *data_r = CONST_PTR_OFFSET(rec, offset);
+       return ret;
+}
+
+int mail_index_lookup_uid_range(struct mail_index_view *view,
+                               uint32_t first_uid, uint32_t last_uid,
+                               uint32_t *first_seq_r, uint32_t *last_seq_r)
+{
+       return view->methods.lookup_uid_range(view, first_uid, last_uid,
+                                             first_seq_r, last_seq_r);
+}
+
+int mail_index_lookup_first(struct mail_index_view *view, enum mail_flags flags,
+                           uint8_t flags_mask, uint32_t *seq_r)
+{
+       return view->methods.lookup_first(view, flags, flags_mask, seq_r);
+}
+
+int mail_index_lookup_full(struct mail_index_view *view, uint32_t seq,
+                          struct mail_index_map **map_r,
+                          const struct mail_index_record **rec_r)
+{
+       return view->methods.lookup_full(view, seq, map_r, rec_r);
+}
+
+static struct mail_index_view_methods view_methods = {
+       _view_close,
+       _view_get_message_count,
+       _view_get_header,
+       _view_lookup_full,
+       _view_lookup_uid,
+       _view_lookup_uid_range,
+       _view_lookup_first
+};
+
+struct mail_index_view *mail_index_view_open(struct mail_index *index)
+{
+       struct mail_index_view *view;
+
+       view = i_new(struct mail_index_view, 1);
+       view->methods = view_methods;
+       view->index = index;
+       view->log_view = mail_transaction_log_view_open(index->log);
+
+       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;
+       return view;
+}
index e6aad4b0a18657a14940dfb9b170d007b3c81026..365de0fc63cf5cc576f74a26819a983a9a5b38be 100644 (file)
@@ -178,6 +178,12 @@ int mail_index_transaction_commit(struct mail_index_transaction *t,
                                  uoff_t *log_file_offset_r);
 void mail_index_transaction_rollback(struct mail_index_transaction *t);
 
+/* Returns a view to transaction. Currently this differs from normal view only
+   in that it contains newly appended messages in transaction. The view is
+   destroyed when the transaction is destroyed. */
+struct mail_index_view *
+mail_index_transaction_get_updated_view(struct mail_index_transaction *t);
+
 /* Begin synchronizing mailbox with index file. This call locks the index
    exclusively against other modifications. Returns 1 if ok, -1 if error.
 
@@ -278,11 +284,6 @@ void mail_index_update_header(struct mail_index_transaction *t,
 void mail_index_update_extra_rec(struct mail_index_transaction *t,
                                 uint32_t seq, uint32_t data_id,
                                 const void *data);
-/* Like mail_index_lookup(), but if seq > view's message count, it's referring
-   to message appended with given transaction. */
-int mail_index_transaction_lookup(struct mail_index_transaction *t,
-                                 uint32_t seq,
-                                 const struct mail_index_record **rec_r);
 
 /* Returns the last error code. */
 enum mail_index_error mail_index_get_last_error(struct mail_index *index);
index 1adff6d193b45b3124664c14f2df8b23e0e6849c..a4d4ebe428108d2eaa6d91069c89efe992e12de8 100644 (file)
@@ -12,7 +12,7 @@ index_storage_fetch(struct mailbox_transaction_context *_t, uint32_t seq,
                (struct index_transaction_context *)_t;
         const struct mail_index_record *rec;
 
-       if (mail_index_lookup(t->ibox->view, seq, &rec) < 0) {
+       if (mail_index_lookup(t->trans_view, seq, &rec) < 0) {
                mail_storage_set_index_error(t->ibox);
                return NULL;
        }
index b4428f3ba011deb4f9db60b817248c5c7f7dc840..76a4dd17ca688798cf057edd9f28a69cf4a3b3ef 100644 (file)
@@ -186,7 +186,7 @@ static int mail_find_wanted_headers(struct index_mail *mail,
 {
        int idx;
 
-       idx = find_wanted_headers(mail->ibox->cache_view, wanted_headers);
+       idx = find_wanted_headers(mail->trans->cache_view, wanted_headers);
        if (idx < 0)
                return -1;
 
@@ -434,7 +434,7 @@ static int parse_cached_headers(struct index_mail *mail, int idx)
                data->header_stream = istream;
        } else {
                str = mail_cache_lookup_string_field(
-                       mail->ibox->cache_view, data->seq,
+                       mail->trans->cache_view, data->seq,
                        mail_cache_header_fields[idx]);
                if (str == NULL) {
                        /* broken - we expected the header to exist */
@@ -447,7 +447,7 @@ static int parse_cached_headers(struct index_mail *mail, int idx)
                                                    str, strlen(str));
        }
 
-       idx_headers = mail_cache_get_header_fields(mail->ibox->cache_view,
+       idx_headers = mail_cache_get_header_fields(mail->trans->cache_view,
                                                   idx);
        if (idx_headers == NULL) {
                mail_cache_set_corrupted(mail->ibox->cache,
@@ -511,7 +511,7 @@ int index_mail_parse_headers(struct index_mail *mail)
                 idx = data->header_data_cached; max = idx-1;
                for (; idx < MAIL_CACHE_HEADERS_COUNT; idx++) {
                        str = mail_cache_lookup_string_field(
-                               mail->ibox->cache_view, mail->data.seq,
+                               mail->trans->cache_view, mail->data.seq,
                                mail_cache_header_fields[idx]);
                        if (str == NULL)
                                continue;
@@ -526,7 +526,7 @@ int index_mail_parse_headers(struct index_mail *mail)
                /* make sure we cache everything */
                for (idx = MAIL_CACHE_HEADERS_COUNT-1; idx >= 0; idx--) {
                        headers = mail_cache_get_header_fields(
-                                       mail->ibox->cache_view, idx);
+                                       mail->trans->cache_view, idx);
                        if (headers != NULL)
                                break;
                }
@@ -655,7 +655,7 @@ struct istream *index_mail_get_headers(struct mail *_mail,
                }
                for (i = data->header_data_cached; i <= idx; i++) {
                        str = mail_cache_lookup_string_field(
-                                       mail->ibox->cache_view, data->seq,
+                                       mail->trans->cache_view, data->seq,
                                        mail_cache_header_fields[i]);
                        if (str == NULL)
                                continue;
@@ -687,7 +687,7 @@ struct istream *index_mail_get_headers(struct mail *_mail,
 
 void index_mail_headers_init(struct index_mail *mail)
 {
-       struct mail_cache_view *cache_view = mail->ibox->cache_view;
+       struct mail_cache_view *cache_view = mail->trans->cache_view;
        int idx = -2, idx2 = -2;
 
        if (mail->wanted_headers != NULL && *mail->wanted_headers != NULL)
@@ -769,7 +769,7 @@ void index_mail_headers_close(struct index_mail *mail)
           accessing headers from same message. index_mails should probably be
           shared.. */
        headers = cached_header_get_names(mail);
-       idx = find_wanted_headers(mail->ibox->cache_view, headers);
+       idx = find_wanted_headers(mail->trans->cache_view, headers);
        if (idx >= 0) {
                /* all headers found */
                if (idx != mail->data.header_save_idx) {
@@ -779,7 +779,7 @@ void index_mail_headers_close(struct index_mail *mail)
                }
        } else {
                /* there's some new headers */
-               idx = find_unused_header_idx(mail->ibox->cache_view);
+               idx = find_unused_header_idx(mail->trans->cache_view);
                if (idx < 0)
                        return;
 
index ff7f6d1449215abdc5fb864f8d96a0754c2448b4..5b6eb48cca32eb77f987c0b925a8175901ce36be 100644 (file)
@@ -23,12 +23,12 @@ static struct message_part *get_cached_parts(struct index_mail *mail)
        size_t part_size;
 
        if ((mail->data.cached_fields & MAIL_CACHE_MESSAGEPART) == 0) {
-               mail_cache_mark_missing(mail->ibox->cache_view,
+               mail_cache_mark_missing(mail->trans->cache_view,
                                        MAIL_CACHE_MESSAGEPART);
                return NULL;
        }
 
-       if (!mail_cache_lookup_field(mail->ibox->cache_view, mail->data.seq,
+       if (!mail_cache_lookup_field(mail->trans->cache_view, mail->data.seq,
                                     MAIL_CACHE_MESSAGEPART,
                                     &part_data, &part_size)) {
                /* unexpected - must be an error */
@@ -61,11 +61,11 @@ char *index_mail_get_cached_string(struct index_mail *mail,
        const char *ret;
 
        if ((mail->data.cached_fields & field) == 0) {
-               mail_cache_mark_missing(mail->ibox->cache_view, field);
+               mail_cache_mark_missing(mail->trans->cache_view, field);
                return NULL;
        }
 
-       ret = mail_cache_lookup_string_field(mail->ibox->cache_view,
+       ret = mail_cache_lookup_string_field(mail->trans->cache_view,
                                             mail->data.seq, field);
        return p_strdup(mail->pool, ret);
 }
@@ -75,9 +75,10 @@ uoff_t index_mail_get_cached_uoff_t(struct index_mail *mail,
 {
        uoff_t uoff;
 
-       if (!mail_cache_copy_fixed_field(mail->ibox->cache_view, mail->data.seq,
-                                        field, &uoff, sizeof(uoff))) {
-               mail_cache_mark_missing(mail->ibox->cache_view, field);
+       if (!mail_cache_copy_fixed_field(mail->trans->cache_view,
+                                        mail->data.seq, field,
+                                        &uoff, sizeof(uoff))) {
+               mail_cache_mark_missing(mail->trans->cache_view, field);
                uoff = (uoff_t)-1;
        }
 
@@ -93,10 +94,11 @@ time_t index_mail_get_cached_received_date(struct index_mail *mail)
 {
        time_t t;
 
-       if (!mail_cache_copy_fixed_field(mail->ibox->cache_view, mail->data.seq,
+       if (!mail_cache_copy_fixed_field(mail->trans->cache_view,
+                                        mail->data.seq,
                                         MAIL_CACHE_RECEIVED_DATE,
                                         &t, sizeof(t))) {
-               mail_cache_mark_missing(mail->ibox->cache_view,
+               mail_cache_mark_missing(mail->trans->cache_view,
                                        MAIL_CACHE_RECEIVED_DATE);
                t = (time_t)-1;
        }
@@ -107,10 +109,11 @@ time_t index_mail_get_cached_received_date(struct index_mail *mail)
 static void get_cached_sent_date(struct index_mail *mail,
                                 struct mail_sent_date *sent_date)
 {
-       if (!mail_cache_copy_fixed_field(mail->ibox->cache_view, mail->data.seq,
+       if (!mail_cache_copy_fixed_field(mail->trans->cache_view,
+                                        mail->data.seq,
                                         MAIL_CACHE_SENT_DATE,
                                         sent_date, sizeof(*sent_date))) {
-               mail_cache_mark_missing(mail->ibox->cache_view,
+               mail_cache_mark_missing(mail->trans->cache_view,
                                        MAIL_CACHE_SENT_DATE);
 
                sent_date->time = (time_t)-1;
@@ -123,13 +126,13 @@ int index_mail_cache_transaction_begin(struct index_mail *mail)
        if (mail->trans->cache_trans != NULL)
                return TRUE;
 
-       if (mail_cache_transaction_begin(mail->ibox->cache_view, TRUE,
+       if (mail_cache_transaction_begin(mail->trans->cache_view, TRUE,
                                         mail->trans->trans,
                                         &mail->trans->cache_trans) <= 0)
                return FALSE;
 
-       mail->data.cached_fields = mail_cache_get_fields(mail->ibox->cache_view,
-                                                        mail->data.seq);
+       mail->data.cached_fields =
+               mail_cache_get_fields(mail->trans->cache_view, mail->data.seq);
        return TRUE;
 }
 
@@ -351,14 +354,14 @@ static void index_mail_parse_body(struct index_mail *mail)
                return;
 
        /* update cache_flags */
-       cache_flags = mail_cache_get_record_flags(mail->ibox->cache_view,
+       cache_flags = mail_cache_get_record_flags(mail->trans->cache_view,
                                                  mail->data.seq);
        if (mail->mail.has_nuls)
                cache_flags |= MAIL_INDEX_FLAG_HAS_NULS;
        else
                cache_flags |= MAIL_INDEX_FLAG_HAS_NO_NULS;
 
-       if (!mail_cache_update_record_flags(mail->ibox->cache_view,
+       if (!mail_cache_update_record_flags(mail->trans->cache_view,
                                            mail->data.seq, cache_flags))
                return;
 
@@ -542,9 +545,9 @@ int index_mail_next(struct index_mail *mail,
        p_clear(mail->pool);
 
        data->cached_fields =
-               mail_cache_get_fields(mail->ibox->cache_view, seq);
+               mail_cache_get_fields(mail->trans->cache_view, seq);
        cache_flags = (data->cached_fields & MAIL_CACHE_INDEX_FLAGS) == 0 ? 0 :
-               mail_cache_get_record_flags(mail->ibox->cache_view, seq);
+               mail_cache_get_record_flags(mail->trans->cache_view, seq);
 
        mail->mail.seq = seq;
        mail->mail.uid = rec->uid;
index 8c938f12d51c1d0d2f173c8588e21d8f93782bce..046a5f1e6ae4dc3edd1aecf94d87966db062a0cb 100644 (file)
@@ -21,7 +21,7 @@
 
 struct index_search_context {
         struct mail_search_context mail_ctx;
-       struct index_transaction_context *trans;
+       struct mail_index_view *view;
        struct index_mailbox *ibox;
        char *charset;
        struct mail_search_arg *args;
@@ -601,7 +601,7 @@ static int search_parse_msgset_args(struct index_mailbox *ibox,
        return 0;
 }
 
-static int search_limit_lowwater(struct index_mailbox *ibox,
+static int search_limit_lowwater(struct index_search_context *ctx,
                                 uint32_t uid_lowwater, uint32_t *first_seq)
 {
        uint32_t seq1, seq2;
@@ -609,9 +609,9 @@ static int search_limit_lowwater(struct index_mailbox *ibox,
        if (uid_lowwater == 0)
                return 0;
 
-       if (mail_index_lookup_uid_range(ibox->view, uid_lowwater, (uint32_t)-1,
-                                       &seq1, &seq2) < 0) {
-               mail_storage_set_index_error(ibox);
+       if (mail_index_lookup_uid_range(ctx->view, uid_lowwater,
+                                       (uint32_t)-1, &seq1, &seq2) < 0) {
+               mail_storage_set_index_error(ctx->ibox);
                return -1;
        }
 
@@ -620,7 +620,7 @@ static int search_limit_lowwater(struct index_mailbox *ibox,
        return 0;
 }
 
-static int search_limit_by_flags(struct index_mailbox *ibox,
+static int search_limit_by_flags(struct index_search_context *ctx,
                                  const struct mail_index_header *hdr,
                                 struct mail_search_arg *args,
                                 uint32_t *seq1, uint32_t *seq2)
@@ -640,7 +640,7 @@ static int search_limit_by_flags(struct index_mailbox *ibox,
                                args->match_always = TRUE;
                        } else if (args->not) {
                                /* UNSEEN with lowwater limiting */
-                               if (search_limit_lowwater(ibox,
+                               if (search_limit_lowwater(ctx,
                                                hdr->first_unseen_uid_lowwater,
                                                seq1) < 0)
                                        return -1;
@@ -662,7 +662,7 @@ static int search_limit_by_flags(struct index_mailbox *ibox,
                                args->match_always = TRUE;
                        } else if (!args->not) {
                                /* DELETED with lowwater limiting */
-                               if (search_limit_lowwater(ibox,
+                               if (search_limit_lowwater(ctx,
                                                hdr->first_deleted_uid_lowwater,
                                                seq1) < 0)
                                        return -1;
@@ -678,7 +678,7 @@ static int search_get_seqset(struct index_search_context *ctx,
 {
         const struct mail_index_header *hdr;
 
-       if (mail_index_get_header(ctx->ibox->view, &hdr) < 0) {
+       if (mail_index_get_header(ctx->view, &hdr) < 0) {
                mail_storage_set_index_error(ctx->ibox);
                return -1;
        }
@@ -701,7 +701,7 @@ static int search_get_seqset(struct index_search_context *ctx,
        i_assert(ctx->seq1 <= ctx->seq2);
 
        /* UNSEEN and DELETED in root search level may limit the range */
-       if (search_limit_by_flags(ctx->ibox, hdr, args,
+       if (search_limit_by_flags(ctx, hdr, args,
                                  &ctx->seq1, &ctx->seq2) < 0)
                return -1;
        return 0;
@@ -733,8 +733,8 @@ index_storage_search_init(struct mailbox_transaction_context *_t,
 
        ctx = i_new(struct index_search_context, 1);
        ctx->mail_ctx.box = &t->ibox->box;
-       ctx->trans = t;
        ctx->ibox = t->ibox;
+       ctx->view = t->trans_view;
        ctx->charset = i_strdup(charset);
        ctx->args = args;
 
@@ -815,7 +815,7 @@ struct mail *index_storage_search_next(struct mail_search_context *_ctx)
 
        ret = 0;
        while (ctx->seq1 <= ctx->seq2) {
-               if (mail_index_lookup(ctx->ibox->view, ctx->seq1, &rec) < 0) {
+               if (mail_index_lookup(ctx->view, ctx->seq1, &rec) < 0) {
                        ctx->failed = TRUE;
                        mail_storage_set_index_error(ctx->ibox);
                        return NULL;
index 812aa8bad6930658a0f21b1803d69c92409910c5..e2dab12929eb3624370538ad72e49a15499e0413 100644 (file)
@@ -350,8 +350,6 @@ index_storage_mailbox_init(struct index_storage *storage, struct mailbox *box,
                }
 
                ibox->view = mail_index_view_open(index);
-               ibox->cache_view =
-                       mail_cache_view_open(ibox->cache, ibox->view);
                return ibox;
        } while (0);
 
@@ -364,8 +362,6 @@ void index_storage_mailbox_free(struct mailbox *box)
 {
        struct index_mailbox *ibox = (struct index_mailbox *) box;
 
-       if (ibox->cache_view != NULL)
-               mail_cache_view_close(ibox->cache_view);
        if (ibox->view != NULL)
                mail_index_view_close(ibox->view);
 
index f4e803aff6cd06f26a64bb030d557245769da463..74b786c40b6b5ef34aae21ea2407fe73238678e5 100644 (file)
@@ -58,7 +58,6 @@ struct index_mailbox {
        struct mail_index *index;
        struct mail_index_view *view;
        struct mail_cache *cache;
-       struct mail_cache_view *cache_view;
        struct mail *mail_interface;
 
        uint32_t (*get_recent_count)(struct index_mailbox *ibox);
@@ -112,7 +111,10 @@ struct index_mailbox {
 struct index_transaction_context {
        struct mailbox_transaction_context mailbox_ctx;
        struct index_mailbox *ibox;
+
        struct mail_index_transaction *trans;
+       struct mail_index_view *trans_view;
+       struct mail_cache_view *cache_view;
        struct mail_cache_transaction_ctx *cache_trans;
 
        struct index_mail fetch_mail; /* for index_storage_fetch() */
@@ -182,8 +184,8 @@ index_storage_search_init(struct mailbox_transaction_context *t,
 int index_storage_search_deinit(struct mail_search_context *ctx);
 struct mail *index_storage_search_next(struct mail_search_context *ctx);
 
-struct mailbox_transaction_context *
-index_transaction_begin(struct mailbox *box);
+void index_transaction_init(struct index_transaction_context *t,
+                           struct index_mailbox *ibox, int hide);
 int index_transaction_commit(struct mailbox_transaction_context *t);
 void index_transaction_rollback(struct mailbox_transaction_context *t);
 
index e32d93075741c35a1ff4436d8855ff4af37089c6..b8364e73b01f4bce6ff764a675e8e43d902c937d 100644 (file)
@@ -3,8 +3,22 @@
 #include "lib.h"
 #include "index-storage.h"
 
+void index_transaction_init(struct index_transaction_context *t,
+                           struct index_mailbox *ibox, int hide)
+{
+       t->mailbox_ctx.box = &ibox->box;
+       t->ibox = ibox;
+       t->trans = mail_index_transaction_begin(ibox->view, hide);
+       t->trans_view = mail_index_transaction_get_updated_view(t->trans);
+       t->cache_view = mail_cache_view_open(ibox->cache, t->trans_view);
+}
+
 static void index_transaction_free(struct index_transaction_context *t)
 {
+       if (t->cache_trans != NULL)
+               (void)mail_cache_transaction_end(t->cache_trans);
+
+       mail_cache_view_close(t->cache_view);
        mail_index_view_unlock(t->ibox->view);
 
        if (t->fetch_mail.pool != NULL)
@@ -20,11 +34,8 @@ int index_transaction_commit(struct mailbox_transaction_context *_t)
        uoff_t offset;
        int ret;
 
-       if (t->cache_trans != NULL)  {
+       if (t->cache_trans != NULL)
                (void)mail_cache_transaction_commit(t->cache_trans);
-               (void)mail_cache_transaction_end(t->cache_trans);
-               t->cache_trans = NULL;
-       }
 
        ret = mail_index_transaction_commit(t->trans, &seq, &offset);
        if (ret < 0)
index 6fbb584f2e95afb9cb754c673d5299b4edd85fe0..2d717e16ef4134740b62d5680fa8ad7c92d98b86 100644 (file)
@@ -7,13 +7,11 @@ struct mailbox_transaction_context *
 maildir_transaction_begin(struct mailbox *box, int hide)
 {
        struct index_mailbox *ibox = (struct index_mailbox *)box;
-       struct maildir_transaction_context *ctx;
+       struct maildir_transaction_context *t;
 
-       ctx = i_new(struct maildir_transaction_context, 1);
-       ctx->ictx.mailbox_ctx.box = box;
-       ctx->ictx.ibox = ibox;
-       ctx->ictx.trans = mail_index_transaction_begin(ibox->view, hide);
-       return &ctx->ictx.mailbox_ctx;
+       t = i_new(struct maildir_transaction_context, 1);
+        index_transaction_init(&t->ictx, ibox, hide);
+       return &t->ictx.mailbox_ctx;
 }
 
 int maildir_transaction_commit(struct mailbox_transaction_context *_t)
index 6e5f03c0ac601167334b96503e4b3c6f7d551481..b2156180131415168bdc9c2a288ac38fee547ba0 100644 (file)
@@ -31,7 +31,7 @@ static int mbox_mail_seek(struct index_mail *mail)
        if (mbox_file_open_stream(ibox) < 0)
                return -1;
 
-       ret = mail_index_lookup_extra(ibox->view, mail->mail.seq,
+       ret = mail_index_lookup_extra(mail->trans->trans_view, mail->mail.seq,
                                      ibox->mbox_extra_idx, &data);
        if (ret <= 0) {
                if (ret < 0)
index a65bfe96bb3028ebf6b4dfdb7d83a4ec1c017ec9..da20fa2327739aed594688712a67bda0354e95df 100644 (file)
@@ -179,7 +179,7 @@ static int mbox_save_init_sync(struct mbox_transaction_context *t)
        struct mbox_save_context *ctx = t->save_ctx;
        const struct mail_index_header *hdr;
 
-       if (mail_index_get_header(ctx->ibox->view, &hdr) < 0) {
+       if (mail_index_get_header(t->ictx.trans_view, &hdr) < 0) {
                mail_storage_set_index_error(ctx->ibox);
                return -1;
        }
@@ -345,7 +345,7 @@ int mbox_save(struct mailbox_transaction_context *_t,
        if (mail_r != NULL) {
                const struct mail_index_record *rec;
 
-               if (mail_index_transaction_lookup(ctx->trans, seq, &rec) < 0)
+               if (mail_index_lookup(t->ictx.trans_view, seq, &rec) < 0)
                        return -1;
                if (index_mail_next(&ctx->mail, rec, seq, FALSE) <= 0)
                        return -1;
index eaff99995ab59010dd250cb9cd3661d9267568db..8a13a664b1e5c567c4ec4c07eb26b91712701509 100644 (file)
@@ -12,9 +12,7 @@ mbox_transaction_begin(struct mailbox *box, int hide)
        struct mbox_transaction_context *t;
 
        t = i_new(struct mbox_transaction_context, 1);
-       t->ictx.mailbox_ctx.box = box;
-       t->ictx.ibox = ibox;
-       t->ictx.trans = mail_index_transaction_begin(ibox->view, hide);
+        index_transaction_init(&t->ictx, ibox, hide);
        return &t->ictx.mailbox_ctx;
 }
 
@@ -24,10 +22,11 @@ int mbox_transaction_commit(struct mailbox_transaction_context *_t)
                (struct mbox_transaction_context *)_t;
        struct index_mailbox *ibox = t->ictx.ibox;
        unsigned int lock_id = t->mbox_lock_id;
-       int ret = 0;
+       int mbox_modified, ret = 0;
 
        if (t->save_ctx != NULL)
                ret = mbox_save_commit(t->save_ctx);
+       mbox_modified = t->mbox_modified;
 
        if (ret == 0) {
                if (index_transaction_commit(_t) < 0)
@@ -35,9 +34,10 @@ int mbox_transaction_commit(struct mailbox_transaction_context *_t)
        } else {
                index_transaction_rollback(_t);
        }
+       t = NULL;
 
        if (ret == 0) {
-               if (mbox_sync(ibox, TRUE, t->mbox_modified, FALSE) < 0)
+               if (mbox_sync(ibox, TRUE, mbox_modified, FALSE) < 0)
                        ret = -1;
        }