]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-index: Don't even try to add fields to cache that exceed record_max_size
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 31 Mar 2020 08:40:58 +0000 (11:40 +0300)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 15 Apr 2020 09:41:43 +0000 (12:41 +0300)
Previously these were temporarily added to memory and later on the whole
cache record was just dropped. But usually not all the cache fields are
huge, so it's better to add some fields to cache than none.

src/lib-index/mail-cache-transaction.c

index e9aa87b48298e79b354cc7fa0688e787b2835cc1..a978aee21cc538188e2b61447269325e07af81fd 100644 (file)
@@ -701,7 +701,7 @@ void mail_cache_add(struct mail_cache_transaction_ctx *ctx, uint32_t seq,
 {
        uint32_t data_size32;
        unsigned int fixed_size;
-       size_t full_size;
+       size_t full_size, record_size;
 
        i_assert(field_idx < ctx->cache->fields_count);
        i_assert(data_size < (uint32_t)-1);
@@ -720,6 +720,9 @@ void mail_cache_add(struct mail_cache_transaction_ctx *ctx, uint32_t seq,
        i_assert(fixed_size == UINT_MAX || fixed_size == data_size);
 
        data_size32 = (uint32_t)data_size;
+       full_size = sizeof(field_idx) + ((data_size + 3) & ~3);
+       if (fixed_size == UINT_MAX)
+               full_size += sizeof(data_size32);
 
        if (ctx->prev_seq != seq) {
                mail_cache_transaction_switch_seq(ctx);
@@ -734,6 +737,15 @@ void mail_cache_add(struct mail_cache_transaction_ctx *ctx, uint32_t seq,
                        ctx->view->trans_seq2 = seq;
        }
 
+       if (mail_cache_transaction_update_last_rec_size(ctx, &record_size) &&
+           record_size + full_size >
+           ctx->cache->index->optimization_set.cache.record_max_size) {
+               /* Adding this field would exceed the cache record's maximum
+                  size. If we don't add this, it's possible that other fields
+                  could still be added. */
+               return;
+       }
+
        /* Remember that this field has been used within the transaction. Later
           on we fill mail_cache_field_private.used with it. We can't rely on
           setting it here, because cache compression may run and clear it. */
@@ -745,10 +757,6 @@ void mail_cache_add(struct mail_cache_transaction_ctx *ctx, uint32_t seq,
        buffer_write(ctx->view->cached_exists_buf, field_idx,
                     &ctx->view->cached_exists_value, 1);
 
-       full_size = sizeof(field_idx) + ((data_size + 3) & ~3);
-       if (fixed_size == UINT_MAX)
-               full_size += sizeof(data_size32);
-
        if (ctx->cache_data->used + full_size > MAIL_CACHE_MAX_WRITE_BUFFER &&
            ctx->last_rec_pos > 0) {
                /* time to flush our buffer. */