mail-cache-compress.c revision 6237f743bbaf74de5a2d2051672baed87023657b
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainenmail_cache_merge_bitmask(struct mail_cache_copy_context *ctx,
a91bd6256b33729531c33ff8bc66ee1ae95840f9Timo Sirainen unsigned char *dest;
a91bd6256b33729531c33ff8bc66ee1ae95840f9Timo Sirainen unsigned int i, *pos;
a91bd6256b33729531c33ff8bc66ee1ae95840f9Timo Sirainen pos = array_idx_modifiable(&ctx->bitmask_pos, field->field_idx);
a91bd6256b33729531c33ff8bc66ee1ae95840f9Timo Sirainen if (*pos == 0) {
a91bd6256b33729531c33ff8bc66ee1ae95840f9Timo Sirainen /* we decided to drop this field */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen dest = buffer_get_space_unsafe(ctx->buffer, *pos, field->size);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen dest[i] |= ((const unsigned char*)field->data)[i];
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenmail_cache_compress_field(struct mail_cache_copy_context *ctx,
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen cache_field = &ctx->cache->fields[field_idx].field;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen field_seen = buffer_get_space_unsafe(ctx->field_seen, field_idx, 1);
c040ee67d0ac0fb7375bb543965bf67dcae6affaTimo Sirainen /* duplicate */
533bfba437e4120aa29dd45bca2aa87e30ee28a2Timo Sirainen if (cache_field->type == MAIL_CACHE_FIELD_BITMASK)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen dec = cache_field->decision & ~MAIL_CACHE_DECISION_FORCED;
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen buffer_append(ctx->buffer, &field_idx, sizeof(field_idx));
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen if (cache_field->field_size == (unsigned int)-1) {
4ba962c3e78f140facdcfb1e093c4c46de75ae24Timo Sirainen buffer_append(ctx->buffer, &size32, sizeof(size32));
4ba962c3e78f140facdcfb1e093c4c46de75ae24Timo Sirainen if (cache_field->type == MAIL_CACHE_FIELD_BITMASK) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* remember the position in case we need to update it */
a91bd6256b33729531c33ff8bc66ee1ae95840f9Timo Sirainen array_idx_set(&ctx->bitmask_pos, field->field_idx, &pos);
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen buffer_append(ctx->buffer, field->data, field->size);
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen buffer_append_zero(ctx->buffer, 4 - (field->size & 3));
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainenget_next_file_seq(struct mail_cache *cache, struct mail_index_view *view)
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen ext = mail_index_view_get_ext(view, cache->ext_id);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen file_seq = ext != NULL ? ext->reset_id + 1 : (uint32_t)ioloop_time;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (cache->hdr != NULL && file_seq <= cache->hdr->file_seq)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenmail_cache_copy(struct mail_cache *cache, struct mail_index_transaction *trans,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen uint32_t i, message_count, seq, first_new_seq, ext_offset;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen view = mail_index_transaction_get_view(trans);
d02d34e138e32b4266f5a403d6c51d7803bf322fTimo Sirainen /* get sequence of first message which doesn't need its temp fields
5694eeb99b69dea8033ca77ad69743c6b4871370Timo Sirainen message_count = mail_index_view_get_messages_count(view);
b13f738e8eb3f24dc2abf2c804f954b4d864ac6fTimo Sirainen if (mail_index_lookup_uid_range(view, idx_hdr->day_first_uid[7],
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen cache_view = mail_cache_view_open(cache, view);
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen output = o_stream_create_file(fd, default_pool, 0, FALSE);
4d84348ffcbb60de566108562c95ad64629e7a53Timo Sirainen hdr.file_seq = get_next_file_seq(cache, view);
9f46aa48a9982567a37bb08dd95af8bee5100c7eTimo Sirainen ctx.buffer = buffer_create_dynamic(default_pool, 4096);
9f46aa48a9982567a37bb08dd95af8bee5100c7eTimo Sirainen ctx.field_seen = buffer_create_dynamic(default_pool, 64);
9f46aa48a9982567a37bb08dd95af8bee5100c7eTimo Sirainen if (mail_index_transaction_is_expunged(trans, seq)) {
4366a21968093172d9b757fe6894b1ee8916434eTimo Sirainen memset(buffer_get_modifiable_data(ctx.field_seen, NULL),
4366a21968093172d9b757fe6894b1ee8916434eTimo Sirainen buffer_append(ctx.buffer, &cache_rec, sizeof(cache_rec));
4366a21968093172d9b757fe6894b1ee8916434eTimo Sirainen mail_cache_lookup_iter_init(cache_view, seq, &iter);
4366a21968093172d9b757fe6894b1ee8916434eTimo Sirainen while (mail_cache_lookup_iter_next(&iter, &field) > 0)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen cache_rec.size = buffer_get_used_size(ctx.buffer);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* nothing cached */
4645cc6c911a95991d7af43b40f88e99506ea5e9Timo Sirainen o_stream_send(output, ctx.buffer->data, cache_rec.size);
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen i_assert(array_count(ext_offsets) == message_count);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen /* we wrote everything using our internal field ids. so we want
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen mail_cache_header_fields_get() to use them and ignore any
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen existing id mappings in the old cache file. */
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen buffer = buffer_create_dynamic(pool_datastack_create(), 256);
4d84348ffcbb60de566108562c95ad64629e7a53Timo Sirainen o_stream_send(output, buffer_get_data(buffer, NULL),
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainen mail_cache_set_syscall_error(cache, "o_stream_flush()");
if (ret >= 0) {
if (ret == 0)
bool *unlock)
unsigned int i, count;
0, &dotlock);
if (ret < 0)
if (*unlock) {
t_push();
t_pop();
t_pop();
for (i = 0; i < count; i++) {
if (offsets[i] != 0) {
t_pop();
if (*unlock) {
int ret;
if (unlock) {
return ret;