[dovecot-cvs] dovecot/src/lib-index Makefile.am, 1.24,
1.25 mail-index-dummy-view.c, NONE,
1.1 mail-index-sync-private.h, 1.19, 1.20 mail-index-sync.c,
1.45, 1.46 mail-index-transaction.c, 1.43,
1.44 mail-index-view-private.h, 1.16, 1.17
cras at dovecot.org
cras at dovecot.org
Sat Jan 22 18:56:39 EET 2005
Update of /var/lib/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv20144
Modified Files:
Makefile.am mail-index-sync-private.h mail-index-sync.c
mail-index-transaction.c mail-index-view-private.h
Added Files:
mail-index-dummy-view.c
Log Message:
Instead of using separate transaction sorting code for syncing, just put the
data from transactions into a temporary transaction and read it from there.
Index: Makefile.am
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/Makefile.am,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- Makefile.am 26 Dec 2004 09:12:40 -0000 1.24
+++ Makefile.am 22 Jan 2005 16:56:37 -0000 1.25
@@ -13,6 +13,7 @@
mail-cache-transaction.c \
mail-cache-sync-update.c \
mail-index.c \
+ mail-index-dummy-view.c \
mail-index-fsck.c \
mail-index-lock.c \
mail-index-transaction.c \
--- NEW FILE: mail-index-dummy-view.c ---
/* Copyright (C) 2004 Timo Sirainen */
#include "lib.h"
#include "mail-index-private.h"
#include "mail-index-view-private.h"
static void _dummy_view_close(struct mail_index_view *view __attr_unused__)
{
i_assert(view->refcount == 0);
i_free(view);
}
static uint32_t
_dummy_view_get_message_count(struct mail_index_view *view __attr_unused__)
{
return (uint32_t)-3;
}
static struct mail_index_view_methods dummy_view_methods = {
_dummy_view_close,
_dummy_view_get_message_count,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
struct mail_index_view *mail_index_dummy_view_open(void)
{
struct mail_index_view *view;
view = i_new(struct mail_index_view, 1);
view->refcount = 1;
view->methods = dummy_view_methods;
return view;
}
Index: mail-index-sync-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync-private.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- mail-index-sync-private.h 10 Jan 2005 17:37:22 -0000 1.19
+++ mail-index-sync-private.h 22 Jan 2005 16:56:37 -0000 1.20
@@ -6,8 +6,7 @@
struct mail_index_sync_ctx {
struct mail_index *index;
struct mail_index_view *view;
-
- buffer_t *expunges_buf, *updates_buf;
+ struct mail_index_transaction *trans;
const struct mail_transaction_expunge *expunges;
const struct mail_transaction_flag_update *updates;
Index: mail-index-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -d -r1.45 -r1.46
--- mail-index-sync.c 26 Dec 2004 09:12:40 -0000 1.45
+++ mail-index-sync.c 22 Jan 2005 16:56:37 -0000 1.46
@@ -4,130 +4,73 @@
#include "buffer.h"
#include "mail-index-view-private.h"
#include "mail-index-sync-private.h"
+#include "mail-index-transaction-private.h"
#include "mail-transaction-log-private.h"
#include "mail-transaction-util.h"
#include "mail-cache.h"
#include <stdlib.h>
-static void
-mail_index_sync_sort_flags(buffer_t *dest_buf,
- const struct mail_transaction_flag_update *src,
- size_t src_size)
+static void mail_index_sync_add_expunge(struct mail_index_sync_ctx *ctx)
{
- const struct mail_transaction_flag_update *src_end;
- struct mail_transaction_flag_update *dest;
- struct mail_transaction_flag_update new_update, tmp_update;
- size_t i, dest_count;
-
- dest = buffer_get_modifyable_data(dest_buf, &dest_count);
- dest_count /= sizeof(*dest);
+ const struct mail_transaction_expunge *e = ctx->data;
+ size_t i, size = ctx->hdr->size / sizeof(*e);
+ uint32_t uid;
- if (dest_count == 0) {
- buffer_append(dest_buf, src, src_size);
- return;
+ for (i = 0; i < size; i++) {
+ for (uid = e[i].uid1; uid <= e[i].uid2; uid++)
+ mail_index_expunge(ctx->trans, uid);
}
+}
- src_end = PTR_OFFSET(src, src_size);
- for (i = 0; src != src_end; src++) {
- new_update = *src;
-
- /* insert it into buffer, split and merge it with existing
- updates if needed. */
- for (; i < dest_count; i++) {
- if (new_update.uid1 > dest[i].uid2)
- continue;
-
- if (new_update.uid2 < dest[i].uid1)
- break;
+static void mail_index_sync_add_flag_update(struct mail_index_sync_ctx *ctx)
+{
+ const struct mail_transaction_flag_update *u = ctx->data;
+ size_t i, size = ctx->hdr->size / sizeof(*u);
- /* at least partially overlapping */
+ for (i = 0; i < size; i++) {
+ if (u[i].add_flags != 0) {
+ mail_index_update_flags_range(ctx->trans,
+ u[i].uid1, u[i].uid2,
+ MODIFY_ADD,
+ u[i].add_flags);
+ }
+ if (u[i].remove_flags != 0) {
+ mail_index_update_flags_range(ctx->trans,
+ u[i].uid1, u[i].uid2,
+ MODIFY_REMOVE,
+ u[i].remove_flags);
+ }
+ }
+}
- if (new_update.uid1 < dest[i].uid1) {
- /* { 5..6 } + { 1..5 } -> { 1..4 } + { 5..6 } */
- tmp_update = new_update;
- tmp_update.uid2 = dest[i].uid1-1;
- new_update.uid1 = dest[i].uid1;
- buffer_insert(dest_buf, i * sizeof(tmp_update),
- &tmp_update, sizeof(tmp_update));
- dest = buffer_get_modifyable_data(dest_buf,
- NULL);
- dest_count++; i++;
- } else if (new_update.uid1 > dest[i].uid1) {
- /* { 5..7 } + { 6..6 } ->
- split old to { 5..5 } + { 6..7 } */
- tmp_update = dest[i];
- tmp_update.uid2 = new_update.uid1-1;
- dest[i].uid1 = new_update.uid1;
- buffer_insert(dest_buf, i * sizeof(tmp_update),
- &tmp_update, sizeof(tmp_update));
- dest = buffer_get_modifyable_data(dest_buf,
- NULL);
- dest_count++; i++;
- }
- i_assert(new_update.uid1 == dest[i].uid1);
+static void mail_index_sync_add_append(struct mail_index_sync_ctx *ctx)
+{
+ const struct mail_index_record *rec = ctx->data;
- if (new_update.uid2 < dest[i].uid2) {
- /* { 5..7 } + { 5..6 } -> { 5..6 } + { 7..7 } */
- tmp_update = dest[i];
- tmp_update.uid1 = new_update.uid2+1;
- dest[i].uid2 = new_update.uid2;
- buffer_insert(dest_buf,
- (i+1) * sizeof(tmp_update),
- &tmp_update, sizeof(tmp_update));
- dest = buffer_get_modifyable_data(dest_buf,
- NULL);
- dest_count++;
- new_update.uid2 = 0;
- } else {
- /* full match, or continues. */
- new_update.uid1 = dest[i].uid2+1;
- }
+ if (ctx->append_uid_first == 0 || rec->uid < ctx->append_uid_first)
+ ctx->append_uid_first = rec->uid;
- /* dest[i] now contains the overlapping area.
- merge them - new_update overrides old changes. */
- dest[i].add_flags |= new_update.add_flags;
- dest[i].add_flags &= ~new_update.remove_flags;
- dest[i].remove_flags |= new_update.remove_flags;
- dest[i].remove_flags &= ~new_update.add_flags;
- }
+ rec = CONST_PTR_OFFSET(ctx->data, ctx->hdr->size - sizeof(*rec));
+ if (rec->uid > ctx->append_uid_last)
+ ctx->append_uid_last = rec->uid;
- if (new_update.uid1 <= new_update.uid2) {
- buffer_insert(dest_buf, i * sizeof(new_update),
- &new_update, sizeof(new_update));
- dest = buffer_get_modifyable_data(dest_buf, NULL);
- dest_count++;
- }
- }
+ ctx->sync_appends = TRUE;
}
-static void mail_index_sync_sort_transaction(struct mail_index_sync_ctx *ctx)
+static void mail_index_sync_add_transaction(struct mail_index_sync_ctx *ctx)
{
switch (ctx->hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
case MAIL_TRANSACTION_EXPUNGE:
- mail_transaction_log_sort_expunges(ctx->expunges_buf,
- ctx->data, ctx->hdr->size);
+ mail_index_sync_add_expunge(ctx);
break;
case MAIL_TRANSACTION_FLAG_UPDATE:
- mail_index_sync_sort_flags(ctx->updates_buf, ctx->data,
- ctx->hdr->size);
+ mail_index_sync_add_flag_update(ctx);
break;
- case MAIL_TRANSACTION_APPEND: {
- const struct mail_index_record *rec = ctx->data;
-
- if (ctx->append_uid_first == 0 ||
- rec->uid < ctx->append_uid_first)
- ctx->append_uid_first = rec->uid;
-
- rec = CONST_PTR_OFFSET(ctx->data,
- ctx->hdr->size - sizeof(*rec));
- if (rec->uid > ctx->append_uid_last)
- ctx->append_uid_last = rec->uid;
-
- ctx->sync_appends = TRUE;
+ case MAIL_TRANSACTION_APPEND:
+ mail_index_sync_add_append(ctx);
break;
}
- }
}
static int mail_index_sync_add_dirty_updates(struct mail_index_sync_ctx *ctx)
@@ -146,48 +89,26 @@
if ((rec->flags & MAIL_INDEX_MAIL_FLAG_DIRTY) == 0)
continue;
- update.uid1 = update.uid2 = rec->uid;
- update.add_flags = rec->flags;
- update.remove_flags = ~update.add_flags;
-
- mail_index_sync_sort_flags(ctx->updates_buf,
- &update, sizeof(update));
+ mail_index_update_flags(ctx->trans, rec->uid,
+ MODIFY_REPLACE, rec->flags);
}
return 0;
}
static int mail_index_sync_add_recent_updates(struct mail_index_sync_ctx *ctx)
{
- struct mail_transaction_flag_update update;
const struct mail_index_record *rec;
uint32_t seq, messages_count;
- memset(&update, 0, sizeof(update));
-
messages_count = mail_index_view_get_messages_count(ctx->view);
for (seq = 1; seq <= messages_count; seq++) {
if (mail_index_lookup(ctx->view, seq, &rec) < 0)
return -1;
- if ((rec->flags & MAIL_RECENT) == 0) {
- if (update.uid1 != 0) {
- mail_index_sync_sort_flags(ctx->updates_buf,
- &update,
- sizeof(update));
- update.uid1 = 0;
- }
- continue;
+ if ((rec->flags & MAIL_RECENT) != 0) {
+ mail_index_update_flags(ctx->trans, rec->uid,
+ MODIFY_REMOVE, MAIL_RECENT);
}
-
- /* group updates together as much as possible */
- if (update.uid1 == 0)
- update.uid1 = rec->uid;
- update.uid2 = rec->uid;
- }
-
- if (update.uid1 != 0) {
- mail_index_sync_sort_flags(ctx->updates_buf,
- &update, sizeof(update));
}
return 0;
}
@@ -219,14 +140,21 @@
if ((ctx->hdr->type & MAIL_TRANSACTION_EXTERNAL) != 0)
*seen_external_r = TRUE;
else
- mail_index_sync_sort_transaction(ctx);
+ mail_index_sync_add_transaction(ctx);
}
- ctx->expunges = buffer_get_data(ctx->expunges_buf, &size);
- ctx->expunges_count = size / sizeof(*ctx->expunges);
- ctx->updates = buffer_get_data(ctx->updates_buf, &size);
- ctx->updates_count = size / sizeof(*ctx->updates);
-
+ if (ctx->trans->expunges == NULL)
+ ctx->expunges_count = 0;
+ else {
+ ctx->expunges = buffer_get_data(ctx->trans->expunges, &size);
+ ctx->expunges_count = size / sizeof(*ctx->expunges);
+ }
+ if (ctx->trans->updates == NULL)
+ ctx->updates_count = 0;
+ else {
+ ctx->updates = buffer_get_data(ctx->trans->updates, &size);
+ ctx->updates_count = size / sizeof(*ctx->updates);
+ }
return ret;
}
@@ -284,6 +212,7 @@
int sync_recent, int sync_dirty)
{
struct mail_index_sync_ctx *ctx;
+ struct mail_index_view *dummy_view;
uint32_t seq;
uoff_t offset;
unsigned int lock_id = 0;
@@ -325,6 +254,10 @@
ctx->view = mail_index_view_open(index);
+ dummy_view = mail_index_dummy_view_open();
+ ctx->trans = mail_index_transaction_begin(dummy_view, FALSE, TRUE);
+ mail_index_view_close(dummy_view);
+
if (index->hdr->log_file_seq == seq &&
index->hdr->log_file_int_offset > offset) {
/* synced offset is greater than what we have available.
@@ -378,8 +311,6 @@
/* we need to have all the transactions sorted to optimize
caller's mailbox access patterns */
- ctx->expunges_buf = buffer_create_dynamic(default_pool, 1024);
- ctx->updates_buf = buffer_create_dynamic(default_pool, 1024);
if (mail_index_sync_read_and_sort(ctx, sync_recent,
&seen_external) < 0) {
mail_index_sync_rollback(ctx);
@@ -497,14 +428,12 @@
static void mail_index_sync_end(struct mail_index_sync_ctx *ctx)
{
mail_index_unlock(ctx->index, ctx->lock_id);
- i_assert(!ctx->index->map->write_to_disk);
+
+ i_assert(!ctx->index->map->write_to_disk);
mail_transaction_log_sync_unlock(ctx->index->log);
- mail_index_view_close(ctx->view);
- if (ctx->expunges_buf != NULL)
- buffer_free(ctx->expunges_buf);
- if (ctx->updates_buf != NULL)
- buffer_free(ctx->updates_buf);
+ mail_index_view_close(ctx->view);
+ mail_index_transaction_rollback(ctx->trans);
i_free(ctx);
}
Index: mail-index-transaction.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-transaction.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- mail-index-transaction.c 22 Jan 2005 16:45:24 -0000 1.43
+++ mail-index-transaction.c 22 Jan 2005 16:56:37 -0000 1.44
@@ -22,6 +22,7 @@
/* don't allow syncing view while there's ongoing transactions */
mail_index_view_transaction_ref(view);
+ mail_index_view_ref(view);
t = i_new(struct mail_index_transaction, 1);
t->refcount = 1;
@@ -66,8 +67,6 @@
buffer_t **recs;
size_t i, size;
- mail_index_view_transaction_unref(t->view);
-
if (t->ext_rec_updates != NULL) {
recs = buffer_get_modifyable_data(t->ext_rec_updates, &size);
size /= sizeof(*recs);
@@ -100,6 +99,9 @@
buffer_free(t->ext_resizes);
if (t->ext_resets != NULL)
buffer_free(t->ext_resets);
+
+ mail_index_view_transaction_unref(t->view);
+ mail_index_view_close(t->view);
i_free(t);
}
Index: mail-index-view-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-view-private.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- mail-index-view-private.h 28 Nov 2004 23:19:53 -0000 1.16
+++ mail-index-view-private.h 22 Jan 2005 16:56:37 -0000 1.17
@@ -54,7 +54,6 @@
void mail_index_view_clone(struct mail_index_view *dest,
const struct mail_index_view *src);
void mail_index_view_ref(struct mail_index_view *view);
-void mail_index_view_unref(struct mail_index_view *view);
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_unref_maps(struct mail_index_view *view);
@@ -62,4 +61,6 @@
uint32_t log_file_seq,
uoff_t log_file_offset);
+struct mail_index_view *mail_index_dummy_view_open(void);
+
#endif
More information about the dovecot-cvs
mailing list