13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg/* Copyright (c) 2004-2018 Dovecot authors, see the included COPYING file */
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankgvoid mail_index_sync_init_expunge_handlers(struct mail_index_sync_map_ctx *ctx)
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg rext = array_get(&ctx->view->index->extensions, &rext_count);
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg ext = array_get(&ctx->view->map->extensions, &ext_count);
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg id_map = array_get(&ctx->view->map->ext_id_map, &id_map_count);
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg contexts = array_get_modifiable(&ctx->extra_contexts, &context_count);
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg for (idx_ext_id = 0; idx_ext_id < rext_count; idx_ext_id++) {
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg map_ext_id = idx_ext_id >= id_map_count ? (uint32_t)-1 :
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankgmail_index_sync_deinit_expunge_handlers(struct mail_index_sync_map_ctx *ctx)
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankgvoid mail_index_sync_init_handlers(struct mail_index_sync_map_ctx *ctx)
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg /* set space for extra contexts */
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg /* make sure the extra_contexts contains everything */
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg (void)array_idx_get_space(&ctx->extra_contexts, count - 1);
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg /* we need to update the expunge handler list in case they had
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg already been called */
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankgvoid mail_index_sync_deinit_handlers(struct mail_index_sync_map_ctx *ctx)
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg rext = array_get(&ctx->view->index->extensions, &rext_count);
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg array_get_modifiable(&ctx->extra_contexts, &context_count);
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg for (i = 0; i < context_count; i++) {
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankgget_ext_header(struct mail_index_map *map, const struct mail_index_ext *ext)
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg /* do some kludgy jumping to get to it. */
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg hdr_base = buffer_get_modifiable_data(map->hdr_copy_buf, NULL);
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankgstatic int mail_index_ext_align_cmp(const void *p1, const void *p2)
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg const struct mail_index_ext *const *e1 = p1, *const *e2 = p2;
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg return (int)(*e2)->record_align - (int)(*e1)->record_align;
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankgstatic void sync_ext_reorder(struct mail_index_map *map, uint32_t ext_map_idx,
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg uint16_t *old_offsets, *copy_sizes, min_align, max_align;
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg i_assert(MAIL_INDEX_MAP_IS_IN_MEMORY(map) && map->refcount == 1);
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg ext = array_get_modifiable(&map->extensions, &count);
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg /* @UNSAFE */
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg for (i = 0; i < count; i++) {
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg qsort(sorted, count, sizeof(struct mail_index_ext *),
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg /* we are growing the extension record. remember this
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg so we don't write extra data while copying the record */
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg /* we simply try to use the extensions with largest alignment
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg requirement first. FIXME: if the extension sizes don't match
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg alignment, this may not give the minimal layout. */
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg for (i = 0; i < count; i++) {
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg if (i == count) {
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg /* all done */
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg /* we have to leave space here */
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg /* keep record size divisible with maximum alignment */
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg i_assert(new_record_size >= sizeof(struct mail_index_record));
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg /* copy the records to new buffer */
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg new_buffer_size = map->rec_map->records_count * new_record_size;
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg new_buffer = buffer_create_dynamic(default_pool, new_buffer_size);
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg for (rec_idx = 0; rec_idx < map->rec_map->records_count; rec_idx++) {
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg /* write the base record */
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg sizeof(struct mail_index_record));
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg /* write extensions */
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg for (i = 0; i < count; i++) {
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg buffer_write(new_buffer, offset + ext[i].record_offset,
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg /* we didn't fully write the last record */
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg buffer_get_modifiable_data(map->rec_map->buffer, NULL);
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg /* update record offsets in headers */
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg for (i = 0; i < count; i++) {
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankgsync_ext_resize(const struct mail_transaction_ext_intro *u,
13b501825bce68e7e49b4bc775da93e38d9bd9f3fuankg uint32_t ext_map_idx, struct mail_index_sync_map_ctx *ctx,
bool no_shrink)
if (no_shrink)
if (no_shrink)
if (reorder)
return TRUE;
return FALSE;
return TRUE;
const char *name,
ext_hdr);
struct mail_transaction_ext_intro u;
i_unreached();
if (!fix_size)
i_zero(&u);
const struct mail_transaction_ext_intro *u)
const struct mail_transaction_ext_reset *u)
if (u->preserve_data == 0)
const void *data)
const struct mail_transaction_ext_rec_update *u)
if (ret <= 0)
return ret;
const struct mail_transaction_ext_atomic_inc *u)
if (u->diff <= 0) {