Mercurial > dovecot > core-2.2
changeset 3191:0df3f5d71958 HEAD
Changed many buffers to arrays. Cleans up the code a lot.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 12 Mar 2005 20:16:29 +0200 |
parents | ba17b6e45193 |
children | 2ff790d5d9e2 |
files | src/lib-index/mail-cache-lookup.c src/lib-index/mail-cache-private.h src/lib-index/mail-cache.c src/lib-index/mail-index-private.h src/lib-index/mail-index-sync-ext.c src/lib-index/mail-index-sync-keywords.c src/lib-index/mail-index-sync-private.h src/lib-index/mail-index-sync-update.c src/lib-index/mail-index-sync.c src/lib-index/mail-index-transaction-private.h src/lib-index/mail-index-transaction-view.c src/lib-index/mail-index-transaction.c src/lib-index/mail-index-view.c src/lib-index/mail-index.c src/lib-index/mail-transaction-log-append.c |
diffstat | 15 files changed, 497 insertions(+), 588 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-cache-lookup.c Sat Mar 12 20:15:48 2005 +0200 +++ b/src/lib-index/mail-cache-lookup.c Sat Mar 12 20:16:29 2005 +0200 @@ -69,8 +69,7 @@ return 0; } - ext = map->extensions->data; - ext += idx; + ext = array_idx(&map->extensions, idx); for (i = 0; i < 2; i++) { if (cache->hdr->file_seq == ext->reset_id) { @@ -163,15 +162,13 @@ return 1; } -static int buffer_find_offset(const buffer_t *buffer, uint32_t offset) +static int find_offset(struct mail_cache_view *view, uint32_t offset) { const uint32_t *offsets; - size_t i, size; + unsigned int i, count; - offsets = buffer_get_data(buffer, &size); - size /= sizeof(*offsets); - - for (i = 0; i < size; i++) { + offsets = array_get(&view->tmp_offsets, &count); + for (i = 0; i < count; i++) { if (offsets[i] == offset) return TRUE; } @@ -199,14 +196,14 @@ } ret = 1; - buffer_set_used_size(view->offsets_buf, 0); + array_clear(&view->tmp_offsets); while (offset != 0 && ret > 0) { - if (buffer_find_offset(view->offsets_buf, offset)) { + if (find_offset(view, offset)) { mail_cache_set_corrupted(view->cache, "record list is circular"); return -1; } - buffer_append(view->offsets_buf, &offset, sizeof(offset)); + array_append(&view->tmp_offsets, &offset, 1); ret = mail_cache_foreach_rec(view, &offset, callback, context); } @@ -214,15 +211,14 @@ if (ret > 0 && view->trans_seq1 <= seq && view->trans_seq2 >= seq && mail_cache_lookup_offset(view->cache, view->trans_view, seq, &offset)) { - buffer_set_used_size(view->offsets_buf, 0); + array_clear(&view->tmp_offsets); while (offset != 0 && ret > 0) { - if (buffer_find_offset(view->offsets_buf, offset)) { + if (find_offset(view, offset)) { mail_cache_set_corrupted(view->cache, "record list is circular"); return -1; } - buffer_append(view->offsets_buf, - &offset, sizeof(offset)); + array_append(&view->tmp_offsets, &offset, 1); ret = mail_cache_foreach_rec(view, &offset, callback, context); }
--- a/src/lib-index/mail-cache-private.h Sat Mar 12 20:15:48 2005 +0200 +++ b/src/lib-index/mail-cache-private.h Sat Mar 12 20:16:29 2005 +0200 @@ -155,7 +155,8 @@ struct mail_cache_transaction_ctx *transaction; uint32_t trans_seq1, trans_seq2; - buffer_t *offsets_buf; /* temporary buffer, just to avoid mallocs */ + /* temporary array, just to avoid mallocs. */ + array_t ARRAY_DEFINE(tmp_offsets, uint32_t); /* if cached_exists_buf[field] == cached_exists_value, it's cached. this allows us to avoid constantly clearing the whole buffer.
--- a/src/lib-index/mail-cache.c Sat Mar 12 20:15:48 2005 +0200 +++ b/src/lib-index/mail-cache.c Sat Mar 12 20:16:29 2005 +0200 @@ -459,7 +459,7 @@ view = i_new(struct mail_cache_view, 1); view->cache = cache; view->view = iview; - view->offsets_buf = buffer_create_dynamic(default_pool, 128); + ARRAY_CREATE(&view->tmp_offsets, default_pool, uint32_t, 32); view->cached_exists_buf = buffer_create_dynamic(default_pool, cache->file_fields_count + 10); @@ -474,7 +474,7 @@ if (view->trans_view != NULL) mail_index_view_close(view->trans_view); - buffer_free(view->offsets_buf); + array_free(&view->tmp_offsets); buffer_free(view->cached_exists_buf); i_free(view); }
--- a/src/lib-index/mail-index-private.h Sat Mar 12 20:15:48 2005 +0200 +++ b/src/lib-index/mail-index-private.h Sat Mar 12 20:16:29 2005 +0200 @@ -87,8 +87,8 @@ unsigned int records_count; pool_t extension_pool; - buffer_t *extensions; /* struct mail_index_ext[] */ - buffer_t *ext_id_map; /* uint32_t[] (index -> file) */ + array_t ARRAY_DEFINE(extensions, struct mail_index_ext); + array_t ARRAY_DEFINE(ext_id_map, uint32_t); /* index -> file */ void *mmap_base; size_t mmap_size, mmap_used_size; @@ -113,11 +113,12 @@ gid_t gid; pool_t extension_pool; - buffer_t *extensions; /* struct mail_index_ext[] */ + array_t ARRAY_DEFINE(extensions, struct mail_index_ext); - buffer_t *expunge_handlers; /* mail_index_expunge_handler_t*[] */ - buffer_t *sync_handlers; /* mail_index_sync_handler_t*[] */ - buffer_t *sync_lost_handlers; /* mail_index_sync_lost_handler_t*[] */ + array_t ARRAY_DEFINE(expunge_handlers, mail_index_expunge_handler_t *); + array_t ARRAY_DEFINE(sync_handlers, struct mail_index_sync_handler); + array_t ARRAY_DEFINE(sync_lost_handlers, + mail_index_sync_lost_handler_t *); char *filepath; int fd;
--- a/src/lib-index/mail-index-sync-ext.c Sat Mar 12 20:15:48 2005 +0200 +++ b/src/lib-index/mail-index-sync-ext.c Sat Mar 12 20:16:29 2005 +0200 @@ -10,46 +10,48 @@ void mail_index_sync_init_expunge_handlers(struct mail_index_sync_map_ctx *ctx) { - const mail_index_expunge_handler_t *const *handlers; + mail_index_expunge_handler_t *const *handlers; const struct mail_index_ext *extensions; const uint32_t *id_map; + void **contexts; struct mail_index_expunge_handler eh; - size_t handlers_count, id_map_size, size; + unsigned int count, ext_count, id_map_count; + unsigned int handlers_count, context_count; uint32_t idx_ext_id, map_ext_id; - if (ctx->view->map->extensions == NULL) + if (!array_is_created(&ctx->view->map->extensions)) return; - handlers = buffer_get_data(ctx->view->index->expunge_handlers, - &handlers_count); - handlers_count /= sizeof(*handlers); + handlers = array_get(&ctx->view->index->expunge_handlers, + &handlers_count); if (handlers_count == 0) return; /* set expunge handlers */ memset(&eh, 0, sizeof(eh)); - if (ctx->expunge_handlers != NULL) - buffer_set_used_size(ctx->expunge_handlers, 0); + if (array_is_created(&ctx->expunge_handlers)) + array_clear(&ctx->expunge_handlers); else { - ctx->expunge_handlers = - buffer_create_dynamic(default_pool, 256); + ARRAY_CREATE(&ctx->expunge_handlers, default_pool, + struct mail_index_expunge_handler, 64); } - extensions = ctx->view->map->extensions->data; - id_map = buffer_get_data(ctx->view->map->ext_id_map, &id_map_size); - id_map_size /= sizeof(*id_map); + extensions = array_get(&ctx->view->map->extensions, &ext_count); + id_map = array_get(&ctx->view->map->ext_id_map, &id_map_count); + contexts = array_get_modifyable(&ctx->extra_contexts, &context_count); - size = I_MIN(handlers_count, id_map_size); - for (idx_ext_id = 0; idx_ext_id < size; idx_ext_id++) { + count = I_MIN(handlers_count, id_map_count); + for (idx_ext_id = 0; idx_ext_id < count; idx_ext_id++) { map_ext_id = id_map[idx_ext_id]; if (handlers[idx_ext_id] == NULL || map_ext_id == (uint32_t)-1) continue; + i_assert(map_ext_id < context_count); eh.handler = handlers[idx_ext_id]; - eh.context = &ctx->extra_context[map_ext_id]; + eh.context = &contexts[map_ext_id]; eh.record_offset = extensions[map_ext_id].record_offset; - buffer_append(ctx->expunge_handlers, &eh, sizeof(eh)); + array_append(&ctx->expunge_handlers, &eh, 1); } ctx->expunge_handlers_set = TRUE; ctx->expunge_handlers_used = TRUE; @@ -59,42 +61,40 @@ mail_index_sync_deinit_expunge_handlers(struct mail_index_sync_map_ctx *ctx) { const struct mail_index_expunge_handler *eh; - size_t i, size; + unsigned int i, count; - if (ctx->expunge_handlers == NULL) + if (!array_is_created(&ctx->expunge_handlers)) return; - eh = buffer_get_data(ctx->expunge_handlers, &size); - size /= sizeof(*eh); - - for (i = 0; i < size; i++) { + eh = array_get(&ctx->expunge_handlers, &count); + for (i = 0; i < count; i++) { if (eh->context != NULL) eh[i].handler(ctx, 0, NULL, eh->context); } - buffer_free(ctx->expunge_handlers); + array_free(&ctx->expunge_handlers); } void mail_index_sync_init_handlers(struct mail_index_sync_map_ctx *ctx) { - size_t size; + unsigned int count; - if (ctx->view->map->extensions == NULL) + if (!array_is_created(&ctx->view->map->extensions)) return; /* set space for extra contexts */ - size = sizeof(void *) * (ctx->view->index->extensions->used / - sizeof(struct mail_index_ext)); - if (ctx->extra_context_buf == NULL) { - ctx->extra_context_buf = - buffer_create_dynamic(default_pool, size); - } else { - buffer_set_used_size(ctx->extra_context_buf, 0); + count = array_count(&ctx->view->index->extensions); + i_assert(count > 0); + + if (array_is_created(&ctx->extra_contexts)) + array_clear(&ctx->extra_contexts); + else { + ARRAY_CREATE(&ctx->extra_contexts, default_pool, + void *, count); } - buffer_append_zero(ctx->extra_context_buf, size); - ctx->extra_context = - buffer_get_modifyable_data(ctx->extra_context_buf, NULL); + /* fill the context array with NULLs */ + (void)array_modifyable_idx(&ctx->extra_contexts, count - 1); ctx->expunge_handlers_set = FALSE; } @@ -102,32 +102,33 @@ { const struct mail_index_sync_handler *sync_handlers; const struct mail_index_ext *ext; - size_t i, synch_size, size; + void **extra_contexts; + unsigned int i, count, synch_count, context_count; - if (ctx->extra_context == NULL) + if (!array_is_created(&ctx->extra_contexts)) return; - sync_handlers = buffer_get_data(ctx->view->index->sync_handlers, - &synch_size); - synch_size /= sizeof(*sync_handlers); + sync_handlers = + array_get(&ctx->view->index->sync_handlers, &synch_count); - i_assert(synch_size <= ctx->extra_context_buf->used / sizeof(void *)); - - ext = buffer_get_data(ctx->view->map->extensions, &size); - size /= sizeof(*ext); - i_assert(size <= synch_size); + ext = array_get(&ctx->view->map->extensions, &count); + i_assert(count <= synch_count); /* sync_handlers[] is ordered by index->extensions while - extra_context is ordered by map->extensions. */ - for (i = 0; i < size; i++) { - if (ctx->extra_context[i] != NULL) { + extra_contexts[] is ordered by map->extensions. */ + extra_contexts = + array_get_modifyable(&ctx->extra_contexts, &context_count); + i_assert(count <= context_count); + + for (i = 0; i < count; i++) { + if (extra_contexts[i] != NULL) { sync_handlers[ext[i].index_idx]. callback(ctx, 0, NULL, NULL, - &ctx->extra_context[i]); + &extra_contexts[i]); } } - buffer_free(ctx->extra_context_buf); + array_free(&ctx->extra_contexts); } static struct mail_index_ext_header * @@ -164,22 +165,21 @@ struct mail_index_ext_header *ext_hdr; uint16_t *old_offsets, min_align; uint32_t offset, old_records_count, rec_idx; + unsigned int i, count; const void *src; - size_t i, size; t_push(); - ext = buffer_get_modifyable_data(map->extensions, &size); - size /= sizeof(*ext); + ext = array_get_modifyable(&map->extensions, &count); /* @UNSAFE */ - old_offsets = t_new(uint16_t, size); - sorted = t_new(struct mail_index_ext *, size); - for (i = 0; i < size; i++) { + old_offsets = t_new(uint16_t, count); + sorted = t_new(struct mail_index_ext *, count); + for (i = 0; i < count; i++) { old_offsets[i] = ext[i].record_offset; ext[i].record_offset = 0; sorted[i] = &ext[i]; } - qsort(sorted, size, sizeof(struct mail_index_ext *), + qsort(sorted, count, sizeof(struct mail_index_ext *), mail_index_ext_align_cmp); /* we simply try to use the extensions with largest alignment @@ -188,7 +188,7 @@ offset = sizeof(struct mail_index_record); for (;;) { min_align = (uint16_t)-1; - for (i = 0; i < size; i++) { + for (i = 0; i < count; i++) { if (sorted[i]->record_offset == 0) { if ((offset % sorted[i]->record_align) == 0) break; @@ -196,7 +196,7 @@ min_align = sorted[i]->record_align; } } - if (i == size) { + if (i == count) { if (min_align == (uint16_t)-1) { /* all done */ break; @@ -234,7 +234,7 @@ for (rec_idx = 0; rec_idx < old_records_count; rec_idx++) { buffer_write(new_map->buffer, offset, src, sizeof(struct mail_index_record)); - for (i = 0; i < size; i++) { + for (i = 0; i < count; i++) { buffer_write(new_map->buffer, offset + ext[i].record_offset, CONST_PTR_OFFSET(src, old_offsets[i]), @@ -259,7 +259,7 @@ i_assert(new_map->records_count == new_map->hdr.messages_count); /* update record offsets in headers */ - for (i = 0; i < size; i++) { + for (i = 0; i < count; i++) { ext_hdr = get_ext_header(new_map, &ext[i]); ext_hdr->record_offset = ext[i].record_offset; } @@ -278,8 +278,7 @@ uint32_t old_size, new_size, old_record_size; int modified = FALSE; - ext = buffer_get_modifyable_data(map->extensions, NULL); - ext += ext_id; + ext = array_modifyable_idx(&map->extensions, ext_id); old_size = MAIL_INDEX_HEADER_SIZE_ALIGN(ext->hdr_size); new_size = MAIL_INDEX_HEADER_SIZE_ALIGN(u->hdr_size); @@ -320,7 +319,7 @@ if (new_size != old_size) { /* move all hdr_offset of all extensions after this one */ - size_t i, count = map->extensions->used / sizeof(*ext); + unsigned i, count = array_count(&map->extensions); ext -= ext_id; for (i = ext_id + 1; i < count; i++) { @@ -347,8 +346,8 @@ uint32_t ext_id, hdr_offset; if (u->ext_id != (uint32_t)-1 && - (map->extensions == NULL || - u->ext_id >= map->extensions->used / sizeof(*ext))) { + (!array_is_created(&map->extensions) || + u->ext_id >= array_count(&map->extensions))) { mail_transaction_log_view_set_corrupted(ctx->view->log_view, "Extension introduction for unknown id %u", u->ext_id); return -1; @@ -371,8 +370,7 @@ if (ext_id != (uint32_t)-1) { /* exists already */ - ext = map->extensions->data; - ext += ext_id; + ext = array_idx(&map->extensions, ext_id); if (u->reset_id == ext->reset_id) { /* check if we need to resize anything */ @@ -406,8 +404,7 @@ u->record_size, u->record_align, u->reset_id); - ext = map->extensions->data; - ext += ext_id; + ext = array_idx(&map->extensions, ext_id); /* <ext_hdr> <name> [padding] [header data] */ memset(&ext_hdr, 0, sizeof(ext_hdr)); @@ -460,8 +457,7 @@ if (ctx->cur_ext_ignore) return 1; - ext = buffer_get_modifyable_data(map->extensions, NULL); - ext += ctx->cur_ext_id; + ext = array_modifyable_idx(&map->extensions, ctx->cur_ext_id); ext->reset_id = u->new_reset_id; memset(buffer_get_space_unsafe(map->hdr_copy_buf, ext->hdr_offset, @@ -495,9 +491,7 @@ if (ctx->cur_ext_ignore) return 1; - ext = map->extensions->data; - ext += ctx->cur_ext_id; - + ext = array_idx(&map->extensions, ctx->cur_ext_id); buffer_write(map->hdr_copy_buf, ext->hdr_offset + u->offset, u + 1, u->size); map->hdr_base = map->hdr_copy_buf->data; @@ -525,19 +519,20 @@ if (seq == 0) return 1; - ext = view->map->extensions->data; - ext += ctx->cur_ext_id; + ext = array_idx(&view->map->extensions, ctx->cur_ext_id); rec = MAIL_INDEX_MAP_IDX(view->map, seq-1); old_data = PTR_OFFSET(rec, ext->record_offset); - sync_handlers = view->index->sync_handlers->data; - sync_handlers += ext->index_idx; + sync_handlers = array_idx(&view->index->sync_handlers, ext->index_idx); /* call sync handlers only when we're syncing index (not view) */ if ((sync_handlers->type & ctx->type) != 0) { + void **extra_context = + array_modifyable_idx(&ctx->extra_contexts, + ctx->cur_ext_id); ret = sync_handlers->callback(ctx, seq, old_data, u + 1, - &ctx->extra_context[ctx->cur_ext_id]); + extra_context); if (ret <= 0) return ret; }
--- a/src/lib-index/mail-index-sync-keywords.c Sat Mar 12 20:15:48 2005 +0200 +++ b/src/lib-index/mail-index-sync-keywords.c Sat Mar 12 20:16:29 2005 +0200 @@ -117,9 +117,7 @@ ext_id = mail_index_map_lookup_ext(map, "keywords"); if (ext_id != (uint32_t)-1) { /* update existing header */ - ext = map->extensions->data; - ext += ext_id; - + ext = array_idx(&map->extensions, ext_id); buf = keywords_get_header_buf(map, ext, 1, &keywords_count, &rec_offset, &name_offset_root, &name_offset); @@ -171,8 +169,7 @@ ext_id = mail_index_map_lookup_ext(map, "keywords"); i_assert(ext_id != (uint32_t)-1); } - ext = map->extensions->data; - ext += ext_id; + ext = array_idx(&map->extensions, ext_id); i_assert(ext->hdr_size == buf->used); } @@ -280,9 +277,7 @@ return 1; } - ext = ctx->view->map->extensions->data; - ext += ext_id; - + ext = array_idx(&ctx->view->map->extensions, ext_id); if (ext->record_size == 0) { /* nothing to do */ i_assert(rec->modify_type == MODIFY_REMOVE); @@ -334,9 +329,7 @@ return 1; } - ext = map->extensions->data; - ext += ext_id; - + ext = array_idx(&map->extensions, ext_id); end = CONST_PTR_OFFSET(r, hdr->size); for (; r != end; r++) { if (mail_index_lookup_uid_range(ctx->view, r->uid1, r->uid2,
--- a/src/lib-index/mail-index-sync-private.h Sat Mar 12 20:15:48 2005 +0200 +++ b/src/lib-index/mail-index-sync-private.h Sat Mar 12 20:16:29 2005 +0200 @@ -10,7 +10,7 @@ const struct mail_transaction_expunge *expunges; const struct mail_transaction_flag_update *updates; - size_t expunges_count, updates_count; + unsigned int expunges_count, updates_count; uint32_t append_uid_first, append_uid_last; @@ -37,10 +37,10 @@ struct mail_index_view *view; uint32_t cur_ext_id; - buffer_t *expunge_handlers; /* struct mail_index_expunge_handler[] */ + array_t ARRAY_DEFINE(expunge_handlers, + struct mail_index_expunge_handler); - buffer_t *extra_context_buf; - void **extra_context; + array_t ARRAY_DEFINE(extra_contexts, void *); enum mail_index_sync_handler_type type;
--- a/src/lib-index/mail-index-sync-update.c Sat Mar 12 20:15:48 2005 +0200 +++ b/src/lib-index/mail-index-sync-update.c Sat Mar 12 20:16:29 2005 +0200 @@ -80,8 +80,8 @@ struct mail_index_map *map = view->map; struct mail_index_record *rec; uint32_t count, seq, seq1, seq2; - struct mail_index_expunge_handler *expunge_handlers, *eh; - size_t i, expunge_handlers_count; + const struct mail_index_expunge_handler *expunge_handlers, *eh; + unsigned int i, expunge_handlers_count; if (e->uid1 > e->uid2 || e->uid1 == 0) { mail_transaction_log_view_set_corrupted(ctx->view->log_view, @@ -114,11 +114,9 @@ mail_index_sync_init_expunge_handlers(ctx); if (ctx->type != MAIL_INDEX_SYNC_HANDLER_VIEW && - ctx->expunge_handlers != NULL) { - expunge_handlers = - buffer_get_modifyable_data(ctx->expunge_handlers, - &expunge_handlers_count); - expunge_handlers_count /= sizeof(*expunge_handlers); + array_is_created(&ctx->expunge_handlers)) { + expunge_handlers = array_get(&ctx->expunge_handlers, + &expunge_handlers_count); } else { expunge_handlers = NULL; expunge_handlers_count = 0; @@ -479,8 +477,8 @@ break; } - ext = ctx->view->map->extensions->data; - record_size = sizeof(*rec) + ext[ctx->cur_ext_id].record_size; + ext = array_idx(&ctx->view->map->extensions, ctx->cur_ext_id); + record_size = sizeof(*rec) + ext->record_size; rec = data; end = CONST_PTR_OFFSET(data, hdr->size);
--- a/src/lib-index/mail-index-sync.c Sat Mar 12 20:15:48 2005 +0200 +++ b/src/lib-index/mail-index-sync.c Sat Mar 12 20:16:29 2005 +0200 @@ -181,7 +181,6 @@ mail_index_sync_read_and_sort(struct mail_index_sync_ctx *ctx, int *seen_external_r) { - size_t size; int ret; *seen_external_r = FALSE; @@ -207,17 +206,17 @@ mail_index_sync_add_transaction(ctx); } - if (ctx->trans->expunges == NULL) + if (!array_is_created(&ctx->trans->expunges)) ctx->expunges_count = 0; else { - ctx->expunges = buffer_get_data(ctx->trans->expunges, &size); - ctx->expunges_count = size / sizeof(*ctx->expunges); + ctx->expunges = array_get(&ctx->trans->expunges, + &ctx->expunges_count); } - if (ctx->trans->updates == NULL) + if (!array_is_created(&ctx->trans->updates)) ctx->updates_count = 0; else { - ctx->updates = buffer_get_data(ctx->trans->updates, &size); - ctx->updates_count = size / sizeof(*ctx->updates); + ctx->updates = array_get(&ctx->trans->updates, + &ctx->updates_count); } return ret; }
--- a/src/lib-index/mail-index-transaction-private.h Sat Mar 12 20:15:48 2005 +0200 +++ b/src/lib-index/mail-index-transaction-private.h Sat Mar 12 20:16:29 2005 +0200 @@ -7,23 +7,22 @@ int refcount; struct mail_index_view *view; - buffer_t *appends; + array_t ARRAY_DEFINE(appends, struct mail_index_record); uint32_t first_new_seq, last_new_seq; - buffer_t *expunges; - - buffer_t *updates; + array_t ARRAY_DEFINE(expunges, struct mail_transaction_expunge); + array_t ARRAY_DEFINE(updates, struct mail_transaction_flag_update); size_t last_update_idx; unsigned char hdr_change[sizeof(struct mail_index_header)]; unsigned char hdr_mask[sizeof(struct mail_index_header)]; - buffer_t *ext_rec_updates; /* buffer_t*[] */ - buffer_t *ext_resizes; /* struct mail_transaction_ext_intro[] */ - buffer_t *ext_resets; /* uint32_t[] */ + array_t ARRAY_DEFINE(ext_rec_updates, array_t); + array_t ARRAY_DEFINE(ext_resizes, struct mail_transaction_ext_intro); + array_t ARRAY_DEFINE(ext_resets, uint32_t); - buffer_t *keyword_updates; /* buffer_t*[] */ - buffer_t *keyword_resets; /* buffer_t*[] */ + array_t ARRAY_DEFINE(keyword_updates, array_t); + array_t ARRAY_DEFINE(keyword_resets, struct seq_range); struct mail_cache_transaction_ctx *cache_trans_ctx; @@ -40,7 +39,7 @@ void mail_index_transaction_ref(struct mail_index_transaction *t); void mail_index_transaction_unref(struct mail_index_transaction *t); -int mail_index_seq_buffer_lookup(buffer_t *buffer, uint32_t seq, - size_t record_size, size_t *pos_r); +int mail_index_seq_array_lookup(const array_t *buffer, uint32_t seq, + unsigned int *idx_r); #endif
--- a/src/lib-index/mail-index-transaction-view.c Sat Mar 12 20:15:48 2005 +0200 +++ b/src/lib-index/mail-index-transaction-view.c Sat Mar 12 20:16:29 2005 +0200 @@ -104,6 +104,7 @@ struct mail_index_view_transaction *tview = (struct mail_index_view_transaction *)view; const struct mail_index_record *rec; + unsigned int append_count; uint32_t seq, message_count; if (tview->parent->lookup_first(view, flags, flags_mask, seq_r) < 0) @@ -112,9 +113,11 @@ if (*seq_r != 0) return 0; - rec = buffer_get_data(tview->t->appends, NULL); + rec = array_get(&tview->t->appends, &append_count); seq = tview->t->first_new_seq; message_count = tview->t->last_new_seq; + i_assert(append_count == message_count - seq + 1); + for (; seq <= message_count; seq++, rec++) { if ((rec->flags & flags_mask) == (uint8_t)flags) { *seq_r = seq; @@ -133,37 +136,36 @@ struct mail_index_view_transaction *tview = (struct mail_index_view_transaction *)view; const struct mail_index_ext *ext; - buffer_t *const *ext_bufs; - size_t size, pos; + const array_t *ext_buf; + ARRAY_ARG_SET_TYPE(ext_buf, void *); + const void *data; + unsigned int idx; - i_assert(ext_id < view->index->extensions->used / sizeof(*ext)); + i_assert(ext_id < array_count(&view->index->extensions)); + + *map_r = view->index->map; - ext = view->index->extensions->data; - ext += ext_id; - - if (tview->t->ext_rec_updates == NULL) { - ext_bufs = NULL; - size = 0; - } else { - ext_bufs = buffer_get_data(tview->t->ext_rec_updates, &size); - size /= sizeof(*ext_bufs); + ext = array_idx(&view->index->extensions, ext_id); + if (array_is_created(&tview->t->ext_rec_updates) && + ext_id < array_count(&tview->t->ext_rec_updates)) { + /* there are some ext updates in transaction. + see if there's any for this sequence. */ + ext_buf = array_idx(&tview->t->ext_rec_updates, ext_id); + if (array_is_created(ext_buf) && + mail_index_seq_array_lookup(ext_buf, seq, &idx)) { + data = array_idx(ext_buf, idx); + *data_r = CONST_PTR_OFFSET(data, sizeof(uint32_t)); + return 1; + } } - *map_r = view->index->map; - if (size <= ext_id || ext_bufs[ext_id] == NULL || - !mail_index_seq_buffer_lookup(ext_bufs[ext_id], seq, - ext->record_size, &pos)) { - /* not updated, return the existing value */ - if (seq < tview->t->first_new_seq) { - return tview->parent->lookup_ext_full(view, seq, ext_id, - map_r, data_r); - } - - *data_r = NULL; - return 1; + /* not updated, return the existing value */ + if (seq < tview->t->first_new_seq) { + return tview->parent->lookup_ext_full(view, seq, ext_id, + map_r, data_r); } - *data_r = CONST_PTR_OFFSET(ext_bufs[ext_id]->data, pos + sizeof(seq)); + *data_r = NULL; return 1; }
--- a/src/lib-index/mail-index-transaction.c Sat Mar 12 20:15:48 2005 +0200 +++ b/src/lib-index/mail-index-transaction.c Sat Mar 12 20:16:29 2005 +0200 @@ -42,45 +42,41 @@ static void mail_index_transaction_free(struct mail_index_transaction *t) { - buffer_t **recs; - size_t i, size; + array_t *recs; + unsigned i, count; + + if (array_is_created(&t->ext_rec_updates)) { + recs = array_get_modifyable(&t->ext_rec_updates, &count); - if (t->ext_rec_updates != NULL) { - recs = buffer_get_modifyable_data(t->ext_rec_updates, &size); - size /= sizeof(*recs); - - for (i = 0; i < size; i++) { - if (recs[i] != NULL) - buffer_free(recs[i]); + for (i = 0; i < count; i++) { + if (array_is_created(&recs[i])) + array_free(&recs[i]); } - buffer_free(t->ext_rec_updates); + array_free(&t->ext_rec_updates); } - if (t->keyword_updates != NULL) { - buffer_t **buf; - - buf = buffer_get_modifyable_data(t->keyword_updates, &size); - size /= sizeof(*buf); + if (array_is_created(&t->keyword_updates)) { + recs = array_get_modifyable(&t->keyword_updates, &count); - for (i = 0; i < size; i++) { - if (buf[i] != NULL) - buffer_free(buf[i]); + for (i = 0; i < count; i++) { + if (array_is_created(&recs[i])) + array_free(&recs[i]); } - buffer_free(t->keyword_updates); + array_free(&t->keyword_updates); } - if (t->keyword_resets != NULL) - buffer_free(t->keyword_resets); + if (array_is_created(&t->keyword_resets)) + array_free(&t->keyword_resets); - if (t->appends != NULL) - buffer_free(t->appends); - if (t->expunges != NULL) - buffer_free(t->expunges); - if (t->updates != NULL) - buffer_free(t->updates); - if (t->ext_resizes != NULL) - buffer_free(t->ext_resizes); - if (t->ext_resets != NULL) - buffer_free(t->ext_resets); + if (array_is_created(&t->appends)) + array_free(&t->appends); + if (array_is_created(&t->expunges)) + array_free(&t->expunges); + if (array_is_created(&t->updates)) + array_free(&t->updates); + if (array_is_created(&t->ext_resizes)) + array_free(&t->ext_resizes); + if (array_is_created(&t->ext_resets)) + array_free(&t->ext_resets); mail_index_view_transaction_unref(t->view); mail_index_view_close(t->view); @@ -100,22 +96,21 @@ static void mail_index_buffer_convert_to_uids(struct mail_index_transaction *t, - buffer_t *buf, size_t record_size, int range) + array_t *array, int range) { + ARRAY_ARG_SET_TYPE(array, uint32_t); struct mail_index_view *view = t->view; const struct mail_index_record *rec; - unsigned char *data; - size_t size, i; uint32_t *seq; + unsigned int i, count; int j; - if (buf == NULL) + if (!array_is_created(array)) return; - /* @UNSAFE */ - data = buffer_get_modifyable_data(buf, &size); - for (i = 0; i < size; i += record_size) { - seq = (uint32_t *)&data[i]; + count = array_count(array); + for (i = 0; i < count; i++) { + seq = array_modifyable_idx(array, i); for (j = 0; j <= range; j++, seq++) { if (*seq >= t->first_new_seq) { @@ -131,51 +126,36 @@ } } +static void arrays_convert_to_uids(struct mail_index_transaction *t, + array_t *array) +{ + ARRAY_ARG_SET_TYPE(array, array_t); + array_t *updates; + unsigned int i, count; + + if (!array_is_created(array)) + return; + + updates = array_get_modifyable(array, &count); + for (i = 0; i < count; i++) { + if (array_is_created(&updates[i])) { + mail_index_buffer_convert_to_uids(t, &updates[i], + FALSE); + } + } +} + static int mail_index_transaction_convert_to_uids(struct mail_index_transaction *t) { - struct mail_index *index = t->view->index; - const struct mail_index_ext *extensions; - buffer_t **updates; - size_t i, size; - if (mail_index_view_lock(t->view) < 0) return -1; - if (t->ext_rec_updates != NULL) { - extensions = buffer_get_data(index->extensions, NULL); - updates = buffer_get_modifyable_data(t->ext_rec_updates, &size); - size /= sizeof(*updates); - - for (i = 0; i < size; i++) { - if (updates[i] == NULL) - continue; - - mail_index_buffer_convert_to_uids(t, updates[i], - sizeof(uint32_t) + extensions[i].record_size, - FALSE); - } - } + arrays_convert_to_uids(t, &t->ext_rec_updates); + arrays_convert_to_uids(t, &t->keyword_updates); - if (t->keyword_updates != NULL) { - buffer_t **buf; - - buf = buffer_get_modifyable_data(t->keyword_updates, &size); - size /= sizeof(*buf); - - for (i = 0; i < size; i++) { - if (buf[i] == NULL) - continue; - - mail_index_buffer_convert_to_uids(t, buf[i], - sizeof(uint32_t) * 2, TRUE); - } - } - - mail_index_buffer_convert_to_uids(t, t->expunges, - sizeof(struct mail_transaction_expunge), TRUE); - mail_index_buffer_convert_to_uids(t, t->updates, - sizeof(struct mail_transaction_flag_update), TRUE); + mail_index_buffer_convert_to_uids(t, &t->expunges, TRUE); + mail_index_buffer_convert_to_uids(t, &t->updates, TRUE); return 0; } @@ -218,13 +198,9 @@ struct mail_index_record * mail_index_transaction_lookup(struct mail_index_transaction *t, uint32_t seq) { - size_t pos; - i_assert(seq >= t->first_new_seq && seq <= t->last_new_seq); - pos = (seq - t->first_new_seq) * sizeof(struct mail_index_record); - return buffer_get_space_unsafe(t->appends, pos, - sizeof(struct mail_index_record)); + return array_modifyable_idx(&t->appends, seq - t->first_new_seq); } void mail_index_append(struct mail_index_transaction *t, uint32_t uid, @@ -236,8 +212,10 @@ t->log_updates = TRUE; - if (t->appends == NULL) - t->appends = buffer_create_dynamic(default_pool, 4096); + if (!array_is_created(&t->appends)) { + ARRAY_CREATE(&t->appends, default_pool, + struct mail_index_record, 32); + } /* sequence number is visible only inside given view, so let it generate it */ @@ -246,32 +224,30 @@ else *seq_r = t->last_new_seq = t->first_new_seq; - rec = buffer_append_space_unsafe(t->appends, sizeof(*rec)); - memset(rec, 0, sizeof(*rec)); + rec = array_modifyable_append(&t->appends); rec->uid = uid; } void mail_index_append_assign_uids(struct mail_index_transaction *t, uint32_t first_uid, uint32_t *next_uid_r) { - struct mail_index_record *rec, *end; - size_t size; + struct mail_index_record *recs; + unsigned int i, count; - if (t->appends == NULL) + if (!array_is_created(&t->appends)) return; - rec = buffer_get_modifyable_data(t->appends, &size); - end = PTR_OFFSET(rec, size); + recs = array_get_modifyable(&t->appends, &count); /* find the first mail with uid = 0 */ - for (; rec != end; rec++) { - if (rec->uid == 0) + for (i = 0; i < count; i++) { + if (recs[i].uid == 0) break; } - for (; rec != end; rec++) { - i_assert(rec->uid == 0); - rec->uid = first_uid++; + for (; i < count; i++) { + i_assert(recs[i].uid == 0); + recs[i].uid = first_uid++; } *next_uid_r = first_uid; @@ -282,36 +258,33 @@ }; static void -mail_index_seq_range_buffer_add(buffer_t **buffer_p, size_t initial_size, - uint32_t seq) +mail_index_seq_range_array_add(array_t *array, unsigned int init_count, + uint32_t seq) { - buffer_t *buffer; + ARRAY_ARG_SET_TYPE(array, struct seq_range); struct seq_range *data, value; - unsigned int idx, left_idx, right_idx; - size_t size; - - if (*buffer_p == NULL) { - *buffer_p = buffer_create_dynamic(default_pool, initial_size); - buffer_append(*buffer_p, &seq, sizeof(seq)); - buffer_append(*buffer_p, &seq, sizeof(seq)); - return; - } - buffer = *buffer_p; + unsigned int idx, left_idx, right_idx, count; value.seq1 = value.seq2 = seq; - data = buffer_get_modifyable_data(buffer, &size); - size /= sizeof(*data); - i_assert(size > 0); + if (!array_is_created(array)) { + array_create(array, default_pool, + sizeof(struct seq_range), init_count); + array_append(array, &value, 1); + return; + } + + data = array_get_modifyable(array, &count); + i_assert(count > 0); /* quick checks */ - if (data[size-1].seq2 == seq-1) { + if (data[count-1].seq2 == seq-1) { /* grow last range */ - data[size-1].seq2 = seq; + data[count-1].seq2 = seq; return; } - if (data[size-1].seq2 < seq) { - buffer_append(buffer, &value, sizeof(value)); + if (data[count-1].seq2 < seq) { + array_append(array, &value, 1); return; } if (data[0].seq1 == seq+1) { @@ -320,13 +293,13 @@ return; } if (data[0].seq1 > seq) { - buffer_insert(buffer, 0, &value, sizeof(value)); + array_insert(array, 0, &value, 1); return; } /* somewhere in the middle, array is sorted so find it with binary search */ - idx = 0; left_idx = 0; right_idx = size; + idx = 0; left_idx = 0; right_idx = count; while (left_idx < right_idx) { idx = (left_idx + right_idx) / 2; @@ -344,8 +317,8 @@ if (data[idx].seq2 < seq) idx++; - /* idx == size couldn't happen because we already handle it above */ - i_assert(idx < size && data[idx].seq1 >= seq); + /* idx == count couldn't happen because we already handle it above */ + i_assert(idx < count && data[idx].seq1 >= seq); i_assert(data[idx].seq1 > seq || data[idx].seq2 < seq); if (data[idx].seq1 == seq+1) { @@ -353,45 +326,41 @@ if (idx > 0 && data[idx-1].seq2 == seq-1) { /* merge */ data[idx-1].seq2 = data[idx].seq2; - buffer_delete(buffer, idx * sizeof(*data), - sizeof(*data)); + array_delete(array, idx, 1); } } else if (data[idx].seq2 == seq-1) { - i_assert(idx+1 < size); /* already handled above */ + i_assert(idx+1 < count); /* already handled above */ data[idx].seq2 = seq; if (data[idx+1].seq1 == seq+1) { /* merge */ data[idx+1].seq1 = data[idx].seq1; - buffer_delete(buffer, idx * sizeof(*data), - sizeof(*data)); + array_delete(array, idx, 1); } } else { - buffer_insert(buffer, idx * sizeof(*data), - &value, sizeof(value)); + array_insert(array, idx, &value, 1); } } -static void mail_index_seq_range_buffer_remove(buffer_t *buffer, uint32_t seq) +static void mail_index_seq_range_array_remove(array_t *array, uint32_t seq) { + ARRAY_ARG_SET_TYPE(array, struct seq_range); struct seq_range *data, value; - unsigned int idx, left_idx, right_idx; - size_t size; + unsigned int idx, left_idx, right_idx, count; - if (buffer == NULL) + if (!array_is_created(array)) return; - data = buffer_get_modifyable_data(buffer, &size); - size /= sizeof(*data); - i_assert(size > 0); + data = array_get_modifyable(array, &count); + i_assert(count > 0); /* quick checks */ - if (seq > data[size-1].seq2 || seq < data[0].seq1) { + if (seq > data[count-1].seq2 || seq < data[0].seq1) { /* outside the range */ return; } - if (data[size-1].seq2 == seq) { + if (data[count-1].seq2 == seq) { /* shrink last range */ - data[size-1].seq2--; + data[count-1].seq2--; return; } if (data[0].seq1 == seq) { @@ -402,7 +371,7 @@ /* somewhere in the middle, array is sorted so find it with binary search */ - idx = 0; left_idx = 0; right_idx = size; + idx = 0; left_idx = 0; right_idx = count; while (left_idx < right_idx) { idx = (left_idx + right_idx) / 2; @@ -416,9 +385,7 @@ if (data[idx].seq1 == data[idx].seq2) { /* a single sequence range. remove it entirely */ - buffer_delete(buffer, - idx * sizeof(*data), - sizeof(*data)); + array_delete(array, idx, 1); } else { /* shrink the range */ data[idx].seq1++; @@ -432,8 +399,7 @@ value.seq2 = data[idx].seq2; data[idx].seq2 = seq - 1; - buffer_insert(buffer, idx * sizeof(*data), - &value, sizeof(value)); + array_insert(array, idx, &value, 1); } break; } @@ -447,7 +413,7 @@ t->log_updates = TRUE; /* expunges is a sorted array of {seq1, seq2, ..}, .. */ - mail_index_seq_range_buffer_add(&t->expunges, 512, seq); + mail_index_seq_range_array_add(&t->expunges, 128, seq); } static void @@ -456,13 +422,12 @@ uint32_t left_idx, uint32_t right_idx) { struct mail_transaction_flag_update *updates, tmp_update; - size_t size; + unsigned int count; uint32_t idx, move; - updates = buffer_get_modifyable_data(t->updates, &size); - size /= sizeof(*updates); + updates = array_get_modifyable(&t->updates, &count); - i_assert(left_idx <= right_idx && right_idx <= size); + i_assert(left_idx <= right_idx && right_idx <= count); /* find the first update with either overlapping range, or the update which will come after our insert */ @@ -477,14 +442,14 @@ else break; } - if (idx < size && updates[idx].uid2 < u.uid1) + if (idx < count && updates[idx].uid2 < u.uid1) idx++; /* overlapping ranges, split/merge them */ i_assert(idx == 0 || updates[idx-1].uid2 < u.uid1); - i_assert(idx == size || updates[idx].uid2 >= u.uid1); + i_assert(idx == count || updates[idx].uid2 >= u.uid1); - for (; idx < size && u.uid2 >= updates[idx].uid1; idx++) { + for (; idx < count && u.uid2 >= updates[idx].uid1; idx++) { if (u.uid1 != updates[idx].uid1 && (updates[idx].add_flags != u.add_flags || updates[idx].remove_flags != u.remove_flags)) { @@ -504,10 +469,9 @@ i_assert(tmp_update.uid1 <= tmp_update.uid2); i_assert(updates[idx].uid1 <= updates[idx].uid2); - buffer_insert(t->updates, idx * sizeof(tmp_update), - &tmp_update, sizeof(tmp_update)); - updates = buffer_get_modifyable_data(t->updates, NULL); - size++; idx += move; + array_insert(&t->updates, idx, &tmp_update, 1); + updates = array_get_modifyable(&t->updates, &count); + idx += move; } else if (u.uid1 < updates[idx].uid1) { updates[idx].uid1 = u.uid1; } @@ -523,10 +487,8 @@ i_assert(tmp_update.uid1 <= tmp_update.uid2); i_assert(updates[idx].uid1 <= updates[idx].uid2); - buffer_insert(t->updates, idx * sizeof(tmp_update), - &tmp_update, sizeof(tmp_update)); - updates = buffer_get_modifyable_data(t->updates, NULL); - size++; + array_insert(&t->updates, idx, &tmp_update, 1); + updates = array_get_modifyable(&t->updates, &count); } updates[idx].add_flags = @@ -543,12 +505,12 @@ break; } } - i_assert(idx <= size); + i_assert(idx <= count); if (u.uid1 <= u.uid2) { i_assert(idx == 0 || updates[idx-1].uid2 < u.uid1); - i_assert(idx == size || updates[idx].uid1 > u.uid2); - buffer_insert(t->updates, idx * sizeof(u), &u, sizeof(u)); + i_assert(idx == count || updates[idx].uid1 > u.uid2); + array_insert(&t->updates, idx, &u, 1); } t->last_update_idx = idx; } @@ -577,7 +539,7 @@ { struct mail_index_record *rec; struct mail_transaction_flag_update u, *last_update; - size_t size; + unsigned int count; t->log_updates = TRUE; @@ -616,23 +578,22 @@ break; } - if (t->updates == NULL) { - t->updates = buffer_create_dynamic(default_pool, 4096); - buffer_append(t->updates, &u, sizeof(u)); + if (!array_is_created(&t->updates)) { + ARRAY_CREATE(&t->updates, default_pool, + struct mail_transaction_flag_update, 256); + array_append(&t->updates, &u, 1); return; } - last_update = buffer_get_modifyable_data(t->updates, &size); - size /= sizeof(*last_update); - - if (t->last_update_idx < size) { + last_update = array_get_modifyable(&t->updates, &count); + if (t->last_update_idx < count) { /* fast path - hopefully we're updating the next message, or a message that is to be appended as last update */ last_update += t->last_update_idx; if (seq1 - 1 == last_update->uid2) { if (u.add_flags == last_update->add_flags && u.remove_flags == last_update->remove_flags && - (t->last_update_idx + 1 == size || + (t->last_update_idx + 1 == count || last_update[1].uid1 > seq2)) { /* we can just update the UID range */ last_update->uid2 = seq2; @@ -645,8 +606,8 @@ } } - if (t->last_update_idx == size) { - buffer_append(t->updates, &u, sizeof(u)); + if (t->last_update_idx == count) { + array_append(&t->updates, &u, 1); return; } @@ -654,7 +615,7 @@ if (seq1 > last_update->uid2) { /* added after this */ mail_index_insert_flag_update(t, u, t->last_update_idx + 1, - size); + count); } else { /* added before this or on top of this */ mail_index_insert_flag_update(t, u, 0, t->last_update_idx + 1); @@ -668,72 +629,71 @@ mail_index_update_flags_range(t, seq, seq, modify_type, flags); } -int mail_index_seq_buffer_lookup(buffer_t *buffer, uint32_t seq, - size_t record_size, size_t *pos_r) +int mail_index_seq_array_lookup(const array_t *array, uint32_t seq, + unsigned int *idx_r) { - unsigned int idx, left_idx, right_idx; - void *data; - uint32_t full_record_size, *seq_p; - size_t size; + ARRAY_ARG_SET_TYPE(array, uint32_t); + unsigned int idx, left_idx, right_idx, count; + const uint32_t *seq_p; - full_record_size = record_size + sizeof(seq); - - data = buffer_get_modifyable_data(buffer, &size); + count = array_count(array); + if (count == 0) { + *idx_r = 0; + return FALSE; + } /* we're probably appending it, check */ - if (size == 0) - idx = 0; - else if (*((uint32_t *)PTR_OFFSET(data, size-full_record_size)) < seq) - idx = size / full_record_size; + seq_p = array_idx(array, count-1); + if (*seq_p < seq) + idx = count; else { - idx = 0; left_idx = 0; right_idx = size / full_record_size; + idx = 0; left_idx = 0; right_idx = count; while (left_idx < right_idx) { idx = (left_idx + right_idx) / 2; - seq_p = PTR_OFFSET(data, idx * full_record_size); + seq_p = array_idx(array, idx); if (*seq_p < seq) left_idx = idx+1; else if (*seq_p > seq) right_idx = idx; else { - *pos_r = idx * full_record_size; + *idx_r = idx; return TRUE; } } } - *pos_r = idx * full_record_size; + *idx_r = idx; return FALSE; } -static int mail_index_seq_buffer_add(buffer_t **buffer, uint32_t seq, - const void *record, size_t record_size, - void *old_record) +static int mail_index_seq_array_add(array_t *array, uint32_t seq, + const void *record, size_t record_size, + void *old_record) { + ARRAY_ARG_SET_TYPE(array, void *); void *p; - size_t pos; + unsigned int idx; - if (*buffer == NULL) { - *buffer = buffer_create_dynamic(default_pool, 1024); - buffer_append(*buffer, &seq, sizeof(seq)); - buffer_append(*buffer, record, record_size); - return FALSE; + if (!array_is_created(array)) { + array_create(array, default_pool, + sizeof(seq) + record_size, + 1024 / (sizeof(seq) + record_size)); } + i_assert(array->element_size == sizeof(seq) + record_size); - if (mail_index_seq_buffer_lookup(*buffer, seq, record_size, &pos)) { + if (mail_index_seq_array_lookup(array, seq, &idx)) { /* already there, update */ - p = buffer_get_space_unsafe(*buffer, pos + sizeof(seq), - record_size); + p = array_modifyable_idx(array, idx); if (old_record != NULL) memcpy(old_record, p, record_size); - memcpy(p, record, record_size); + memcpy(PTR_OFFSET(p, sizeof(seq)), record, record_size); return TRUE; } else { /* insert */ - buffer_copy(*buffer, pos + sizeof(seq) + record_size, - *buffer, pos, (size_t)-1); - buffer_write(*buffer, pos, &seq, sizeof(seq)); - buffer_write(*buffer, pos + sizeof(seq), record, record_size); + p = array_modifyable_insert(array, idx); + memcpy(p, &seq, sizeof(seq)); + memcpy(PTR_OFFSET(p, sizeof(seq)), record, record_size); return FALSE; } } @@ -763,55 +723,53 @@ if (!mail_index_map_get_ext_idx(t->view->map, ext_id, &intro.ext_id)) { intro.ext_id = (uint32_t)-1; - ext = t->view->index->extensions->data; - ext += ext_id; + ext = array_idx(&t->view->index->extensions, ext_id); } else { - ext = t->view->map->extensions->data; - ext += ext_id; + ext = array_idx(&t->view->map->extensions, ext_id); } - /* allow only header size changes if something was already written */ - i_assert(t->ext_rec_updates == NULL || + /* allow only header size changes if extension records have already + been changed in transaction */ + i_assert(!array_is_created(&t->ext_rec_updates) || (ext->record_size == record_size && ext->record_align == record_align)); t->log_updates = TRUE; - if (t->ext_resizes == NULL) - t->ext_resizes = buffer_create_dynamic(default_pool, 128); + if (!array_is_created(&t->ext_resizes)) { + ARRAY_CREATE(&t->ext_resizes, default_pool, + struct mail_transaction_ext_intro, ext_id + 2); + } intro.hdr_size = hdr_size; intro.record_size = record_size; intro.record_align = record_align; intro.name_size = 1; - buffer_write(t->ext_resizes, ext_id * sizeof(intro), - &intro, sizeof(intro)); + array_idx_set(&t->ext_resizes, ext_id, &intro); } void mail_index_ext_reset(struct mail_index_transaction *t, uint32_t ext_id, uint32_t reset_id) { - size_t pos; - i_assert(reset_id != 0); t->log_updates = TRUE; - if (t->ext_rec_updates != NULL && - ext_id < t->ext_rec_updates->used / sizeof(buffer_t *)) { - buffer_t *const *buf = t->ext_rec_updates->data; - buf += ext_id; + if (array_is_created(&t->ext_rec_updates) && + ext_id < array_count(&t->ext_rec_updates)) { + /* if extension records have been updated, clear them */ + array_t *array; - if (*buf != NULL) - buffer_set_used_size(*buf, 0); + array = array_modifyable_idx(&t->ext_rec_updates, ext_id); + if (array_is_created(array)) + array_clear(array); } - pos = ext_id * sizeof(uint32_t); - if (t->ext_resets == NULL) { - t->ext_resets = buffer_create_dynamic(default_pool, - pos + sizeof(uint32_t)); + if (!array_is_created(&t->ext_resets)) { + ARRAY_CREATE(&t->ext_resets, default_pool, + uint32_t, ext_id + 2); } - buffer_write(t->ext_resets, pos, &reset_id, sizeof(reset_id)); + array_idx_set(&t->ext_resets, ext_id, &reset_id); } void mail_index_update_header_ext(struct mail_index_transaction *t, @@ -827,40 +785,40 @@ struct mail_index *index = t->view->index; const struct mail_index_ext *ext; const struct mail_transaction_ext_intro *intro; - buffer_t **buf; uint16_t record_size; - size_t size; + array_t *array; + unsigned int count; i_assert(seq > 0 && (seq <= mail_index_view_get_messages_count(t->view) || seq <= t->last_new_seq)); - i_assert(ext_id < index->extensions->used / sizeof(*ext)); + i_assert(ext_id < array_count(&index->extensions)); t->log_updates = TRUE; - if (t->ext_resizes == NULL) { + if (!array_is_created(&t->ext_resizes)) { intro = NULL; - size = 0; + count = 0; } else { - intro = buffer_get_data(t->ext_resizes, &size); + intro = array_get(&t->ext_resizes, &count); } - if (ext_id < size / sizeof(*intro) && intro[ext_id].name_size != 0) { + if (ext_id < count && intro[ext_id].name_size != 0) { /* resized record */ record_size = intro[ext_id].record_size; } else { - ext = index->extensions->data; - record_size = ext[ext_id].record_size; + ext = array_idx(&index->extensions, ext_id); + record_size = ext->record_size; } - if (t->ext_rec_updates == NULL) - t->ext_rec_updates = buffer_create_dynamic(default_pool, 128); - buf = buffer_get_space_unsafe(t->ext_rec_updates, - ext_id * sizeof(buffer_t *), - sizeof(buffer_t *)); + if (!array_is_created(&t->ext_rec_updates)) { + ARRAY_CREATE(&t->ext_rec_updates, default_pool, + array_t, ext_id + 2); + } + array = array_modifyable_idx(&t->ext_rec_updates, ext_id); /* @UNSAFE */ - if (!mail_index_seq_buffer_add(buf, seq, data, record_size, - old_data_r)) { + if (!mail_index_seq_array_add(array, seq, data, record_size, + old_data_r)) { if (old_data_r != NULL) memset(old_data_r, 0, record_size); } @@ -939,9 +897,8 @@ enum modify_type modify_type, struct mail_keywords *keywords) { - buffer_t **buf; - unsigned int i; - size_t pos; + array_t *arr; + unsigned int i, idx; i_assert(seq > 0 && (seq <= mail_index_view_get_messages_count(t->view) || @@ -956,50 +913,42 @@ If t->keyword_resets is set for the sequence, there's no need to update remove_seq as it will remove all keywords. */ - if (t->keyword_updates == NULL) { + if (!array_is_created(&t->keyword_updates)) { uint32_t max_idx = keywords->idx[keywords->count-1]; - t->keyword_updates = - buffer_create_dynamic(default_pool, - max_idx * 2 * sizeof(buffer_t *)); + ARRAY_CREATE(&t->keyword_updates, default_pool, + array_t, max_idx * 2); } switch (modify_type) { case MODIFY_ADD: for (i = 0; i < keywords->count; i++) { - pos = keywords->idx[i] * 2 * sizeof(buffer_t *); - buf = buffer_get_space_unsafe(t->keyword_updates, pos, - sizeof(buffer_t *)); - mail_index_seq_range_buffer_add(buf, 64, seq); + idx = keywords->idx[i] * 2; + arr = array_modifyable_idx(&t->keyword_updates, idx); + mail_index_seq_range_array_add(arr, 16, seq); - buf = buffer_get_space_unsafe(t->keyword_updates, - pos + sizeof(buffer_t *), - sizeof(buffer_t *)); - mail_index_seq_range_buffer_remove(*buf, seq); + arr = array_modifyable_idx(&t->keyword_updates, idx+1); + mail_index_seq_range_array_remove(arr, seq); } break; case MODIFY_REMOVE: for (i = 0; i < keywords->count; i++) { - pos = keywords->idx[i] * 2 * sizeof(buffer_t *); - buf = buffer_get_space_unsafe(t->keyword_updates, pos, - sizeof(buffer_t *)); - mail_index_seq_range_buffer_remove(*buf, seq); + idx = keywords->idx[i] * 2; + arr = array_modifyable_idx(&t->keyword_updates, idx); + mail_index_seq_range_array_remove(arr, seq); - buf = buffer_get_space_unsafe(t->keyword_updates, - pos + sizeof(buffer_t *), - sizeof(buffer_t *)); - mail_index_seq_range_buffer_add(buf, 64, seq); + arr = array_modifyable_idx(&t->keyword_updates, idx+1); + mail_index_seq_range_array_add(arr, 16, seq); } break; case MODIFY_REPLACE: for (i = 0; i < keywords->count; i++) { - pos = keywords->idx[i] * 2 * sizeof(buffer_t *); - buf = buffer_get_space_unsafe(t->keyword_updates, pos, - sizeof(buffer_t *)); - mail_index_seq_range_buffer_add(buf, 64, seq); + idx = keywords->idx[i] * 2; + arr = array_modifyable_idx(&t->keyword_updates, idx); + mail_index_seq_range_array_add(arr, 16, seq); } - mail_index_seq_range_buffer_add(&t->keyword_resets, 64, seq); + mail_index_seq_range_array_add(&t->keyword_resets, 16, seq); break; }
--- a/src/lib-index/mail-index-view.c Sat Mar 12 20:15:48 2005 +0200 +++ b/src/lib-index/mail-index-view.c Sat Mar 12 20:16:29 2005 +0200 @@ -387,10 +387,9 @@ return ret; } - ext = (*map_r)->extensions->data; - ext += idx; + ext = array_idx(&(*map_r)->extensions, idx); + offset = ext->record_offset; - offset = ext->record_offset; *data_r = offset == 0 ? NULL : CONST_PTR_OFFSET(rec, offset); return ret; } @@ -418,9 +417,7 @@ return 0; } - ext = map->extensions->data; - ext += idx; - + ext = array_idx(&map->extensions, idx); *data_r = CONST_PTR_OFFSET(map->hdr_base, ext->hdr_offset); *data_size_r = ext->hdr_size; return 0; @@ -484,9 +481,7 @@ return ret; } - ext = map->extensions->data; - ext += idx; - + ext = array_idx(&map->extensions, idx); for (i = 0, idx = 0; i < ext->record_size; i++) { if (((const char *)data)[i] == 0) continue; @@ -606,12 +601,10 @@ const struct mail_index_ext * mail_index_view_get_ext(struct mail_index_view *view, uint32_t ext_id) { - const struct mail_index_ext *ext; uint32_t idx; if (!mail_index_map_get_ext_idx(view->map, ext_id, &idx)) return 0; - ext = view->map->extensions->data; - return &ext[idx]; + return array_idx(&view->map->extensions, idx); }
--- a/src/lib-index/mail-index.c Sat Mar 12 20:15:48 2005 +0200 +++ b/src/lib-index/mail-index.c Sat Mar 12 20:16:29 2005 +0200 @@ -27,10 +27,15 @@ index->fd = -1; index->extension_pool = pool_alloconly_create("extension", 256); - index->extensions = buffer_create_dynamic(index->extension_pool, 64); - index->sync_handlers = buffer_create_dynamic(default_pool, 64); - index->sync_lost_handlers = buffer_create_dynamic(default_pool, 64); - index->expunge_handlers = buffer_create_dynamic(default_pool, 32); + ARRAY_CREATE(&index->extensions, index->extension_pool, + struct mail_index_ext, 5); + + ARRAY_CREATE(&index->expunge_handlers, default_pool, + mail_index_expunge_handler_t *, 4); + ARRAY_CREATE(&index->sync_handlers, default_pool, + struct mail_index_sync_handler, 4); + ARRAY_CREATE(&index->sync_lost_handlers, default_pool, + mail_index_sync_lost_handler_t *, 4); index->mode = 0600; index->gid = (gid_t)-1; @@ -50,9 +55,9 @@ pool_unref(index->extension_pool); pool_unref(index->keywords_pool); - buffer_free(index->sync_handlers); - buffer_free(index->sync_lost_handlers); - buffer_free(index->expunge_handlers); + array_free(&index->sync_handlers); + array_free(&index->sync_lost_handlers); + array_free(&index->expunge_handlers); buffer_free(index->keywords_buf); i_free(index->error); @@ -75,14 +80,11 @@ { const struct mail_index_ext *extensions; struct mail_index_ext ext; - size_t ext_count; - unsigned int i; + unsigned int i, ext_count; - extensions = buffer_get_data(index->extensions, &ext_count); - ext_count /= sizeof(*extensions); + extensions = array_get(&index->extensions, &ext_count); - i_assert(index->sync_handlers->used / - sizeof(struct mail_index_sync_handler) == ext_count); + i_assert(array_count(&index->sync_handlers) == ext_count); /* see if it's already there */ for (i = 0; i < ext_count; i++) { @@ -97,9 +99,8 @@ ext.record_size = default_record_size; ext.record_align = default_record_align; - buffer_append(index->extensions, &ext, sizeof(ext)); - buffer_append_zero(index->sync_handlers, - sizeof(struct mail_index_sync_handler)); + array_append(&index->extensions, &ext, 1); + (void)array_modifyable_append(&index->sync_handlers); return ext_count; } @@ -107,37 +108,34 @@ uint32_t ext_id, mail_index_expunge_handler_t *cb) { - buffer_write(index->expunge_handlers, ext_id * sizeof(cb), - &cb, sizeof(cb)); + array_idx_set(&index->expunge_handlers, ext_id, &cb); } void mail_index_register_sync_handler(struct mail_index *index, uint32_t ext_id, mail_index_sync_handler_t *cb, enum mail_index_sync_handler_type type) { - struct mail_index_sync_handler h; + struct mail_index_sync_handler *h; - memset(&h, 0, sizeof(h)); - h.callback = cb; - h.type = type; - buffer_write(index->sync_handlers, ext_id * sizeof(h), &h, sizeof(h)); + h = array_modifyable_idx(&index->sync_handlers, ext_id); + h->callback = cb; + h->type = type; } void mail_index_register_sync_lost_handler(struct mail_index *index, mail_index_sync_lost_handler_t *cb) { - buffer_append(index->sync_lost_handlers, &cb, sizeof(cb)); + array_append(&index->sync_lost_handlers, &cb, 1); } static void mail_index_map_init_extbufs(struct mail_index_map *map, unsigned int initial_count) { - size_t ext_size, ext_id_map_size, size; + size_t size; - ext_size = initial_count * sizeof(struct mail_index_ext); - ext_id_map_size = initial_count * sizeof(uint32_t); if (map->extension_pool == NULL) { - size = ext_size + ext_id_map_size + + size = initial_count * sizeof(struct mail_index_ext) + + initial_count * sizeof(uint32_t) + (initial_count * 20); /* for names */ map->extension_pool = pool_alloconly_create("extensions", @@ -146,22 +144,21 @@ p_clear(map->extension_pool); } - map->extensions = buffer_create_dynamic(map->extension_pool, ext_size); - map->ext_id_map = - buffer_create_dynamic(map->extension_pool, ext_id_map_size); + ARRAY_CREATE(&map->extensions, map->extension_pool, + struct mail_index_ext, initial_count); + ARRAY_CREATE(&map->ext_id_map, map->extension_pool, + uint32_t, initial_count); } uint32_t mail_index_map_lookup_ext(struct mail_index_map *map, const char *name) { const struct mail_index_ext *extensions; - size_t i, size; + unsigned int i, size; - if (map->extensions == NULL) + if (!array_is_created(&map->extensions)) return (uint32_t)-1; - extensions = buffer_get_data(map->extensions, &size); - size /= sizeof(*extensions); - + extensions = array_get(&map->extensions, &size); for (i = 0; i < size; i++) { if (strcmp(extensions[i].name, name) == 0) return i; @@ -177,17 +174,17 @@ uint32_t record_align, uint32_t reset_id) { struct mail_index_ext *ext; - uint32_t idx, ext_id, empty_id = (uint32_t)-1; + uint32_t idx, empty_idx = (uint32_t)-1; - if (map->extensions == NULL) { + if (!array_is_created(&map->extensions)) { mail_index_map_init_extbufs(map, 5); idx = 0; } else { - idx = map->extensions->used / sizeof(*ext); + idx = array_count(&map->extensions); } i_assert(mail_index_map_lookup_ext(map, name) == (uint32_t)-1); - ext = buffer_append_space_unsafe(map->extensions, sizeof(*ext)); + ext = array_modifyable_append(&map->extensions); memset(ext, 0, sizeof(*ext)); ext->name = p_strdup(map->extension_pool, name); @@ -198,14 +195,12 @@ ext->record_align = record_align; ext->reset_id = reset_id; - ext_id = mail_index_ext_register(index, name, hdr_size, - record_size, record_align); - ext->index_idx = ext_id; + ext->index_idx = mail_index_ext_register(index, name, hdr_size, + record_size, record_align); - while (map->ext_id_map->used < ext_id * sizeof(uint32_t)) - buffer_append(map->ext_id_map, &empty_id, sizeof(empty_id)); - buffer_write(map->ext_id_map, ext_id * sizeof(uint32_t), - &idx, sizeof(idx)); + while (array_count(&map->ext_id_map) < ext->index_idx) + array_append(&map->ext_id_map, &empty_idx, 1); + array_idx_set(&map->ext_id_map, ext->index_idx, &idx); return idx; } @@ -240,12 +235,12 @@ return 1; } - old_count = index->extensions->used / sizeof(struct mail_index_ext); + old_count = array_count(&index->extensions); mail_index_map_init_extbufs(map, old_count + 5); ext_id = (uint32_t)-1; for (i = 0; i < old_count; i++) - buffer_append(map->ext_id_map, &ext_id, sizeof(ext_id)); + array_append(&map->ext_id_map, &ext_id, 1); while (offset < map->hdr.header_size) { ext_hdr = CONST_PTR_OFFSET(map->hdr_base, offset); @@ -307,8 +302,7 @@ return 0; } - ext = map->extensions->data; - ext += ext_id; + ext = array_idx(&map->extensions, ext_id); kw_hdr = CONST_PTR_OFFSET(map->hdr_base, ext->hdr_offset); kw_rec = (const void *)(kw_hdr + 1); @@ -761,8 +755,7 @@ int sync_to_index) { mail_index_sync_lost_handler_t *const *handlers; - size_t size; - unsigned int i; + unsigned int i, count; int ret, retry; if (index->log_locked) { @@ -785,10 +778,8 @@ } /* notify all "sync lost" handlers */ - handlers = buffer_get_data(index->sync_lost_handlers, &size); - size /= sizeof(*handlers); - - for (i = 0; i < size; i++) + handlers = array_get(&index->sync_lost_handlers, &count); + for (i = 0; i < count; i++) (*handlers[i])(index); for (i = 0; i < MAIL_INDEX_ESTALE_RETRY_COUNT; i++) { @@ -979,18 +970,15 @@ mem_map->hdr_base = hdr; /* copy extensions */ - if (map->ext_id_map != NULL) { - count = map->ext_id_map->used / sizeof(uint32_t); + if (array_is_created(&map->ext_id_map)) { + count = array_count(&map->ext_id_map); mail_index_map_init_extbufs(mem_map, count + 2); - buffer_append_buf(mem_map->extensions, map->extensions, - 0, (size_t)-1); - buffer_append_buf(mem_map->ext_id_map, map->ext_id_map, - 0, (size_t)-1); + array_append_array(&mem_map->extensions, &map->extensions); + array_append_array(&mem_map->ext_id_map, &map->ext_id_map); /* fix the name pointers to use our own pool */ - extensions = buffer_get_modifyable_data(mem_map->extensions, - NULL); + extensions = array_get_modifyable(&mem_map->extensions, &count); for (i = 0; i < count; i++) { extensions[i].name = p_strdup(mem_map->extension_pool, extensions[i].name); @@ -1003,14 +991,14 @@ int mail_index_map_get_ext_idx(struct mail_index_map *map, uint32_t ext_id, uint32_t *idx_r) { - const uint32_t *id_map; + const uint32_t *id; - if (map->ext_id_map == NULL || - map->ext_id_map->used / sizeof(*id_map) <= ext_id) + if (!array_is_created(&map->ext_id_map) || + ext_id >= array_count(&map->ext_id_map)) return 0; - id_map = map->ext_id_map->data; - *idx_r = id_map[ext_id]; + id = array_idx(&map->ext_id_map, ext_id); + *idx_r = *id; return *idx_r != (uint32_t)-1; }
--- a/src/lib-index/mail-transaction-log-append.c Sat Mar 12 20:15:48 2005 +0200 +++ b/src/lib-index/mail-transaction-log-append.c Sat Mar 12 20:16:29 2005 +0200 @@ -105,26 +105,23 @@ struct mail_transaction_ext_intro *intro; buffer_t *buf; uint32_t idx; - size_t size; + unsigned int count; if (!mail_index_map_get_ext_idx(t->view->map, ext_id, &idx)) { /* new extension */ idx = (uint32_t)-1; } - ext = t->view->index->extensions->data; - ext += ext_id; - - if (t->ext_resizes == NULL) { + ext = array_idx(&t->view->index->extensions, ext_id); + if (!array_is_created(&t->ext_resizes)) { intro = NULL; - size = 0; + count = 0; } else { - intro = buffer_get_modifyable_data(t->ext_resizes, &size); - size /= sizeof(*intro); + intro = array_get(&t->ext_resizes, &count); } buf = buffer_create_dynamic(pool_datastack_create(), 128); - if (ext_id < size && intro[ext_id].name_size != 0) { + if (ext_id < count && intro[ext_id].name_size != 0) { /* we're resizing it */ intro += ext_id; @@ -148,9 +145,7 @@ } else if (idx != (uint32_t)-1) { /* use the existing reset_id */ const struct mail_index_ext *map_ext = - t->view->map->extensions->data; - map_ext += idx; - + array_idx(&t->view->map->extensions, idx); intro->reset_id = map_ext->reset_id; } else { /* new extension, reset_id defaults to 0 */ @@ -170,34 +165,31 @@ { const struct mail_transaction_ext_intro *resize; struct mail_transaction_ext_reset ext_reset; - uint32_t ext_id, ext_count, update_count, resize_count, reset_count; + unsigned int update_count, resize_count, reset_count, ext_count; + uint32_t ext_id; const uint32_t *reset; - const buffer_t *const *update; + const array_t *update; buffer_t *buf; - size_t size; - if (t->ext_rec_updates == NULL) { + if (!array_is_created(&t->ext_rec_updates)) { update = NULL; update_count = 0; } else { - update = buffer_get_data(t->ext_rec_updates, &size); - update_count = size / sizeof(*update); + update = array_get(&t->ext_rec_updates, &update_count); } - if (t->ext_resizes == NULL) { + if (!array_is_created(&t->ext_resizes)) { resize = NULL; resize_count = 0; } else { - resize = buffer_get_data(t->ext_resizes, &size); - resize_count = size / sizeof(*resize); + resize = array_get(&t->ext_resizes, &resize_count); } - if (t->ext_resets == NULL) { + if (!array_is_created(&t->ext_resets)) { reset = NULL; reset_count = 0; } else { - reset = buffer_get_data(t->ext_resets, &size); - reset_count = size / sizeof(*reset); + reset = array_get(&t->ext_resets, &reset_count); } memset(&ext_reset, 0, sizeof(ext_reset)); @@ -212,7 +204,8 @@ ext_id < reset_count && reset[ext_id] != 0 ? reset[ext_id] : 0; if ((ext_id < resize_count && resize[ext_id].name_size) || - (ext_id < update_count && update[ext_id] != NULL) || + (ext_id < update_count && + array_is_created(&update[ext_id])) || ext_reset.new_reset_id != 0) { if (log_append_ext_intro(file, t, ext_id, 0) < 0) return -1; @@ -231,29 +224,27 @@ static int log_append_ext_rec_updates(struct mail_transaction_log_file *file, struct mail_index_transaction *t) { - buffer_t **updates; + array_t *updates; const uint32_t *reset; - uint32_t ext_id, reset_id, reset_count; - size_t size; + unsigned int ext_id, count, reset_count; + uint32_t reset_id; - if (t->ext_rec_updates == NULL) { + if (!array_is_created(&t->ext_rec_updates)) { updates = NULL; - size = 0; + count = 0; } else { - updates = buffer_get_modifyable_data(t->ext_rec_updates, &size); - size /= sizeof(*updates); + updates = array_get_modifyable(&t->ext_rec_updates, &count); } - if (t->ext_resets == NULL) { + if (!array_is_created(&t->ext_resets)) { reset = NULL; reset_count = 0; } else { - reset = buffer_get_data(t->ext_resets, &size); - reset_count = size / sizeof(*reset); + reset = array_get_modifyable(&t->ext_resets, &reset_count); } - for (ext_id = 0; ext_id < size; ext_id++) { - if (updates[ext_id] == NULL) + for (ext_id = 0; ext_id < count; ext_id++) { + if (!array_is_created(&updates[ext_id])) continue; reset_id = ext_id < reset_count && reset[ext_id] != 0 ? @@ -261,7 +252,7 @@ if (log_append_ext_intro(file, t, ext_id, reset_id) < 0) return -1; - if (log_append_buffer(file, updates[ext_id], NULL, + if (log_append_buffer(file, updates[ext_id].buffer, NULL, MAIL_TRANSACTION_EXT_REC_UPDATE, t->external) < 0) return -1; @@ -274,15 +265,15 @@ { struct mail_index *index = t->view->index; struct mail_transaction_keyword_update kt_hdr; - buffer_t *hdr_buf, **buf; - size_t i, size; + buffer_t *hdr_buf; + array_t *updates; + unsigned int i, count; hdr_buf = buffer_create_dynamic(pool_datastack_create(), 64); - buf = buffer_get_modifyable_data(t->keyword_updates, &size); - size /= sizeof(*buf); - for (i = 0; i < size; i++) { - if (buf[i] == NULL) + updates = array_get_modifyable(&t->keyword_updates, &count); + for (i = 0; i < count; i++) { + if (!array_is_created(&updates[i])) continue; buffer_set_used_size(hdr_buf, 0); @@ -296,7 +287,7 @@ if ((hdr_buf->used % 4) != 0) buffer_append_zero(hdr_buf, 4 - (hdr_buf->used % 4)); - if (log_append_buffer(file, buf[i], hdr_buf, + if (log_append_buffer(file, updates[i].buffer, hdr_buf, MAIL_TRANSACTION_KEYWORD_UPDATE, t->external) < 0) return -1; @@ -316,7 +307,7 @@ struct mail_index_header idx_hdr; uoff_t append_offset; unsigned int lock_id; - int ret; + int ret, visibility_changes = FALSE; index = mail_index_view_get_index(view); log = index->log; @@ -383,30 +374,35 @@ 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, + if (array_is_created(&t->appends) && ret == 0) { + visibility_changes = TRUE; + ret = log_append_buffer(file, t->appends.buffer, NULL, MAIL_TRANSACTION_APPEND, t->external); } - if (t->updates != NULL && ret == 0) { - ret = log_append_buffer(file, t->updates, NULL, + if (array_is_created(&t->updates) && ret == 0) { + visibility_changes = TRUE; + ret = log_append_buffer(file, t->updates.buffer, NULL, MAIL_TRANSACTION_FLAG_UPDATE, t->external); } - if (t->ext_rec_updates != NULL && ret == 0) + if (array_is_created(&t->ext_rec_updates) && ret == 0) ret = log_append_ext_rec_updates(file, t); /* keyword resets before updates */ - if (t->keyword_resets != NULL && ret == 0) { - ret = log_append_buffer(file, t->keyword_resets, NULL, + if (array_is_created(&t->keyword_resets) && ret == 0) { + visibility_changes = TRUE; + ret = log_append_buffer(file, t->keyword_resets.buffer, NULL, MAIL_TRANSACTION_KEYWORD_RESET, t->external); } - if (t->keyword_updates != NULL && ret == 0) + if (array_is_created(&t->keyword_updates) && ret == 0) { + visibility_changes = TRUE; ret = log_append_keyword_updates(file, t); + } - if (t->expunges != NULL && ret == 0) { - ret = log_append_buffer(file, t->expunges, NULL, + if (array_is_created(&t->expunges) && ret == 0) { + ret = log_append_buffer(file, t->expunges.buffer, NULL, MAIL_TRANSACTION_EXPUNGE, t->external); } if (t->hdr_changed && ret == 0) { @@ -420,8 +416,7 @@ "pwrite()"); } - if (ret == 0 && (t->updates != NULL || t->appends != NULL) && - t->hide_transaction) { + if (ret == 0 && visibility_changes && t->hide_transaction) { mail_index_view_add_synced_transaction(view, file->hdr.file_seq, append_offset); }