Mercurial > dovecot > core-2.2
changeset 2555:87af1f39a69e HEAD
Added support for bitmask type.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 04 Sep 2004 13:26:36 +0300 |
parents | 3ad5b4e60321 |
children | d39842e9e83b |
files | src/lib-index/mail-cache-compress.c src/lib-index/mail-cache-lookup.c |
diffstat | 2 files changed, 86 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-cache-compress.c Sat Sep 04 12:09:27 2004 +0300 +++ b/src/lib-index/mail-cache-compress.c Sat Sep 04 13:26:36 2004 +0300 @@ -14,26 +14,67 @@ uint8_t field_seen_value; }; +static void mail_cache_merge_bitmask(struct mail_cache *cache, buffer_t *buffer, + uint32_t file_field, const void *data, + size_t data_size) +{ + void *buf_data; + uint32_t field, buf_file_field; + unsigned int i, buf_data_size; + size_t pos, buf_size; + + buf_data = buffer_get_modifyable_data(buffer, &buf_size); + for (pos = sizeof(struct mail_cache_record); pos < buf_size; ) { + buf_file_field = *((uint32_t *)PTR_OFFSET(buf_data, pos)); + pos += sizeof(uint32_t); + + field = cache->file_field_map[file_field]; + buf_data_size = cache->fields[field].field.field_size; + if (buf_data_size == (unsigned int)-1) { + buf_data_size = + *((uint32_t *)PTR_OFFSET(buf_data, pos)); + pos += sizeof(uint32_t); + } + + if (buf_file_field == file_field) { + /* found it, do the merging */ + unsigned char *dest = PTR_OFFSET(buf_data, pos); + + i_assert(buf_data_size == data_size); + for (i = 0; i < buf_data_size; i++) + dest[i] |= ((const unsigned char*)data)[i]; + break; + } + pos += (data_size + 3) & ~3; + } +} + static int mail_cache_compress_callback(struct mail_cache_view *view, uint32_t file_field, const void *data, size_t data_size, void *context) { struct mail_cache_copy_context *ctx = context; + struct mail_cache_field *cache_field; enum mail_cache_decision_type dec; unsigned int field; uint8_t *field_seen; uint32_t size32; + field = view->cache->file_field_map[file_field]; + cache_field = &view->cache->fields[field].field; + field_seen = buffer_get_space_unsafe(ctx->field_seen, file_field, 1); if (*field_seen == ctx->field_seen_value) { /* duplicate */ + if (cache_field->type == MAIL_CACHE_FIELD_BITMASK) { + mail_cache_merge_bitmask(view->cache, ctx->buffer, + field, data, data_size); + } return 1; } *field_seen = ctx->field_seen_value; - field = view->cache->file_field_map[file_field]; - dec = view->cache->fields[field].field.decision & - ~MAIL_CACHE_DECISION_FORCED; + dec = cache_field->decision & ~MAIL_CACHE_DECISION_FORCED; if (ctx->new_msg) { if (dec == MAIL_CACHE_DECISION_NO) return 1; @@ -44,7 +85,7 @@ buffer_append(ctx->buffer, &file_field, sizeof(file_field)); - if (view->cache->fields[field].field.field_size == (unsigned int)-1) { + if (cache_field->field_size == (unsigned int)-1) { size32 = (uint32_t)data_size; buffer_append(ctx->buffer, &size32, sizeof(size32)); }
--- a/src/lib-index/mail-cache-lookup.c Sat Sep 04 12:09:27 2004 +0300 +++ b/src/lib-index/mail-cache-lookup.c Sat Sep 04 13:26:36 2004 +0300 @@ -73,7 +73,8 @@ mail_cache_foreach_callback_t *callback, void *context) { struct mail_cache *cache = view->cache; - size_t pos, next_pos, max_size, data_size; + size_t pos, next_pos, max_size; + unsigned int data_size; uint32_t file_field; unsigned int field; int ret; @@ -204,6 +205,7 @@ uint32_t file_field; size_t size; + i_assert(seq > 0); i_assert(field < view->cache->fields_count); file_field = view->cache->field_file_map[field]; @@ -231,6 +233,7 @@ struct mail_cache_lookup_context { buffer_t *dest_buf; uint32_t file_field; + int found; }; static int @@ -244,13 +247,35 @@ return 1; buffer_append(ctx->dest_buf, data, data_size); + ctx->found = TRUE; return 0; } +static int +mail_cache_lookup_bitmask_callback(struct mail_cache_view *view __attr_unused__, + uint32_t file_field, const void *data, + size_t data_size, void *context) +{ + struct mail_cache_lookup_context *ctx = context; + unsigned char *dest; + size_t i; + + if (ctx->file_field != file_field) + return 1; + + /* merge all bits */ + dest = buffer_get_space_unsafe(ctx->dest_buf, 0, data_size); + for (i = 0; i < data_size; i++) + dest[i] |= ((const unsigned char *)data)[i]; + ctx->found = TRUE; + return 1; +} + int mail_cache_lookup_field(struct mail_cache_view *view, buffer_t *dest_buf, uint32_t seq, unsigned int field) { struct mail_cache_lookup_context ctx; + unsigned int data_size; int ret; if ((ret = mail_cache_field_exists(view, seq, field)) <= 0) @@ -261,8 +286,21 @@ /* should exist. find it. */ ctx.file_field = view->cache->field_file_map[field]; ctx.dest_buf = dest_buf; - return mail_cache_foreach(view, seq, mail_cache_lookup_callback, - &ctx) == 0; + ctx.found = FALSE; + if (view->cache->fields[field].field.type != MAIL_CACHE_FIELD_BITMASK) { + ret = mail_cache_foreach(view, seq, mail_cache_lookup_callback, + &ctx); + } else { + /* make sure we're cleared first */ + data_size = view->cache->fields[field].field.field_size; + memset(buffer_get_space_unsafe(dest_buf, 0, data_size), + 0, data_size); + + ret = mail_cache_foreach(view, seq, + mail_cache_lookup_bitmask_callback, + &ctx); + } + return ret < 0 ? -1 : ctx.found; } struct header_lookup_data_rec {