dovecot: Cleaned up keyword handling code.

dovecot at dovecot.org dovecot at dovecot.org
Sun Sep 2 04:52:01 EEST 2007


details:   http://hg.dovecot.org/dovecot/rev/75c814287334
changeset: 6349:75c814287334
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Sep 02 04:51:56 2007 +0300
description:
Cleaned up keyword handling code.

diffstat:

6 files changed, 62 insertions(+), 85 deletions(-)
src/lib-index/mail-index-map.c           |    8 ++
src/lib-index/mail-index-private.h       |    1 
src/lib-index/mail-index-sync-keywords.c |   98 ++++++++++++++----------------
src/lib-index/mail-index-sync-update.c   |    3 
src/lib-index/mail-index-view.c          |   35 ++--------
src/lib-index/mail-index.c               |    2 

diffs (291 lines):

diff -r ef1c7b2acc10 -r 75c814287334 src/lib-index/mail-index-map.c
--- a/src/lib-index/mail-index-map.c	Sun Sep 02 04:28:21 2007 +0300
+++ b/src/lib-index/mail-index-map.c	Sun Sep 02 04:51:56 2007 +0300
@@ -912,6 +912,14 @@ struct mail_index_map *mail_index_map_cl
 		}
 	}
 
+	/* copy keyword map */
+	if (array_is_created(&map->keyword_idx_map)) {
+		i_array_init(&mem_map->keyword_idx_map,
+			     array_count(&map->keyword_idx_map) + 4);
+		array_append_array(&mem_map->keyword_idx_map,
+				   &map->keyword_idx_map);
+	}
+
 	return mem_map;
 }
 
