dovecot-1.2: lib-index: Added support for reading new records ge...
dovecot at dovecot.org
dovecot at dovecot.org
Thu Aug 13 21:51:57 EEST 2009
details: http://hg.dovecot.org/dovecot-1.2/rev/9445831aebc0
changeset: 9318:9445831aebc0
user: Timo Sirainen <tss at iki.fi>
date: Thu Aug 13 14:50:41 2009 -0400
description:
lib-index: Added support for reading new records generated by Dovecot v2.0.
diffstat:
6 files changed, 231 insertions(+), 134 deletions(-)
src/lib-index/mail-index-sync-update.c | 142 +++++++++++++++++-------
src/lib-index/mail-index-sync.c | 14 ++
src/lib-index/mail-index-view-sync.c | 167 +++++++++++++----------------
src/lib-index/mail-transaction-log-file.c | 2
src/lib-index/mail-transaction-log-view.c | 20 +++
src/lib-index/mail-transaction-log.h | 20 +++
diffs (truncated from 545 to 300 lines):
diff -r 1e8edebee242 -r 9445831aebc0 src/lib-index/mail-index-sync-update.c
--- a/src/lib-index/mail-index-sync-update.c Thu Aug 13 12:40:19 2009 -0400
+++ b/src/lib-index/mail-index-sync-update.c Thu Aug 13 14:50:41 2009 -0400
@@ -236,44 +236,81 @@ sync_expunge_call_handlers(struct mail_i
}
}
-static int
-sync_expunge(const struct mail_transaction_expunge *e, unsigned int count,
- struct mail_index_sync_map_ctx *ctx)
+static void
+sync_expunge(struct mail_index_sync_map_ctx *ctx, uint32_t uid1, uint32_t uid2)
{
struct mail_index_map *map = ctx->view->map;
struct mail_index_record *rec;
uint32_t seq_count, seq, seq1, seq2;
- unsigned int i;
-
- for (i = 0; i < count; i++, e++) {
- if (!mail_index_lookup_seq_range(ctx->view, e->uid1, e->uid2,
- &seq1, &seq2)) {
- /* everything expunged already */
- continue;
- }
-
- sync_expunge_call_handlers(ctx, seq1, seq2);
-
- map = mail_index_sync_get_atomic_map(ctx);
- for (seq = seq1; seq <= seq2; seq++) {
- rec = MAIL_INDEX_MAP_IDX(map, seq-1);
- mail_index_sync_header_update_counts(ctx, rec->uid,
- rec->flags, 0,
- FALSE);
- }
-
- /* @UNSAFE */
- memmove(MAIL_INDEX_MAP_IDX(map, seq1-1),
- MAIL_INDEX_MAP_IDX(map, seq2),
- (map->rec_map->records_count - seq2) *
- map->hdr.record_size);
-
- seq_count = seq2 - seq1 + 1;
- map->rec_map->records_count -= seq_count;
- map->hdr.messages_count -= seq_count;
- mail_index_modseq_expunge(ctx->modseq_ctx, seq1, seq2);
- }
- return 1;
+
+ if (!mail_index_lookup_seq_range(ctx->view, uid1, uid2, &seq1, &seq2)) {
+ /* everything expunged already */
+ return;
+ }
+
+ sync_expunge_call_handlers(ctx, seq1, seq2);
+
+ map = mail_index_sync_get_atomic_map(ctx);
+ for (seq = seq1; seq <= seq2; seq++) {
+ rec = MAIL_INDEX_MAP_IDX(map, seq-1);
+ mail_index_sync_header_update_counts(ctx, rec->uid, rec->flags,
+ 0, FALSE);
+ }
+
+ /* @UNSAFE */
+ memmove(MAIL_INDEX_MAP_IDX(map, seq1-1),
+ MAIL_INDEX_MAP_IDX(map, seq2),
+ (map->rec_map->records_count - seq2) * map->hdr.record_size);
+
+ seq_count = seq2 - seq1 + 1;
+ map->rec_map->records_count -= seq_count;
+ map->hdr.messages_count -= seq_count;
+ mail_index_modseq_expunge(ctx->modseq_ctx, seq1, seq2);
+}
+
+static void *sync_append_record(struct mail_index_map *map)
+{
+ size_t append_pos;
+ void *ret;
+
+ append_pos = map->rec_map->records_count * map->hdr.record_size;
+ ret = buffer_get_space_unsafe(map->rec_map->buffer, append_pos,
+ map->hdr.record_size);
+ map->rec_map->records =
+ buffer_get_modifiable_data(map->rec_map->buffer, NULL);
+ return ret;
+}
+
+static void sync_uid_update(struct mail_index_sync_map_ctx *ctx,
+ uint32_t old_uid, uint32_t new_uid)
+{
+ struct mail_index_map *map;
+ struct mail_index_record *rec;
+ uint32_t old_seq;
+ void *dest;
+
+ if (new_uid < ctx->view->map->hdr.next_uid) {
+ /* uid update is no longer possible */
+ return;
+ }
+
+ if (!mail_index_lookup_seq(ctx->view, old_uid, &old_seq))
+ return;
+
+ map = mail_index_sync_get_atomic_map(ctx);
+ map->hdr.next_uid = new_uid+1;
+ map->rec_map->last_appended_uid = new_uid;
+
+ /* add the new record */
+ dest = sync_append_record(map);
+ rec = MAIL_INDEX_MAP_IDX(map, old_seq-1);
+ rec->uid = new_uid;
+ memcpy(dest, rec, map->hdr.record_size);
+
+ /* @UNSAFE: remove the old record */
+ memmove(rec, PTR_OFFSET(rec, map->hdr.record_size),
+ (map->rec_map->records_count + 1 - old_seq) *
+ map->hdr.record_size);
}
void mail_index_sync_write_seq_update(struct mail_index_sync_map_ctx *ctx,
@@ -296,7 +333,6 @@ static int sync_append(const struct mail
const struct mail_index_record *old_rec;
enum mail_flags new_flags;
void *dest;
- size_t append_pos;
if (rec->uid < map->hdr.next_uid) {
mail_index_sync_set_corrupted(ctx,
@@ -322,12 +358,7 @@ static int sync_append(const struct mail
} else {
/* don't rely on buffer->used being at the correct position.
at least expunges can move it */
- append_pos = map->rec_map->records_count * map->hdr.record_size;
- dest = buffer_get_space_unsafe(map->rec_map->buffer, append_pos,
- map->hdr.record_size);
- map->rec_map->records =
- buffer_get_modifiable_data(map->rec_map->buffer, NULL);
-
+ dest = sync_append_record(map);
memcpy(dest, rec, sizeof(*rec));
memset(PTR_OFFSET(dest, sizeof(*rec)), 0,
map->hdr.record_size - sizeof(*rec));
@@ -484,7 +515,21 @@ int mail_index_sync_record(struct mail_i
break;
}
end = CONST_PTR_OFFSET(data, hdr->size);
- ret = sync_expunge(rec, end - rec, ctx);
+ for (; rec != end; rec++)
+ sync_expunge(ctx, rec->uid1, rec->uid2);
+ break;
+ }
+ case MAIL_TRANSACTION_EXPUNGE_GUID:
+ case MAIL_TRANSACTION_EXPUNGE_GUID|MAIL_TRANSACTION_EXPUNGE_PROT: {
+ const struct mail_transaction_expunge_guid *rec = data, *end;
+
+ if ((hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0) {
+ /* this is simply a request for expunge */
+ break;
+ }
+ end = CONST_PTR_OFFSET(data, hdr->size);
+ for (; rec != end; rec++)
+ sync_expunge(ctx, rec->uid, rec->uid);
break;
}
case MAIL_TRANSACTION_FLAG_UPDATE: {
@@ -640,6 +685,19 @@ int mail_index_sync_record(struct mail_i
const struct mail_transaction_keyword_reset *rec = data;
ret = mail_index_sync_keywords_reset(ctx, hdr, rec);
+ break;
+ }
+ case MAIL_TRANSACTION_UID_UPDATE: {
+ const struct mail_transaction_uid_update *rec = data, *end;
+
+ end = CONST_PTR_OFFSET(data, hdr->size);
+ for (rec = data; rec < end; rec++)
+ sync_uid_update(ctx, rec->old_uid, rec->new_uid);
+ break;
+ }
+ case MAIL_TRANSACTION_MODSEQ_UPDATE: {
+ /* just ignore modseq updates. they're not so hugely
+ important. */
break;
}
default:
diff -r 1e8edebee242 -r 9445831aebc0 src/lib-index/mail-index-sync.c
--- a/src/lib-index/mail-index-sync.c Thu Aug 13 12:40:19 2009 -0400
+++ b/src/lib-index/mail-index-sync.c Thu Aug 13 14:50:41 2009 -0400
@@ -41,6 +41,16 @@ static void mail_index_sync_add_expunge(
}
}
+static void mail_index_sync_add_expunge_guid(struct mail_index_sync_ctx *ctx)
+{
+ const struct mail_transaction_expunge_guid *e = ctx->data;
+ size_t i, size = ctx->hdr->size / sizeof(*e);
+
+ for (i = 0; i < size; i++)
+ mail_index_expunge(ctx->sync_trans, e[i].uid);
+}
+
+
static void mail_index_sync_add_flag_update(struct mail_index_sync_ctx *ctx)
{
const struct mail_transaction_flag_update *u = ctx->data;
@@ -128,6 +138,9 @@ static bool mail_index_sync_add_transact
switch (ctx->hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
case MAIL_TRANSACTION_EXPUNGE:
mail_index_sync_add_expunge(ctx);
+ break;
+ case MAIL_TRANSACTION_EXPUNGE_GUID:
+ mail_index_sync_add_expunge_guid(ctx);
break;
case MAIL_TRANSACTION_FLAG_UPDATE:
mail_index_sync_add_flag_update(ctx);
@@ -509,6 +522,7 @@ static bool mail_index_sync_view_have_an
to be synced, but cache syncing relies on tail
offsets being updated. */
case MAIL_TRANSACTION_EXPUNGE:
+ case MAIL_TRANSACTION_EXPUNGE_GUID:
case MAIL_TRANSACTION_FLAG_UPDATE:
case MAIL_TRANSACTION_KEYWORD_UPDATE:
case MAIL_TRANSACTION_KEYWORD_RESET:
diff -r 1e8edebee242 -r 9445831aebc0 src/lib-index/mail-index-view-sync.c
--- a/src/lib-index/mail-index-view-sync.c Thu Aug 13 12:40:19 2009 -0400
+++ b/src/lib-index/mail-index-view-sync.c Thu Aug 13 14:50:41 2009 -0400
@@ -40,71 +40,6 @@ struct mail_index_view_sync_ctx {
unsigned int log_was_lost:1;
unsigned int hidden:1;
};
-
-static int
-mail_transaction_log_sort_expunges(ARRAY_TYPE(seq_range) *expunges,
- const struct seq_range *src, size_t src_size)
-{
- /* Note that all the sequences are actually still UIDs at this point */
- const struct seq_range *src_end;
- struct seq_range *dest, new_exp;
- unsigned int first, i, dest_count;
-
- i_assert(src_size % sizeof(*src) == 0);
-
- /* @UNSAFE */
- dest = array_get_modifiable(expunges, &dest_count);
- if (dest_count == 0) {
- array_append(expunges, src, src_size / sizeof(*src));
- return 0;
- }
-
- src_end = CONST_PTR_OFFSET(src, src_size);
- for (i = 0; src != src_end; src++) {
- /* src[] must be sorted. */
- if (src->seq1 > src->seq2 ||
- (src+1 != src_end && src->seq2 >= src[1].seq1))
- return -1;
-
- for (; i < dest_count; i++) {
- if (src->seq1 < dest[i].seq1)
- break;
- }
-
- new_exp = *src;
-
- first = i;
- while (i < dest_count && src->seq2 >= dest[i].seq1-1) {
- /* we can/must merge with next record */
- if (new_exp.seq2 < dest[i].seq2)
- new_exp.seq2 = dest[i].seq2;
- i++;
- }
-
- if (first > 0 && new_exp.seq1 <= dest[first-1].seq2+1) {
- /* continue previous record */
- if (dest[first-1].seq2 < new_exp.seq2)
- dest[first-1].seq2 = new_exp.seq2;
- } else if (i == first) {
- array_insert(expunges, i, &new_exp, 1);
- i++; first++;
-
- dest = array_get_modifiable(expunges, &dest_count);
- } else {
- /* use next record */
- dest[first] = new_exp;
- first++;
- }
-
- if (i > first) {
- array_delete(expunges, first, i - first);
-
- dest = array_get_modifiable(expunges, &dest_count);
- i = first;
- }
- }
- return 0;
-}
static int
view_sync_set_log_view_range(struct mail_index_view *view, bool sync_expunges,
@@ -175,6 +110,33 @@ view_sync_expunges2seqs(struct mail_inde
return expunge_count;
}
More information about the dovecot-cvs
mailing list