dovecot-2.0: lib-storage: Added support for listing/adding cache...

dovecot at dovecot.org dovecot at dovecot.org
Tue Nov 17 03:00:42 EET 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/69c2aa08cf2c
changeset: 10337:69c2aa08cf2c
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Nov 16 19:38:13 2009 -0500
description:
lib-storage: Added support for listing/adding cache fields.

diffstat:

3 files changed, 84 insertions(+), 3 deletions(-)
src/lib-storage/index/index-status.c  |   32 ++++++++++++++++++++--
src/lib-storage/index/index-storage.c |   48 +++++++++++++++++++++++++++++++++
src/lib-storage/mail-storage.h        |    7 ++++

diffs (150 lines):

diff -r e18645b47984 -r 69c2aa08cf2c src/lib-storage/index/index-status.c
--- a/src/lib-storage/index/index-status.c	Mon Nov 16 18:38:06 2009 -0500
+++ b/src/lib-storage/index/index-status.c	Mon Nov 16 19:38:13 2009 -0500
@@ -1,8 +1,34 @@
 /* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "array.h"
+#include "mail-cache.h"
 #include "index-storage.h"
 #include "mail-index-modseq.h"
+
+static void
+index_storage_get_status_cache_fields(struct index_mailbox *ibox,
+				      struct mailbox_status *status_r)
+{
+	const struct mail_cache_field *fields;
+	enum mail_cache_decision_type dec;
+	ARRAY_TYPE(const_string) *cache_fields;
+	unsigned int i, count;
+
+	fields = mail_cache_register_get_list(ibox->cache,
+					      pool_datastack_create(), &count);
+
+	/* a bit leaky to allocate memory from mailbox pool every time, but this
+	   is unlikely to be called more than once for the mailbox anyway. */
+	cache_fields = p_new(ibox->box.pool, ARRAY_TYPE(const_string), 1);
+	p_array_init(cache_fields, ibox->box.pool, count);
+	for (i = 0; i < count; i++) {
+		dec = fields[i].decision & ~MAIL_CACHE_DECISION_FORCED;
+		if (dec != MAIL_CACHE_DECISION_NO)
+			array_append(cache_fields, &fields[i].name, 1);
+	}
+	status_r->cache_fields = cache_fields;
+}
 
 void index_storage_get_status(struct mailbox *box,
 			      enum mailbox_status_items items,
@@ -35,11 +61,13 @@ void index_storage_get_status(struct mai
 		}
 	}
 
-	if (items & STATUS_FIRST_UNSEEN_SEQ) {
+	if ((items & STATUS_FIRST_UNSEEN_SEQ) != 0) {
 		mail_index_lookup_first(ibox->view, 0, MAIL_SEEN,
 					&status_r->first_unseen_seq);
 	}
 
-	if (items & STATUS_KEYWORDS)
+	if ((items & STATUS_KEYWORDS) != 0)
 		status_r->keywords = mail_index_get_keywords(ibox->index);
+	if ((items & STATUS_CACHE_FIELDS) != 0)
+		index_storage_get_status_cache_fields(ibox, status_r);
 }
diff -r e18645b47984 -r 69c2aa08cf2c src/lib-storage/index/index-storage.c
--- a/src/lib-storage/index/index-storage.c	Mon Nov 16 18:38:06 2009 -0500
+++ b/src/lib-storage/index/index-storage.c	Mon Nov 16 19:38:13 2009 -0500
@@ -539,6 +539,52 @@ void index_storage_mailbox_close(struct 
 	pool_unref(&box->pool);
 }
 
+static void
+index_storage_mailbox_update_cache_fields(struct index_mailbox *ibox,
+					  const struct mailbox_update *update)
+{
+	const char *const *field_names = update->cache_fields;
+	ARRAY_DEFINE(new_fields, struct mail_cache_field);
+	const struct mail_cache_field *old_fields;
+	struct mail_cache_field field;
+	unsigned int i, j, old_count;
+
+	old_fields = mail_cache_register_get_list(ibox->cache,
+						  pool_datastack_create(),
+						  &old_count);
+
+	/* There shouldn't be many fields, so don't worry about O(n^2). */
+	t_array_init(&new_fields, 32);
+	for (i = 0; field_names[i] != NULL; i++) {
+		/* see if it's an existing field */
+		for (j = 0; j < old_count; j++) {
+			if (strcmp(field_names[i], old_fields[j].name) == 0)
+				break;
+		}
+		if (j != old_count) {
+			field = old_fields[i];
+			if (field.decision == MAIL_CACHE_DECISION_NO)
+				field.decision = MAIL_CACHE_DECISION_TEMP;
+			array_append(&new_fields, &field, 1);
+		} else if (strncmp(field_names[i], "hdr.", 4) == 0) {
+			/* new header */
+			memset(&field, 0, sizeof(field));
+			field.name = field_names[i];
+			field.type = MAIL_CACHE_FIELD_HEADER;
+			field.decision = MAIL_CACHE_DECISION_TEMP;
+			array_append(&new_fields, &field, 1);
+		} else {
+			/* new unknown field. we can't do anything about
+			   this since we don't know its type */
+		}
+	}
+	if (array_count(&new_fields) > 0) {
+		mail_cache_register_fields(ibox->cache,
+					   array_idx_modifiable(&new_fields, 0),
+					   array_count(&new_fields));
+	}
+}
+
 int index_storage_mailbox_update(struct mailbox *box,
 				 const struct mailbox_update *update)
 {
@@ -552,6 +598,8 @@ int index_storage_mailbox_update(struct 
 		if (mailbox_open(box) < 0)
 			return -1;
 	}
+	if (update->cache_fields != NULL)
+		index_storage_mailbox_update_cache_fields(ibox, update);
 
 	/* make sure we get the latest index info */
 	(void)mail_index_refresh(ibox->index);
diff -r e18645b47984 -r 69c2aa08cf2c src/lib-storage/mail-storage.h
--- a/src/lib-storage/mail-storage.h	Mon Nov 16 18:38:06 2009 -0500
+++ b/src/lib-storage/mail-storage.h	Mon Nov 16 19:38:13 2009 -0500
@@ -60,7 +60,8 @@ enum mailbox_status_items {
 	STATUS_FIRST_UNSEEN_SEQ	= 0x20,
 	STATUS_KEYWORDS		= 0x40,
 	STATUS_HIGHESTMODSEQ	= 0x80,
-	STATUS_GUID		= 0x100
+	STATUS_GUID		= 0x100,
+	STATUS_CACHE_FIELDS	= 0x200
 };
 
 enum mailbox_search_result_flags {
@@ -185,6 +186,8 @@ struct mailbox_status {
 	uint8_t mailbox_guid[MAIL_GUID_128_SIZE];
 
 	const ARRAY_TYPE(keywords) *keywords;
+	/* Fields that have "temp" or "yes" caching decision. */
+	const ARRAY_TYPE(const_string) *cache_fields;
 
 	/* There are expunges that haven't been synced yet */
 	unsigned int sync_delayed_expunges:1;
@@ -198,6 +201,8 @@ struct mailbox_update {
 	uint32_t uid_validity;
 	uint32_t min_next_uid;
 	uint64_t min_highest_modseq;
+	/* Add these fields to be temporarily cached, if they aren't already. */
+	const char *const *cache_fields;
 };
 
 struct mail_transaction_commit_changes {


More information about the dovecot-cvs mailing list