diff -r ef1c7b2acc10 -r 75c814287334 src/lib-index/mail-index-private.h
--- a/src/lib-index/mail-index-private.h	Sun Sep 02 04:28:21 2007 +0300
+++ b/src/lib-index/mail-index-private.h	Sun Sep 02 04:51:56 2007 +0300
@@ -139,7 +139,6 @@ struct mail_index_map {
 
 	struct mail_index_record_map *rec_map;
 
-	unsigned int keywords_read:1;
 	unsigned int write_base_header:1;
 	unsigned int write_ext_header:1;
 	unsigned int write_atomic:1; /* write to a new file and rename() */
diff -r ef1c7b2acc10 -r 75c814287334 src/lib-index/mail-index-sync-keywords.c
--- a/src/lib-index/mail-index-sync-keywords.c	Sun Sep 02 04:28:21 2007 +0300
+++ b/src/lib-index/mail-index-sync-keywords.c	Sun Sep 02 04:51:56 2007 +0300
@@ -7,7 +7,7 @@
 #include "mail-index-sync-private.h"
 #include "mail-transaction-log.h"
 
-static int
+static bool
 keyword_lookup(struct mail_index_sync_map_ctx *ctx,
 	       const char *keyword_name, unsigned int *idx_r)
 {
@@ -15,10 +15,6 @@ keyword_lookup(struct mail_index_sync_ma
 	const unsigned int *idx_map;
 	unsigned int i, count, keyword_idx;
 
-	if (!map->keywords_read) {
-		if (mail_index_map_parse_keywords(map) < 0)
-			return -1;
-	}
 	if (array_is_created(&map->keyword_idx_map) &&
 	    mail_index_keyword_lookup(ctx->view->index, keyword_name,
 				      &keyword_idx)) {
@@ -27,13 +23,11 @@ keyword_lookup(struct mail_index_sync_ma
 		for (i = 0; i < count; i++) {
 			if (idx_map[i] == keyword_idx) {
 				*idx_r = i;
-				return 1;
+				return TRUE;
 			}
 		}
 	}
-
-	*idx_r = (unsigned int)-1;
-	return 0;
+	return FALSE;
 }
 
 static buffer_t *
@@ -77,12 +71,14 @@ keywords_get_header_buf(struct mail_inde
 	return buf;
 }
 
-static int keywords_ext_register(struct mail_index_sync_map_ctx *ctx,
-				 uint32_t ext_map_idx, uint32_t reset_id,
-				 uint32_t hdr_size, uint32_t keywords_count)
+static void keywords_ext_register(struct mail_index_sync_map_ctx *ctx,
+				  uint32_t ext_map_idx, uint32_t reset_id,
+				  uint32_t hdr_size, uint32_t keywords_count)
 {
 	buffer_t *ext_intro_buf;
 	struct mail_transaction_ext_intro *u;
+
+	i_assert(keywords_count > 0);
 
 	ext_intro_buf =
 		buffer_create_static_hard(pool_datastack_create(),
@@ -105,10 +101,11 @@ static int keywords_ext_register(struct 
 		buffer_append(ext_intro_buf, "keywords", u->name_size);
 	}
 
-	return mail_index_sync_ext_intro(ctx, u);
-}
-
-static int
+	if (mail_index_sync_ext_intro(ctx, u) < 0)
+		i_panic("Keyword extension growing failed");
+}
+
+static void
 keywords_header_add(struct mail_index_sync_map_ctx *ctx,
 		    const char *keyword_name, unsigned int *keyword_idx_r)
 {
@@ -120,7 +117,6 @@ keywords_header_add(struct mail_index_sy
 	buffer_t *buf = NULL;
 	size_t keyword_len, rec_offset, name_offset, name_offset_root;
 	unsigned int keywords_count;
-	int ret;
 
 	/* if we crash in the middle of writing the header, the
 	   keywords are more or less corrupted. avoid that by
@@ -169,12 +165,9 @@ keywords_header_add(struct mail_index_sy
 	    (uint32_t)ext->record_size * CHAR_BIT < keywords_count) {
 		/* if we need to grow the buffer, add some padding */
 		buffer_append_zero(buf, 128);
-
-		ret = keywords_ext_register(ctx, ext_map_idx,
-					    ext == NULL ? 0 : ext->reset_id,
-					    buf->used, keywords_count);
-		if (ret <= 0)
-			return ret;
+		keywords_ext_register(ctx, ext_map_idx,
+				      ext == NULL ? 0 : ext->reset_id,
+				      buf->used, keywords_count);
 
 		/* map may have changed */
 		map = ctx->view->map;
@@ -186,13 +179,14 @@ keywords_header_add(struct mail_index_sy
 		i_assert(ext->hdr_size == buf->used);
 	}
 
-	buffer_copy(map->hdr_copy_buf, ext->hdr_offset,
-		    buf, 0, buf->used);
+	buffer_copy(map->hdr_copy_buf, ext->hdr_offset, buf, 0, buf->used);
 	map->hdr_base = map->hdr_copy_buf->data;
 
+	if (mail_index_map_parse_keywords(map) < 0)
+		i_panic("Keyword update corrupted keywords header");
+
 	*keyword_idx_r = keywords_count - 1;
-        map->keywords_read = FALSE;
-	return 1;
+	i_assert(*keyword_idx_r / CHAR_BIT < ext->record_size);
 }
 
 static int
@@ -249,6 +243,7 @@ int mail_index_sync_keywords(struct mail
 			     const struct mail_transaction_header *hdr,
 			     const struct mail_transaction_keyword_update *rec)
 {
+	struct mail_index_view *view = ctx->view;
 	const char *keyword_name;
 	const struct mail_index_ext *ext;
 	const uint32_t *uid, *end;
@@ -270,31 +265,30 @@ int mail_index_sync_keywords(struct mail
 					      "Trying to use empty keyword");
 		return -1;
 	}
-	if (keyword_lookup(ctx, keyword_name, &keyword_idx) < 0)
-		return -1;
-	if (keyword_idx == (unsigned int)-1) {
-		ret = keywords_header_add(ctx, keyword_name, &keyword_idx);
-		if (ret <= 0)
-			return ret;
-	}
-
-	if (!mail_index_map_lookup_ext(ctx->view->map, "keywords",
-				       &ext_map_idx))
-		ext = NULL;
-	else
-		ext = array_idx(&ctx->view->map->extensions, ext_map_idx);
-	if (ext == NULL || ext->record_size == 0) {
-		/* nothing to do */
-		if (rec->modify_type != MODIFY_REMOVE) {
-			mail_index_sync_set_corrupted(ctx,
-				"Keyword ext record missing for added keyword");
-		}
-		return 1;
-	}
-
-	if (!ctx->view->map->keywords_read) {
-		if (mail_index_map_parse_keywords(ctx->view->map) < 0)
-			return -1;
+	if (!keyword_lookup(ctx, keyword_name, &keyword_idx))
+		keywords_header_add(ctx, keyword_name, &keyword_idx);
+
+	/* if the keyword wasn't found, the "keywords" extension was created.
+	   if it was found, the record size should already be correct, but
+	   in case it isn't just fix it ourself. */
+	if (!mail_index_map_lookup_ext(view->map, "keywords", &ext_map_idx))
+		i_unreached();
+
+	ext = array_idx(&view->map->extensions, ext_map_idx);
+	if (keyword_idx / CHAR_BIT >= ext->record_size) {
+		if (rec->modify_type == MODIFY_REMOVE) {
+			/* nothing to do */
+			return 1;
+		}
+
+		/* grow the record size */
+		keywords_ext_register(ctx, ext_map_idx, ext->reset_id,
+				      ext->hdr_size,
+				      array_count(&view->map->keyword_idx_map));
+		if (!mail_index_map_lookup_ext(view->map, "keywords",
+					       &ext_map_idx))
+			i_unreached();
+		ext = array_idx(&view->map->extensions, ext_map_idx);
 	}
 
 	while (uid+2 <= end) {
diff -r ef1c7b2acc10 -r 75c814287334 src/lib-index/mail-index-sync-update.c
--- a/src/lib-index/mail-index-sync-update.c	Sun Sep 02 04:28:21 2007 +0300
+++ b/src/lib-index/mail-index-sync-update.c	Sun Sep 02 04:51:56 2007 +0300
@@ -610,9 +610,6 @@ void mail_index_sync_map_init(struct mai
 	sync_map_ctx->cur_ext_map_idx = (uint32_t)-1;
 	sync_map_ctx->type = type;
 
-	/* make sure we re-read it in case it has changed */
-	sync_map_ctx->view->map->keywords_read = FALSE;
-
 	mail_index_sync_init_handlers(sync_map_ctx);
 }
 
diff -r ef1c7b2acc10 -r 75c814287334 src/lib-index/mail-index-view.c
--- a/src/lib-index/mail-index-view.c	Sun Sep 02 04:28:21 2007 +0300
+++ b/src/lib-index/mail-index-view.c	Sun Sep 02 04:51:56 2007 +0300
@@ -460,20 +460,16 @@ void mail_index_lookup_keywords(struct m
 		/* no keywords at all in index */
 		return;
 	}
+        keyword_data = data;
 
 	(void)mail_index_ext_get_size(view, ext_id, map, NULL,
 				      &record_size, NULL);
 
 	/* keyword_idx_map[] contains file => index keyword mapping */
-	if (!array_is_created(&map->keyword_idx_map)) {
-		keyword_idx_map = NULL;
-		keyword_count = 0;
-	} else {
-		keyword_idx_map = array_get(&map->keyword_idx_map,
-					    &keyword_count);
-	}
-
-        keyword_data = data;
+	if (!array_is_created(&map->keyword_idx_map))
+		return;
+
+	keyword_idx_map = array_get(&map->keyword_idx_map, &keyword_count);
 	for (i = 0, idx = 0; i < record_size; i++) {
 		/* first do the quick check to see if there's keywords at all */
 		if (keyword_data[i] == 0)
@@ -485,24 +481,9 @@ void mail_index_lookup_keywords(struct m
 				continue;
 
 			if (idx >= keyword_count) {
-				/* keyword header was updated, parse it again
-				   it so we know what this keyword is called */
-				if (mail_index_map_parse_keywords(map) < 0)
-					return;
-
-				if (!array_is_created(&map->keyword_idx_map))
-					return;
-
-				/* pointer may have changed. update it. */
-				keyword_idx_map =
-					array_get(&map->keyword_idx_map,
-						  &keyword_count);
-
-				if (idx >= keyword_count) {
-					/* extra bits set in keyword bytes.
-					   shouldn't happen, but just ignore. */
-					break;
-				}
+				/* extra bits set in keyword bytes.
+				   shouldn't happen, but just ignore. */
+				break;
 			}
 
 			index_idx = keyword_idx_map[idx];
diff -r ef1c7b2acc10 -r 75c814287334 src/lib-index/mail-index.c
--- a/src/lib-index/mail-index.c	Sun Sep 02 04:28:21 2007 +0300
+++ b/src/lib-index/mail-index.c	Sun Sep 02 04:51:56 2007 +0300
@@ -224,8 +224,6 @@ int mail_index_map_parse_keywords(struct
 	unsigned int i, name_area_end_offset, old_count;
 	uint32_t idx;
 
-	map->keywords_read = TRUE;
-
 	if (!mail_index_map_lookup_ext(map, "keywords", &idx)) {
 		if (array_is_created(&map->keyword_idx_map))
 			array_clear(&map->keyword_idx_map);


More information about the dovecot-cvs mailing list