Mercurial > dovecot > original-hg > dovecot-1.2
changeset 2762:a1c7e92c1839 HEAD
New way of handling extension introductions in transaction log.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 17 Oct 2004 21:24:21 +0300 |
parents | f96a7b2d1c52 |
children | ab14dffd0e91 |
files | src/lib-index/mail-index-sync-private.h src/lib-index/mail-index-sync-update.c src/lib-index/mail-index-transaction-private.h src/lib-index/mail-index-transaction.c src/lib-index/mail-index-view-sync.c src/lib-index/mail-transaction-log.c src/lib-index/mail-transaction-log.h src/lib-index/mail-transaction-util.c src/lib-index/mail-transaction-util.h |
diffstat | 9 files changed, 282 insertions(+), 430 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-index-sync-private.h Sun Oct 17 19:42:20 2004 +0300 +++ b/src/lib-index/mail-index-sync-private.h Sun Oct 17 21:24:21 2004 +0300 @@ -27,6 +27,7 @@ struct mail_index_sync_map_ctx { struct mail_index_view *view; + uint32_t last_ext_id; unsigned int update_cache:1; unsigned int cache_locked:1; @@ -36,6 +37,10 @@ int mail_index_sync_update_index(struct mail_index_sync_ctx *sync_ctx); +int mail_index_sync_record(struct mail_index_sync_map_ctx *ctx, + const struct mail_transaction_header *hdr, + const void *data); + void mail_index_sync_get_expunge(struct mail_index_sync_rec *rec, const struct mail_transaction_expunge *exp);
--- a/src/lib-index/mail-index-sync-update.c Sun Oct 17 19:42:20 2004 +0300 +++ b/src/lib-index/mail-index-sync-update.c Sun Oct 17 21:24:21 2004 +0300 @@ -423,7 +423,7 @@ return new_map; } -static int +static void sync_ext_resize(const struct mail_transaction_ext_intro *u, uint32_t ext_id, struct mail_index_sync_map_ctx *ctx) { @@ -434,13 +434,6 @@ uint32_t offset, old_size, new_size, old_record_size; int modified = FALSE; - if (ext_id != u->ext_id) { - mail_transaction_log_view_set_corrupted(ctx->view->log_view, - "Introduced existing extension with wrong id: %u != %u", - u->ext_id, ext_id); - return -1; - } - ext = buffer_get_modifyable_data(map->extensions, NULL); ext += ext_id; @@ -492,8 +485,6 @@ mail_index_sync_replace_map(ctx->view, map); modified = TRUE; } - - return 1; } static int sync_ext_intro(const struct mail_transaction_ext_intro *u, @@ -507,17 +498,37 @@ const char *name; buffer_t *hdr_buf; uint32_t ext_id, hdr_offset; - int ret; + + if (u->ext_id != (uint32_t)-1 && + (map->extensions == NULL || + u->ext_id >= map->extensions->used / sizeof(*ext))) { + mail_transaction_log_view_set_corrupted(ctx->view->log_view, + "Extension introduction for unknown id %u", u->ext_id); + return -1; + } + + if (u->ext_id == (uint32_t)-1 && u->name_size == 0) { + mail_transaction_log_view_set_corrupted(ctx->view->log_view, + "Extension introduction without id or name"); + return -1; + } t_push(); - name = t_strndup(u + 1, u->name_size); + if (u->ext_id != (uint32_t)-1) { + name = NULL; + ext_id = u->ext_id; + } else { + name = t_strndup(u + 1, u->name_size); + ext_id = mail_index_map_lookup_ext(map, name); + } - ext_id = mail_index_map_lookup_ext(map, name); if (ext_id != (uint32_t)-1) { /* exists already - are we resizing? */ - ret = sync_ext_resize(u, ext_id, ctx); + sync_ext_resize(u, ext_id, ctx); t_pop(); - return ret; + + ctx->last_ext_id = ext_id; + return 1; } hdr_buf = map->hdr_copy_buf; @@ -562,20 +573,14 @@ t_pop(); - if (ext_id != u->ext_id) { - mail_transaction_log_view_set_corrupted(ctx->view->log_view, - "Introduced extension with invalid id: %u != %u", - u->ext_id, ext_id); - return -1; - } - map = sync_ext_reorder(map, ext_id, 0); mail_index_sync_replace_map(ctx->view, map); + + ctx->last_ext_id = ext_id; return 1; } -static int sync_ext_reset(const struct mail_transaction_ext_rec_header *u, - void *context) +static int sync_ext_reset(void *context) { struct mail_index_sync_map_ctx *ctx = context; struct mail_index_view *view = ctx->view; @@ -584,15 +589,14 @@ struct mail_index_record *rec; uint32_t i; - if (map->extensions == NULL || - u->ext_id >= map->extensions->used / sizeof(*ext)) { + if (ctx->last_ext_id == (uint32_t)-1) { mail_transaction_log_view_set_corrupted(view->log_view, - "Extension reset for unknown id %u", u->ext_id); + "Extension reset without intro prefix"); return -1; } ext = map->extensions->data; - ext += u->ext_id; + ext += ctx->last_ext_id; memset(buffer_get_space_unsafe(map->hdr_copy_buf, ext->hdr_offset, ext->hdr_size), 0, ext->hdr_size); @@ -613,15 +617,14 @@ struct mail_index_map *map = ctx->view->map; const struct mail_index_ext *ext; - if (map->extensions == NULL || - u->ext_id >= map->extensions->used / sizeof(*ext)) { + if (ctx->last_ext_id == (uint32_t)-1) { mail_transaction_log_view_set_corrupted(ctx->view->log_view, - "Extension header update for unknown id %u", u->ext_id); + "Extension header update without intro prefix"); return -1; } ext = map->extensions->data; - ext += u->ext_id; + ext += ctx->last_ext_id; buffer_write(map->hdr_copy_buf, ext->hdr_offset + u->offset, u + 1, u->size); @@ -630,8 +633,7 @@ } static int -sync_ext_rec_update(const struct mail_transaction_ext_rec_header *hdr, - const struct mail_transaction_ext_rec_update *u, +sync_ext_rec_update(const struct mail_transaction_ext_rec_update *u, void *context) { struct mail_index_sync_map_ctx *ctx = context; @@ -640,10 +642,9 @@ const struct mail_index_ext *ext; uint32_t seq; - if (view->map->extensions == NULL || - hdr->ext_id >= view->map->extensions->used / sizeof(*ext)) { - mail_transaction_log_view_set_corrupted(view->log_view, - "Extension update for unknown id %u", hdr->ext_id); + if (ctx->last_ext_id == (uint32_t)-1) { + mail_transaction_log_view_set_corrupted(ctx->view->log_view, + "Extension record update update without intro prefix"); return -1; } @@ -652,7 +653,7 @@ if (seq != 0) { ext = view->map->extensions->data; - ext += hdr->ext_id; + ext += ctx->last_ext_id; rec = MAIL_INDEX_MAP_IDX(view->map, seq-1); memcpy(PTR_OFFSET(rec, ext->record_offset), @@ -750,6 +751,152 @@ hdr->day_first_uid[0] = uid; } +int mail_index_sync_record(struct mail_index_sync_map_ctx *ctx, + const struct mail_transaction_header *hdr, + const void *data) +{ + int ret = 0; + + switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) { + case MAIL_TRANSACTION_APPEND: { + const struct mail_index_record *rec, *end; + + end = CONST_PTR_OFFSET(data, hdr->size); + for (rec = data; rec < end; rec++) { + ret = sync_append(rec, ctx); + if (ret <= 0) + break; + } + break; + } + case MAIL_TRANSACTION_EXPUNGE: + case MAIL_TRANSACTION_EXPUNGE|MAIL_TRANSACTION_EXPUNGE_PROT: { + const struct mail_transaction_expunge *rec, *end; + + end = CONST_PTR_OFFSET(data, hdr->size); + for (rec = data; rec < end; rec++) { + ret = sync_expunge(rec, ctx); + if (ret <= 0) + break; + } + break; + } + case MAIL_TRANSACTION_FLAG_UPDATE: { + const struct mail_transaction_flag_update *rec, *end; + + end = CONST_PTR_OFFSET(data, hdr->size); + for (rec = data; rec < end; rec++) { + ret = sync_flag_update(rec, ctx); + if (ret <= 0) + break; + } + break; + } + case MAIL_TRANSACTION_CACHE_RESET: { + const struct mail_transaction_cache_reset *rec = data; + + ret = sync_cache_reset(rec, ctx); + break; + } + case MAIL_TRANSACTION_CACHE_UPDATE: { + const struct mail_transaction_cache_update *rec, *end; + + end = CONST_PTR_OFFSET(data, hdr->size); + for (rec = data; rec != end; rec++) { + ret = sync_cache_update(rec, ctx); + if (ret <= 0) + break; + } + break; + } + case MAIL_TRANSACTION_HEADER_UPDATE: { + const struct mail_transaction_header_update *rec; + unsigned int i; + + for (i = 0; i < hdr->size; ) { + rec = CONST_PTR_OFFSET(data, i); + ret = sync_header_update(rec, ctx); + if (ret <= 0) + break; + + i += sizeof(*rec) + rec->size; + if ((i % 4) != 0) + i += 4 - (i % 4); + } + break; + } + case MAIL_TRANSACTION_EXT_INTRO: { + const struct mail_transaction_ext_intro *rec = data; + unsigned int i; + + for (i = 0; i < hdr->size; ) { + if (i + sizeof(*rec) > hdr->size) { + /* should be just extra padding */ + break; + } + + rec = CONST_PTR_OFFSET(data, i); + ret = sync_ext_intro(rec, ctx); + if (ret <= 0) + break; + + i += sizeof(*rec) + rec->name_size; + if ((i % 4) != 0) + i += 4 - (i % 4); + } + break; + } + case MAIL_TRANSACTION_EXT_RESET: + ret = sync_ext_reset(ctx); + break; + case MAIL_TRANSACTION_EXT_HDR_UPDATE: { + const struct mail_transaction_ext_hdr_update *rec = data; + unsigned int i; + + for (i = 0; i < hdr->size; ) { + rec = CONST_PTR_OFFSET(data, i); + ret = sync_ext_hdr_update(rec, ctx); + if (ret <= 0) + break; + + i += sizeof(*rec) + rec->size; + if ((i % 4) != 0) + i += 4 - (i % 4); + } + break; + } + case MAIL_TRANSACTION_EXT_REC_UPDATE: { + const struct mail_transaction_ext_rec_update *rec, *end; + const struct mail_index_ext *ext; + unsigned int record_size; + + /* call the first one, it checks if last_ext_id isn't set */ + rec = data; + ret = sync_ext_rec_update(rec, ctx); + if (ret <= 0) + break; + + ext = ctx->view->map->extensions->data; + record_size = sizeof(*rec) + ext[ctx->last_ext_id].record_size; + + rec = CONST_PTR_OFFSET(rec, record_size); + end = CONST_PTR_OFFSET(data, hdr->size); + while (rec < end) { + ret = sync_ext_rec_update(rec, ctx); + if (ret <= 0) + break; + + rec = CONST_PTR_OFFSET(rec, record_size); + } + break; + } + default: + i_unreached(); + } + + return ret; +} + int mail_index_sync_update_index(struct mail_index_sync_ctx *sync_ctx) { struct mail_index *index = sync_ctx->index; @@ -767,6 +914,7 @@ memset(&sync_map_ctx, 0, sizeof(sync_map_ctx)); sync_map_ctx.view = view; sync_map_ctx.update_cache = TRUE; + sync_map_ctx.last_ext_id = (uint32_t)-1; /* we'll have to update view->lock_id to avoid mail_index_view_lock() trying to update the file later. */ @@ -821,9 +969,7 @@ } } - if (mail_transaction_map(view->map, thdr, data, - &mail_index_map_sync_funcs, - &sync_map_ctx) < 0) { + if (mail_index_sync_record(&sync_map_ctx, thdr, data) < 0) { ret = -1; break; } @@ -884,10 +1030,3 @@ mail_index_view_unlock(view); return ret; } - -struct mail_transaction_map_functions mail_index_map_sync_funcs = { - sync_expunge, sync_append, sync_flag_update, - sync_cache_reset, sync_cache_update, sync_header_update, - sync_ext_intro, sync_ext_reset, - sync_ext_hdr_update, sync_ext_rec_update -};
--- a/src/lib-index/mail-index-transaction-private.h Sun Oct 17 19:42:20 2004 +0300 +++ b/src/lib-index/mail-index-transaction-private.h Sun Oct 17 21:24:21 2004 +0300 @@ -21,8 +21,6 @@ buffer_t *ext_rec_updates; /* buffer[] */ buffer_t *ext_resizes; /* struct mail_transaction_ext_intro[] */ - buffer_t *ext_intros; - uint32_t ext_intros_max_id; uint32_t new_cache_file_seq, last_cache_file_seq; buffer_t *cache_updates;
--- a/src/lib-index/mail-index-transaction.c Sun Oct 17 19:42:20 2004 +0300 +++ b/src/lib-index/mail-index-transaction.c Sun Oct 17 21:24:21 2004 +0300 @@ -57,8 +57,6 @@ buffer_free(t->updates); if (t->cache_updates != NULL) buffer_free(t->cache_updates); - if (t->ext_intros != NULL) - buffer_free(t->ext_intros); i_free(t); }
--- a/src/lib-index/mail-index-view-sync.c Sun Oct 17 19:42:20 2004 +0300 +++ b/src/lib-index/mail-index-view-sync.c Sun Oct 17 21:24:21 2004 +0300 @@ -206,10 +206,10 @@ memset(&sync_map_ctx, 0, sizeof(sync_map_ctx)); sync_map_ctx.view = view; + sync_map_ctx.last_ext_id = (uint32_t)-1; - if (mail_transaction_map(view->map, ctx->hdr, ctx->data, - &mail_index_map_sync_funcs, - &sync_map_ctx) < 0) + if (mail_index_sync_record(&sync_map_ctx, ctx->hdr, + ctx->data) < 0) return -1; }
--- a/src/lib-index/mail-transaction-log.c Sun Oct 17 19:42:20 2004 +0300 +++ b/src/lib-index/mail-transaction-log.c Sun Oct 17 21:24:21 2004 +0300 @@ -921,38 +921,6 @@ return ret; } -static void -transaction_save_ext_intro(struct mail_index_transaction *t, - const struct mail_transaction_ext_intro *intro) -{ - const char *name; - void *p; - uint32_t ext_id; - size_t pos; - - if (t->ext_intros == NULL) - t->ext_intros = buffer_create_dynamic(default_pool, 128); - - t_push(); - name = t_strndup((const char *)(intro+1), intro->name_size); - ext_id = mail_index_ext_register(t->view->index, name, - intro->hdr_size, intro->record_size, - intro->record_align); - pos = ext_id * sizeof(intro->ext_id); - if (pos > t->ext_intros->used) { - /* unused records are -1 */ - p = buffer_append_space_unsafe(t->ext_intros, - pos - t->ext_intros->used); - memset(p, 0xff, pos - t->ext_intros->used); - } - - buffer_write(t->ext_intros, pos, - &intro->ext_id, sizeof(intro->ext_id)); - if (intro->ext_id > t->ext_intros_max_id) - t->ext_intros_max_id = intro->ext_id; - t_pop(); -} - static int mail_transaction_log_scan_pending(struct mail_transaction_log *log, struct mail_index_transaction *t) { @@ -976,23 +944,6 @@ max_cache_file_seq = reset->new_file_seq; break; } - case MAIL_TRANSACTION_EXT_INTRO: { - const struct mail_transaction_ext_intro *intro; - uint32_t i; - - for (i = 0; i < hdr->size; ) { - if (i + sizeof(*intro) > hdr->size) { - /* should be just extra padding */ - break; - } - - intro = CONST_PTR_OFFSET(data, i); - transaction_save_ext_intro(t, intro); - - i += sizeof(*intro) + intro->name_size; - } - break; - } } } @@ -1120,121 +1071,111 @@ return buf; } -static uint32_t -mail_transaction_log_lookup_ext(struct mail_index_transaction *t, - uint32_t ext_id) +static int +mail_transaction_log_append_ext_intro(struct mail_transaction_log_file *file, + struct mail_index_transaction *t, + uint32_t ext_id) { - const uint32_t *id_map; + const struct mail_index_ext *ext; + struct mail_transaction_ext_intro *intro; + buffer_t *buf; uint32_t idx; size_t size; - /* already in nonsynced part of transaction log? */ - if (t->ext_intros != NULL) { - id_map = buffer_get_data(t->ext_intros, &size); - size /= sizeof(*id_map); + if (!mail_index_map_get_ext_idx(t->view->map, ext_id, &idx)) { + /* new extension */ + idx = (uint32_t)-1; + } - if (ext_id < size && id_map[ext_id] != (uint32_t)-1) - return id_map[ext_id]; + ext = t->view->index->extensions->data; + ext += ext_id; + + if (t->ext_resizes == NULL) { + intro = NULL; + size = 0; + } else { + intro = buffer_get_modifyable_data(t->ext_resizes, &size); + size /= sizeof(*intro); } - if (mail_index_map_get_ext_idx(t->view->map, ext_id, &idx)) - return idx; + buf = buffer_create_dynamic(pool_datastack_create(), 128); + if (ext_id < size && intro[ext_id].name_size != 0) { + /* we're resizing it */ + intro += ext_id; - return (uint32_t)-1; + i_assert(intro->ext_id == idx); + intro->name_size = idx != (uint32_t)-1 ? 0 : + strlen(ext->name); + buffer_append(buf, intro, sizeof(*intro)); + } else { + /* generate a new intro structure */ + intro = buffer_append_space_unsafe(buf, sizeof(*intro)); + intro->ext_id = idx; + intro->hdr_size = ext->hdr_size; + intro->record_size = ext->record_size; + intro->record_align = ext->record_align; + intro->name_size = idx != (uint32_t)-1 ? 0 : + strlen(ext->name); + } + buffer_append(buf, ext->name, intro->name_size); + + if ((buf->used % 4) != 0) + buffer_append_zero(buf, 4 - (buf->used % 4)); + + return log_append_buffer(file, buf, NULL, MAIL_TRANSACTION_EXT_INTRO, + t->view->external); } static int mail_transaction_log_append_ext_intros(struct mail_transaction_log_file *file, struct mail_index_transaction *t) { - const struct mail_index_ext *ext; - struct mail_transaction_ext_intro *intro; - buffer_t **updates, *buf; - uint32_t idx; - size_t i, size; + const struct mail_transaction_ext_intro *resize; + uint32_t ext_id, ext_count, update_count, resize_count; + buffer_t **update; + size_t size; - ext = t->view->index->extensions->data; - - if (t->ext_rec_updates != NULL) { - updates = buffer_get_modifyable_data(t->ext_rec_updates, &size); - size /= sizeof(*updates); + if (t->ext_rec_updates == NULL) { + update = NULL; + update_count = 0; + } else { + update = buffer_get_modifyable_data(t->ext_rec_updates, &size); + update_count = size / sizeof(*update); + } - /* add new extension introductions into resize buffer */ - for (i = 0; i < size; i++) { - if (updates[i] == NULL) - continue; + if (t->ext_resizes == NULL) { + resize = NULL; + resize_count = 0; + } else { + resize = buffer_get_modifyable_data(t->ext_resizes, &size); + resize_count = size / sizeof(*resize); + } - idx = mail_transaction_log_lookup_ext(t, i); - if (idx == (uint32_t)-1) { - mail_index_ext_resize(t, i, ext[i].hdr_size, - ext[i].record_size, - ext[i].record_align); - } + ext_count = I_MAX(update_count, resize_count); + + for (ext_id = 0; ext_id < ext_count; ext_id++) { + if ((ext_id < resize_count && resize[ext_id].name_size) || + (ext_id < update_count && update[ext_id] != NULL)) { + if (mail_transaction_log_append_ext_intro(file, t, + ext_id) < 0) + return -1; } } - if (t->ext_resizes == NULL) - return 0; - - /* give IDs to new extensions */ - intro = buffer_get_modifyable_data(t->ext_resizes, &size); - size /= sizeof(*intro); - for (i = 0; i < size; i++) { - if (intro[i].name_size != 0 && intro[i].ext_id == (uint32_t)-1) - intro[i].ext_id = t->ext_intros_max_id++; - } - - /* and register them */ - buf = buffer_create_dynamic(pool_datastack_create(), 128); - for (i = 0; i < size; i++) { - if (intro[i].name_size != 0) { - intro[i].name_size = strlen(ext[i].name); - buffer_append(buf, &intro[i], sizeof(*intro)); - buffer_append(buf, ext[i].name, intro[i].name_size); - } - } - - if ((buf->used % 4) != 0) - buffer_append_zero(buf, 4 - (buf->used % 4)); - - if (buf->used == 0) - return 0; - - return log_append_buffer(file, buf, NULL, MAIL_TRANSACTION_EXT_INTRO, - t->view->external); -} - -static uint32_t -mail_transaction_log_get_ext_idx(struct mail_index_transaction *t, - uint32_t ext_id) -{ - const struct mail_transaction_ext_intro *intro; - uint32_t idx; - - idx = mail_transaction_log_lookup_ext(t, ext_id); - if (idx != (uint32_t)-1) - return idx; - - i_assert(ext_id < t->ext_resizes->used / sizeof(*intro)); - intro = t->ext_resizes->data; - intro += ext_id; - - i_assert(intro->name_size > 0 && intro->ext_id != (uint32_t)-1); - return intro->ext_id; + return 0; } int mail_transaction_log_append(struct mail_index_transaction *t, uint32_t *log_file_seq_r, uoff_t *log_file_offset_r) { - struct mail_transaction_ext_rec_header ext_rec_hdr; struct mail_index_view *view = t->view; struct mail_index *index; struct mail_transaction_log *log; struct mail_transaction_log_file *file; struct mail_index_header idx_hdr; uoff_t append_offset; - buffer_t *hdr_buf, **updates; + buffer_t **updates; unsigned int i, lock_id; size_t size; int ret; @@ -1297,10 +1238,6 @@ t->cache_updates = NULL; } - t->ext_intros_max_id = t->view->index->map->extensions == NULL ? 0 : - (t->view->index->map->extensions->used / - sizeof(struct mail_index_ext)); - if (t->appends != NULL || (t->cache_updates != NULL && t->new_cache_file_seq == 0) || (t->ext_rec_updates != NULL && t->ext_rec_updates->used > 0)) { @@ -1313,10 +1250,9 @@ ret = 0; - /* introduce extensions before appends to avoid having to resize - records unneededly */ - if (mail_transaction_log_append_ext_intros(file, t) < 0) - ret = -1; + /* send all extension introductions and resizes before appends + to avoid resize overhead as much as possible */ + ret = mail_transaction_log_append_ext_intros(file, t); if (t->appends != NULL && ret == 0) { ret = log_append_buffer(file, t->appends, NULL, @@ -1347,15 +1283,15 @@ size /= sizeof(*updates); } - hdr_buf = buffer_create_data(pool_datastack_create(), - &ext_rec_hdr, sizeof(ext_rec_hdr)); - buffer_set_used_size(hdr_buf, sizeof(ext_rec_hdr)); for (i = 0; i < size && ret == 0; i++) { if (updates[i] == NULL) continue; - ext_rec_hdr.ext_id = mail_transaction_log_get_ext_idx(t, i); - ret = log_append_buffer(file, updates[i], hdr_buf, + ret = mail_transaction_log_append_ext_intro(file, t, i); + if (ret < 0) + break; + + ret = log_append_buffer(file, updates[i], NULL, MAIL_TRANSACTION_EXT_REC_UPDATE, view->external); }
--- a/src/lib-index/mail-transaction-log.h Sun Oct 17 19:42:20 2004 +0300 +++ b/src/lib-index/mail-transaction-log.h Sun Oct 17 21:24:21 2004 +0300 @@ -69,7 +69,9 @@ }; struct mail_transaction_ext_intro { - uint32_t ext_id; /* must be first */ + /* old extension: set ext_id. don't set name. + new extension: ext_id = (uint32_t)-1. give name. */ + uint32_t ext_id; uint32_t hdr_size; uint16_t record_size; uint16_t record_align; @@ -78,17 +80,13 @@ /* unsigned char name[]; */ }; +/* these are set for the last ext_intro */ struct mail_transaction_ext_hdr_update { - uint32_t ext_id; /* must be first */ uint16_t offset; uint16_t size; /* unsigned char data[]; */ }; -struct mail_transaction_ext_rec_header { - uint32_t ext_id; /* must be first */ -}; - struct mail_transaction_ext_rec_update { uint32_t uid; /* unsigned char data[]; */
--- a/src/lib-index/mail-transaction-util.c Sun Oct 17 19:42:20 2004 +0300 +++ b/src/lib-index/mail-transaction-util.c Sun Oct 17 21:24:21 2004 +0300 @@ -6,13 +6,6 @@ #include "mail-transaction-log.h" #include "mail-transaction-util.h" -struct mail_transaction_expunge_iter_ctx { - const struct mail_transaction_expunge *expunges; - size_t expunges_count; - uint32_t cur_seq, cur_idx, expunges_before; - uint32_t iter_seq, iter_count, iter_idx; -}; - const struct mail_transaction_type_map mail_transaction_type_map[] = { { MAIL_TRANSACTION_APPEND, MAIL_INDEX_SYNC_TYPE_APPEND, 1 }, /* index-specific size, use 1 */ @@ -26,8 +19,7 @@ sizeof(struct mail_transaction_cache_update) }, { MAIL_TRANSACTION_HEADER_UPDATE, 0, 1 }, /* variable size, use 1 */ { MAIL_TRANSACTION_EXT_INTRO, 0, 1 }, - { MAIL_TRANSACTION_EXT_RESET, 0, - sizeof(struct mail_transaction_ext_rec_header) }, + { MAIL_TRANSACTION_EXT_RESET, 0, 0 }, { MAIL_TRANSACTION_EXT_HDR_UPDATE, 0, 1 }, { MAIL_TRANSACTION_EXT_REC_UPDATE, 0, 1 }, { 0, 0, 0 } @@ -58,192 +50,6 @@ return type; } -int mail_transaction_map(struct mail_index_map *map, - const struct mail_transaction_header *hdr, - const void *data, - struct mail_transaction_map_functions *func_map, - void *context) -{ - int ret = 0; - - switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) { - case MAIL_TRANSACTION_APPEND: { - const struct mail_index_record *rec, *end; - - if (func_map->append == NULL) - break; - - end = CONST_PTR_OFFSET(data, hdr->size); - for (rec = data; rec != end; rec++) { - ret = func_map->append(rec, context); - if (ret <= 0) - break; - } - break; - } - case MAIL_TRANSACTION_EXPUNGE: - case MAIL_TRANSACTION_EXPUNGE|MAIL_TRANSACTION_EXPUNGE_PROT: { - const struct mail_transaction_expunge *rec, *end; - - if (func_map->expunge == NULL) - break; - - end = CONST_PTR_OFFSET(data, hdr->size); - for (rec = data; rec != end; rec++) { - ret = func_map->expunge(rec, context); - if (ret <= 0) - break; - } - break; - } - case MAIL_TRANSACTION_FLAG_UPDATE: { - const struct mail_transaction_flag_update *rec, *end; - - if (func_map->flag_update == NULL) - break; - - end = CONST_PTR_OFFSET(data, hdr->size); - for (rec = data; rec != end; rec++) { - ret = func_map->flag_update(rec, context); - if (ret <= 0) - break; - } - break; - } - case MAIL_TRANSACTION_CACHE_RESET: { - const struct mail_transaction_cache_reset *rec = data; - - if (func_map->cache_reset != NULL) - ret = func_map->cache_reset(rec, context); - break; - } - case MAIL_TRANSACTION_CACHE_UPDATE: { - const struct mail_transaction_cache_update *rec, *end; - - if (func_map->cache_update == NULL) - break; - - end = CONST_PTR_OFFSET(data, hdr->size); - for (rec = data; rec != end; rec++) { - ret = func_map->cache_update(rec, context); - if (ret <= 0) - break; - } - break; - } - case MAIL_TRANSACTION_HEADER_UPDATE: { - const struct mail_transaction_header_update *rec; - unsigned int i; - - if (func_map->header_update == NULL) - break; - - for (i = 0; i < hdr->size; ) { - rec = CONST_PTR_OFFSET(data, i); - ret = func_map->header_update(rec, context); - if (ret <= 0) - break; - - i += sizeof(*rec) + rec->size; - } - break; - } - case MAIL_TRANSACTION_EXT_INTRO: { - const struct mail_transaction_ext_intro *rec = data; - unsigned int i; - - if (func_map->ext_intro == NULL) - break; - - for (i = 0; i < hdr->size; ) { - if (i + sizeof(*rec) > hdr->size) { - /* should be just extra padding */ - break; - } - - rec = CONST_PTR_OFFSET(data, i); - ret = func_map->ext_intro(rec, context); - if (ret <= 0) - break; - - i += sizeof(*rec) + rec->name_size; - } - break; - } - case MAIL_TRANSACTION_EXT_RESET: { - const struct mail_transaction_ext_rec_header *rec = data; - unsigned int i, size; - - if (func_map->ext_reset == NULL) - break; - - size = hdr->size / sizeof(*rec); - for (i = 0; i < size; i++) { - ret = func_map->ext_reset(&rec[i], context); - if (ret <= 0) - break; - } - break; - } - case MAIL_TRANSACTION_EXT_HDR_UPDATE: { - const struct mail_transaction_ext_hdr_update *rec = data; - unsigned int i; - - if (func_map->ext_hdr_update == NULL) - break; - - for (i = 0; i < hdr->size; ) { - rec = CONST_PTR_OFFSET(data, i); - ret = func_map->ext_hdr_update(rec, context); - if (ret <= 0) - break; - - i += sizeof(*rec) + rec->size; - } - break; - } - case MAIL_TRANSACTION_EXT_REC_UPDATE: { - const struct mail_transaction_ext_rec_header *ehdr = data; - const struct mail_transaction_ext_rec_update *rec, *end; - const struct mail_index_ext *ext; - unsigned int record_size; - - if (func_map->ext_rec_update == NULL) - break; - - rec = CONST_PTR_OFFSET(data, sizeof(*ehdr)); - - if (map->extensions == NULL || - ehdr->ext_id >= map->extensions->used / sizeof(*ext)) { - /* broken. let the ext_rec_update handler do the - error handling. */ - ret = func_map->ext_rec_update(ehdr, rec, context); - if (ret >= 0) - i_unreached(); - break; - } - - ext = map->extensions->data; - ext += ehdr->ext_id; - record_size = sizeof(*ehdr) + ext->record_size; - - end = CONST_PTR_OFFSET(data, hdr->size); - while (rec != end) { - ret = func_map->ext_rec_update(ehdr, rec, context); - if (ret <= 0) - break; - - rec = CONST_PTR_OFFSET(rec, record_size); - } - break; - } - default: - i_unreached(); - } - - return ret; -} - void mail_transaction_log_sort_expunges(buffer_t *expunges_buf, const struct mail_transaction_expunge *src,
--- a/src/lib-index/mail-transaction-util.h Sun Oct 17 19:42:20 2004 +0300 +++ b/src/lib-index/mail-transaction-util.h Sun Oct 17 21:24:21 2004 +0300 @@ -8,39 +8,11 @@ }; extern const struct mail_transaction_type_map mail_transaction_type_map[]; -struct mail_transaction_map_functions { - int (*expunge)(const struct mail_transaction_expunge *e, void *context); - int (*append)(const struct mail_index_record *rec, void *context); - int (*flag_update)(const struct mail_transaction_flag_update *u, - void *context); - int (*cache_reset)(const struct mail_transaction_cache_reset *u, - void *context); - int (*cache_update)(const struct mail_transaction_cache_update *u, - void *context); - int (*header_update)(const struct mail_transaction_header_update *u, - void *context); - int (*ext_intro)(const struct mail_transaction_ext_intro *u, - void *context); - int (*ext_reset)(const struct mail_transaction_ext_rec_header *u, - void *context); - int (*ext_hdr_update)(const struct mail_transaction_ext_hdr_update *u, - void *context); - int (*ext_rec_update)(const struct mail_transaction_ext_rec_header *hdr, - const struct mail_transaction_ext_rec_update *u, - void *context); -}; - const struct mail_transaction_type_map * mail_transaction_type_lookup(enum mail_transaction_type type); enum mail_transaction_type mail_transaction_type_mask_get(enum mail_index_sync_type sync_type); -int mail_transaction_map(struct mail_index_map *map, - const struct mail_transaction_header *hdr, - const void *data, - struct mail_transaction_map_functions *func_map, - void *context); - void mail_transaction_log_sort_expunges(buffer_t *expunges_buf, const struct mail_transaction_expunge *src,