dovecot-1.2: Keep modseqs as 1 until the first modseq ext intro ...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Jun 21 15:06:52 EEST 2008
details: http://hg.dovecot.org/dovecot-1.2/rev/502cfdcc5650
changeset: 7931:502cfdcc5650
user: Timo Sirainen <tss at iki.fi>
date: Sat Jun 21 15:06:46 2008 +0300
description:
Keep modseqs as 1 until the first modseq ext intro record enables them.
Performance should be better again when modseqs are disabled.
diffstat:
7 files changed, 139 insertions(+), 80 deletions(-)
src/lib-index/mail-index-modseq.c | 4
src/lib-index/mail-index-modseq.h | 2
src/lib-index/mail-transaction-log-append.c | 43 +++++--
src/lib-index/mail-transaction-log-file.c | 142 +++++++++++++++++---------
src/lib-index/mail-transaction-log-private.h | 4
src/lib-index/mail-transaction-log-view.c | 8 -
src/util/logview.c | 16 +-
diffs (truncated from 464 to 300 lines):
diff -r b4286cde68d0 -r 502cfdcc5650 src/lib-index/mail-index-modseq.c
--- a/src/lib-index/mail-index-modseq.c Sat Jun 21 14:03:59 2008 +0300
+++ b/src/lib-index/mail-index-modseq.c Sat Jun 21 15:06:46 2008 +0300
@@ -6,8 +6,6 @@
#include "mail-index-private.h"
#include "mail-index-sync-private.h"
#include "mail-index-modseq.h"
-
-#define MAIL_INDEX_MODSEQ_EXT_NAME "modseq"
ARRAY_DEFINE_TYPE(modseqs, uint64_t);
@@ -51,7 +49,7 @@ static uint64_t mail_index_modseq_get_he
static uint64_t mail_index_modseq_get_head(struct mail_index *index)
{
return index->log->head == NULL ? 1 :
- index->log->head->sync_highest_modseq;
+ I_MAX(index->log->head->sync_highest_modseq, 1);
}
void mail_index_modseq_enable(struct mail_index *index)
diff -r b4286cde68d0 -r 502cfdcc5650 src/lib-index/mail-index-modseq.h
--- a/src/lib-index/mail-index-modseq.h Sat Jun 21 14:03:59 2008 +0300
+++ b/src/lib-index/mail-index-modseq.h Sat Jun 21 15:06:46 2008 +0300
@@ -1,5 +1,7 @@
#ifndef MAIL_INDEX_MODSEQ_H
#define MAIL_INDEX_MODSEQ_H
+
+#define MAIL_INDEX_MODSEQ_EXT_NAME "modseq"
enum mail_flags;
struct mail_keywords;
diff -r b4286cde68d0 -r 502cfdcc5650 src/lib-index/mail-transaction-log-append.c
--- a/src/lib-index/mail-transaction-log-append.c Sat Jun 21 14:03:59 2008 +0300
+++ b/src/lib-index/mail-transaction-log-append.c Sat Jun 21 15:06:46 2008 +0300
@@ -6,6 +6,7 @@
#include "write-full.h"
#include "mail-index-private.h"
#include "mail-index-view-private.h"
+#include "mail-index-modseq.h"
#include "mail-index-transaction-private.h"
#include "mail-transaction-log-private.h"
@@ -14,7 +15,7 @@ struct log_append_context {
struct mail_index_transaction *trans;
buffer_t *output;
- unsigned int modseq_change_count;
+ uint64_t modseq;
uint32_t first_append_size;
bool sync_includes_this;
};
@@ -25,6 +26,7 @@ static void log_append_buffer(struct log
{
struct mail_transaction_header hdr;
uint32_t hdr_size;
+ size_t hdr_pos;
i_assert((type & MAIL_TRANSACTION_TYPE_MASK) != 0);
i_assert((buf->used % 4) == 0);
@@ -39,26 +41,31 @@ static void log_append_buffer(struct log
hdr.type |= MAIL_TRANSACTION_EXPUNGE_PROT;
if ((ctx->trans->flags & MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL) != 0)
hdr.type |= MAIL_TRANSACTION_EXTERNAL;
-
- if (mail_transaction_header_has_modseq(&hdr))
- ctx->modseq_change_count++;
-
- hdr_size = mail_index_uint32_to_offset(sizeof(hdr) + buf->used +
- (hdr_buf == NULL ? 0 :
- hdr_buf->used));
+ hdr.size = sizeof(hdr) + buf->used +
+ (hdr_buf == NULL ? 0 : hdr_buf->used);
+
+ hdr_pos = ctx->output->used;
+ buffer_append(ctx->output, &hdr, sizeof(hdr));
+ if (hdr_buf != NULL)
+ buffer_append(ctx->output, hdr_buf->data, hdr_buf->used);
+ buffer_append(ctx->output, buf->data, buf->used);
+
+ if (mail_transaction_header_has_modseq(buf->data,
+ CONST_PTR_OFFSET(buf->data, sizeof(hdr)), ctx->modseq))
+ ctx->modseq++;
+
+ /* update the size */
+ hdr_size = mail_index_uint32_to_offset(hdr.size);
if (!MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(ctx->file) &&
ctx->first_append_size == 0) {
/* size will be written later once everything
is in disk */
ctx->first_append_size = hdr_size;
+ hdr.size = 0;
} else {
hdr.size = hdr_size;
}
-
- buffer_append(ctx->output, &hdr, sizeof(hdr));
- if (hdr_buf != NULL)
- buffer_append(ctx->output, hdr_buf->data, hdr_buf->used);
- buffer_append(ctx->output, buf->data, buf->used);
+ buffer_write(ctx->output, hdr_pos, &hdr, sizeof(hdr));
}
static int log_buffer_move_to_memory(struct log_append_context *ctx)
@@ -280,9 +287,14 @@ static void log_append_ext_intro(struct
/* new extension, reset_id defaults to 0 */
}
buffer_append(buf, rext->name, intro->name_size);
-
if ((buf->used % 4) != 0)
buffer_append_zero(buf, 4 - (buf->used % 4));
+
+ if (ctx->file->sync_highest_modseq == 0 &&
+ strcmp(rext->name, MAIL_INDEX_MODSEQ_EXT_NAME) == 0) {
+ /* modseq tracking started */
+ ctx->file->sync_highest_modseq = 1;
+ }
log_append_buffer(ctx, buf, NULL, MAIL_TRANSACTION_EXT_INTRO);
}
@@ -601,6 +613,7 @@ mail_transaction_log_append_locked(struc
ctx.file = file;
ctx.trans = t;
ctx.output = buffer_create_dynamic(default_pool, 1024);
+ ctx.modseq = file->sync_highest_modseq;
/* send all extension introductions and resizes before appends
to avoid resize overhead as much as possible */
@@ -674,7 +687,7 @@ mail_transaction_log_append_locked(struc
buffer_free(&ctx.output);
return -1;
}
- file->sync_highest_modseq += ctx.modseq_change_count;
+ file->sync_highest_modseq = ctx.modseq;
buffer_free(&ctx.output);
if ((t->flags & MAIL_INDEX_TRANSACTION_FLAG_HIDE) != 0) {
diff -r b4286cde68d0 -r 502cfdcc5650 src/lib-index/mail-transaction-log-file.c
--- a/src/lib-index/mail-transaction-log-file.c Sat Jun 21 14:03:59 2008 +0300
+++ b/src/lib-index/mail-transaction-log-file.c Sat Jun 21 15:06:46 2008 +0300
@@ -102,45 +102,62 @@ void mail_transaction_log_file_free(stru
}
static void
-mail_transaction_log_file_add_to_list(struct mail_transaction_log_file *file)
+mail_transaction_log_file_skip_to_head(struct mail_transaction_log_file *file)
{
struct mail_transaction_log *log = file->log;
- struct mail_transaction_log_file **p;
struct mail_index_map *map = log->index->map;
const struct mail_index_modseq_header *modseq_hdr;
-
- if (map != NULL && file->hdr.file_seq == map->hdr.log_file_seq &&
- map->hdr.log_file_head_offset != 0) {
- /* we can get a valid log offset from index file. initialize
- sync_offset from it so we don't have to read the whole log
- file from beginning. */
- uoff_t head_offset = map->hdr.log_file_head_offset;
-
- modseq_hdr = mail_index_map_get_modseq_header(map);
- if (head_offset < file->hdr.hdr_size) {
- mail_index_set_error(log->index,
- "%s: log_file_head_offset too small",
- log->index->filepath);
- file->sync_offset = file->hdr.hdr_size;
- file->sync_highest_modseq = file->hdr.initial_modseq;
- } else if (modseq_hdr == NULL ||
- modseq_hdr->log_seq != file->hdr.file_seq ||
- modseq_hdr->log_offset != head_offset) {
- /* highest_modseq not synced, start from beginning */
- file->sync_offset = file->hdr.hdr_size;
- file->sync_highest_modseq = file->hdr.initial_modseq;
- } else {
- file->sync_offset = head_offset;
- file->sync_highest_modseq = modseq_hdr->highest_modseq;
- }
- file->saved_tail_offset = map->hdr.log_file_tail_offset;
- } else {
+ uoff_t head_offset;
+
+ if (map == NULL || file->hdr.file_seq != map->hdr.log_file_seq ||
+ map->hdr.log_file_head_offset == 0)
+ return;
+
+ /* we can get a valid log offset from index file. initialize
+ sync_offset from it so we don't have to read the whole log
+ file from beginning. */
+ head_offset = map->hdr.log_file_head_offset;
+
+ modseq_hdr = mail_index_map_get_modseq_header(map);
+ if (head_offset < file->hdr.hdr_size) {
+ mail_index_set_error(log->index,
+ "%s: log_file_head_offset too small",
+ log->index->filepath);
file->sync_offset = file->hdr.hdr_size;
file->sync_highest_modseq = file->hdr.initial_modseq;
- }
+ } else if (modseq_hdr == NULL && file->hdr.initial_modseq == 0) {
+ /* modseqs not used yet */
+ file->sync_offset = head_offset;
+ file->sync_highest_modseq = 0;
+ } else if (modseq_hdr->log_seq != file->hdr.file_seq) {
+ /* highest_modseq not synced, start from beginning */
+ file->sync_offset = file->hdr.hdr_size;
+ file->sync_highest_modseq = file->hdr.initial_modseq;
+ } else if (modseq_hdr->log_offset > head_offset) {
+ mail_index_set_error(log->index,
+ "%s: modseq_hdr.log_offset too large",
+ log->index->filepath);
+ file->sync_offset = file->hdr.hdr_size;
+ file->sync_highest_modseq = file->hdr.initial_modseq;
+ } else {
+ /* start from where we last stopped tracking modseqs */
+ file->sync_offset = modseq_hdr->log_offset;
+ file->sync_highest_modseq = modseq_hdr->highest_modseq;
+ }
+ file->saved_tail_offset = log->index->map->hdr.log_file_tail_offset;
+}
+
+static void
+mail_transaction_log_file_add_to_list(struct mail_transaction_log_file *file)
+{
+ struct mail_transaction_log_file **p;
+
+ file->sync_offset = file->hdr.hdr_size;
+ file->sync_highest_modseq = file->hdr.initial_modseq;
+ mail_transaction_log_file_skip_to_head(file);
/* insert it to correct position */
- for (p = &log->files; *p != NULL; p = &(*p)->next) {
+ for (p = &file->log->files; *p != NULL; p = &(*p)->next) {
if ((*p)->hdr.file_seq > file->hdr.file_seq)
break;
i_assert((*p)->hdr.file_seq < file->hdr.file_seq);
@@ -179,7 +196,8 @@ mail_transaction_log_init_hdr(struct mai
hdr->prev_file_seq = index->map->hdr.log_file_seq;
hdr->prev_file_offset = index->map->hdr.log_file_head_offset;
hdr->file_seq = index->map->hdr.log_file_seq + 1;
- hdr->initial_modseq =
+ hdr->initial_modseq = log->head == NULL ||
+ log->head->sync_highest_modseq == 0 ? 0 :
mail_index_map_modseq_get_highest(index->map);
} else {
hdr->file_seq = 1;
@@ -368,8 +386,6 @@ mail_transaction_log_file_read_hdr(struc
shouldn't have filled */
memset(PTR_OFFSET(&file->hdr, file->hdr.hdr_size), 0,
sizeof(file->hdr) - file->hdr.hdr_size);
- if (file->hdr.minor_version == 0)
- file->hdr.initial_modseq = 1;
}
if (file->hdr.indexid == 0) {
@@ -524,7 +540,7 @@ mail_transaction_log_file_create2(struct
if (reset) {
file->hdr.prev_file_seq = 0;
file->hdr.prev_file_offset = 0;
- file->hdr.initial_modseq = 1;
+ file->hdr.initial_modseq = 0;
}
if (write_full(new_fd, &file->hdr, sizeof(file->hdr)) < 0) {
@@ -724,8 +740,31 @@ log_file_track_mailbox_sync_offset_hdr(s
}
bool
-mail_transaction_header_has_modseq(const struct mail_transaction_header *hdr)
-{
+mail_transaction_header_has_modseq(const struct mail_transaction_header *hdr,
+ const void *data,
+ uint64_t cur_modseq)
+{
+ if (cur_modseq != 0) {
+ /* tracking modseqs */
+ } else if ((hdr->type & MAIL_TRANSACTION_TYPE_MASK) ==
+ MAIL_TRANSACTION_EXT_INTRO) {
+ /* modseqs not tracked yet. see if this is a modseq
+ extension introduction. */
+ const struct mail_transaction_ext_intro *intro = data;
+ const unsigned int modseq_ext_len =
+ strlen(MAIL_INDEX_MODSEQ_EXT_NAME);
+
+ if (intro->name_size == modseq_ext_len &&
+ memcmp(intro + 1, MAIL_INDEX_MODSEQ_EXT_NAME,
+ modseq_ext_len) == 0) {
+ /* modseq tracking started */
+ return TRUE;
+ }
+ } else {
+ /* not tracking modseqs */
+ return FALSE;
+ }
+
switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
case MAIL_TRANSACTION_EXPUNGE | MAIL_TRANSACTION_EXPUNGE_PROT:
if ((hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0) {
@@ -882,7 +921,8 @@ int mail_transaction_log_file_get_highes
while (cur_offset < offset) {
if (log_get_synced_record(file, &cur_offset, &hdr) < 0)
return- 1;
More information about the dovecot-cvs
mailing list