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