]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-index: Allow updating cache's last_used field with mail_cache_register_fields()
authorTimo Sirainen <tss@iki.fi>
Sat, 10 Dec 2011 06:42:26 +0000 (08:42 +0200)
committerTimo Sirainen <tss@iki.fi>
Sat, 10 Dec 2011 06:42:26 +0000 (08:42 +0200)
src/lib-index/mail-cache-compress.c
src/lib-index/mail-cache-decisions.c
src/lib-index/mail-cache-fields.c
src/lib-index/mail-cache-private.h
src/lib-index/mail-cache.h

index cb9b692916c48461b783b77685c998aaee2f62f1..a52a1bb0b79fa8c85b082cba4a072a26e690ca8e 100644 (file)
@@ -208,7 +208,7 @@ mail_cache_copy(struct mail_cache *cache, struct mail_index_transaction *trans,
                        /* if the decision isn't forced and this field hasn't
                           been accessed for a while, drop it */
                        if ((dec & MAIL_CACHE_DECISION_FORCED) == 0 &&
-                           (time_t)priv->last_used < max_drop_time &&
+                           priv->field.last_used < max_drop_time &&
                            !priv->adding) {
                                dec = MAIL_CACHE_DECISION_NO;
                                priv->field.decision = dec;
@@ -218,7 +218,7 @@ mail_cache_copy(struct mail_cache *cache, struct mail_index_transaction *trans,
                        if ((dec & ~MAIL_CACHE_DECISION_FORCED) ==
                            MAIL_CACHE_DECISION_NO && !priv->adding) {
                                priv->used = FALSE;
-                               priv->last_used = 0;
+                               priv->field.last_used = 0;
                        }
 
                        ctx.field_file_map[i] = !priv->used ?
index 0cdbcfc4d15d85087857e9817d0ae1c89fec9b5f..12754a20153d90b51f30b9f85abf1c287e1a1873 100644 (file)
@@ -89,9 +89,9 @@ void mail_cache_decision_state_update(struct mail_cache_view *view,
                return;
        }
 
-       if (ioloop_time - cache->fields[field].last_used > 3600*24) {
+       if (ioloop_time - cache->fields[field].field.last_used > 3600*24) {
                /* update last_used about once a day */
-               cache->fields[field].last_used = (uint32_t)ioloop_time;
+               cache->fields[field].field.last_used = (uint32_t)ioloop_time;
                if (cache->field_file_map[field] != (uint32_t)-1)
                        cache->field_header_write_pending = TRUE;
        }
index 1326adedb9020f9b2dfd118cfbeda992cc622590..1d134ed817b8da7d17c3e4e2a36a77075414e7be 100644 (file)
@@ -65,11 +65,35 @@ static int field_type_verify(struct mail_cache *cache, unsigned int idx,
        return 0;
 }
 
+static void
+mail_cache_field_update(struct mail_cache *cache,
+                       const struct mail_cache_field *newfield)
+{
+       struct mail_cache_field_private *orig;
+
+       i_assert(newfield->type < MAIL_CACHE_FIELD_COUNT);
+
+       orig = &cache->fields[newfield->idx];
+       if (newfield->decision != MAIL_CACHE_DECISION_NO &&
+           orig->field.decision != newfield->decision) {
+               orig->field.decision = newfield->decision;
+               orig->decision_dirty = TRUE;
+       }
+       if (orig->field.last_used < newfield->last_used) {
+               orig->field.last_used = newfield->last_used;
+               orig->decision_dirty = TRUE;
+       }
+       if (orig->decision_dirty)
+               cache->field_header_write_pending = TRUE;
+
+       (void)field_type_verify(cache, newfield->idx,
+                               newfield->type, newfield->field_size);
+}
+
 void mail_cache_register_fields(struct mail_cache *cache,
                                struct mail_cache_field *fields,
                                unsigned int fields_count)
 {
-       struct mail_cache_field *orig_field;
        void *orig_key, *orig_value;
        char *name;
        unsigned int new_idx;
@@ -80,18 +104,9 @@ void mail_cache_register_fields(struct mail_cache *cache,
                if (hash_table_lookup_full(cache->field_name_hash,
                                           fields[i].name,
                                           &orig_key, &orig_value)) {
-                       i_assert(fields[i].type < MAIL_CACHE_FIELD_COUNT);
-
                        fields[i].idx =
                                POINTER_CAST_TO(orig_value, unsigned int);
-
-                       orig_field = &cache->fields[fields[i].idx].field;
-                       if (orig_field->decision == MAIL_CACHE_DECISION_NO)
-                               orig_field->decision = fields[i].decision;
-
-                       (void)field_type_verify(cache, fields[i].idx,
-                                               fields[i].type,
-                                               fields[i].field_size);
+                       mail_cache_field_update(cache, &fields[i]);
                        continue;
                }
 
@@ -130,6 +145,7 @@ void mail_cache_register_fields(struct mail_cache *cache,
                name = p_strdup(cache->field_pool, fields[i].name);
                cache->fields[idx].field = fields[i];
                cache->fields[idx].field.name = name;
+               cache->fields[idx].field.last_used = fields[i].last_used;
                cache->field_file_map[idx] = (uint32_t)-1;
 
                if (!field_has_fixed_size(cache->fields[idx].field.type))
@@ -387,12 +403,12 @@ int mail_cache_header_fields_read(struct mail_cache *cache)
                cache->file_field_map[i] = fidx;
 
                /* update last_used if it's newer than ours */
-               if (last_used[i] > cache->fields[fidx].last_used)
-                       cache->fields[fidx].last_used = last_used[i];
+               if (last_used[i] > cache->fields[fidx].field.last_used)
+                       cache->fields[fidx].field.last_used = last_used[i];
 
                dec = cache->fields[fidx].field.decision;
-               if ((time_t)cache->fields[fidx].last_used < max_drop_time &&
-                   cache->fields[fidx].last_used != 0 &&
+               if (cache->fields[fidx].field.last_used < max_drop_time &&
+                   cache->fields[fidx].field.last_used != 0 &&
                    (dec & MAIL_CACHE_DECISION_FORCED) == 0 &&
                    dec != MAIL_CACHE_DECISION_NO) {
                        /* time to drop this field. don't bother dropping
@@ -469,7 +485,7 @@ static int mail_cache_header_fields_update_locked(struct mail_cache *cache)
        buffer = buffer_create_dynamic(pool_datastack_create(), 256);
 
        copy_to_buf(cache, buffer, FALSE,
-                   offsetof(struct mail_cache_field_private, last_used),
+                   offsetof(struct mail_cache_field, last_used),
                    sizeof(uint32_t));
        ret = mail_cache_write(cache, buffer->data, buffer->used,
                               offset + MAIL_CACHE_FIELD_LAST_USED());
@@ -532,7 +548,7 @@ void mail_cache_header_fields_get(struct mail_cache *cache, buffer_t *dest)
 
        /* we have to keep the field order for the existing fields. */
        copy_to_buf(cache, dest, TRUE,
-                   offsetof(struct mail_cache_field_private, last_used),
+                   offsetof(struct mail_cache_field, last_used),
                    sizeof(uint32_t));
        copy_to_buf(cache, dest, TRUE,
                    offsetof(struct mail_cache_field, field_size),
index 97c60d77d2c38a0ba6e0480247a2fc5fab752e75..088722ddb799a4e1c3e98a7801f7de0d9775f239 100644 (file)
@@ -117,7 +117,6 @@ struct mail_cache_field_private {
        struct mail_cache_field field;
 
        uint32_t uid_highwater;
-       uint32_t last_used;
 
        /* Unused fields aren't written to cache file */
        unsigned int used:1;
index 6c6549f3f22ceb5fc3da2558947d543e0dfa3c98..69f39ac8b4d1fa2c386c85483b9d2b313a4cf94e 100644 (file)
@@ -38,6 +38,8 @@ struct mail_cache_field {
        enum mail_cache_field_type type;
        unsigned int field_size;
        enum mail_cache_decision_type decision;
+       /* If higher than the current last_used field, update it */
+       time_t last_used;
 };
 
 struct mail_cache *mail_cache_open_or_create(struct mail_index *index);