[dovecot-cvs] dovecot/src/lib-index mail-cache-lookup.c, 1.27, 1.28 mail-cache-private.h, 1.23, 1.24 mail-cache.c, 1.63, 1.64 mail-index-private.h, 1.50, 1.51 mail-index-sync-ext.c, 1.5, 1.6 mail-index-sync-keywords.c, 1.3, 1.4 mail-index-sync-private.h, 1.22, 1.23 mail-index-sync-update.c, 1.81, 1.82 mail-index-sync.c, 1.50, 1.51 mail-index-transaction-private.h, 1.22, 1.23 mail-index-transaction-view.c, 1.11, 1.12 mail-index-transaction.c, 1.53, 1.54 mail-index-view.c, 1.32, 1.33 mail-index.c, 1.191, 1.192 mail-transaction-log-append.c, 1.4, 1.5

cras at dovecot.org cras at dovecot.org
Sat Mar 12 20:16:32 EET 2005


Update of /var/lib/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv5803/lib-index

Modified Files:
	mail-cache-lookup.c mail-cache-private.h mail-cache.c 
	mail-index-private.h mail-index-sync-ext.c 
	mail-index-sync-keywords.c mail-index-sync-private.h 
	mail-index-sync-update.c mail-index-sync.c 
	mail-index-transaction-private.h mail-index-transaction-view.c 
	mail-index-transaction.c mail-index-view.c mail-index.c 
	mail-transaction-log-append.c 
Log Message:
Changed many buffers to arrays. Cleans up the code a lot.



Index: mail-cache-lookup.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache-lookup.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- mail-cache-lookup.c	29 Nov 2004 12:30:27 -0000	1.27
+++ mail-cache-lookup.c	12 Mar 2005 18:16:29 -0000	1.28
@@ -69,8 +69,7 @@
 		return 0;
 	}
 
-	ext = map->extensions->data;
-	ext += idx;
+	ext = array_idx(&map->extensions, idx);
 
 	for (i = 0; i < 2; i++) {
 		if (cache->hdr->file_seq == ext->reset_id) {
@@ -163,15 +162,13 @@
 	return 1;
 }
 
-static int buffer_find_offset(const buffer_t *buffer, uint32_t offset)
+static int find_offset(struct mail_cache_view *view, uint32_t offset)
 {
 	const uint32_t *offsets;
-	size_t i, size;
-
-	offsets = buffer_get_data(buffer, &size);
-	size /= sizeof(*offsets);
+	unsigned int i, count;
 
-	for (i = 0; i < size; i++) {
+	offsets = array_get(&view->tmp_offsets, &count);
+	for (i = 0; i < count; i++) {
 		if (offsets[i] == offset)
 			return TRUE;
 	}
@@ -199,14 +196,14 @@
 	}
 
 	ret = 1;
-	buffer_set_used_size(view->offsets_buf, 0);
+	array_clear(&view->tmp_offsets);
 	while (offset != 0 && ret > 0) {
-		if (buffer_find_offset(view->offsets_buf, offset)) {
+		if (find_offset(view, offset)) {
 			mail_cache_set_corrupted(view->cache,
 						 "record list is circular");
 			return -1;
 		}
-		buffer_append(view->offsets_buf, &offset, sizeof(offset));
+		array_append(&view->tmp_offsets, &offset, 1);
 		ret = mail_cache_foreach_rec(view, &offset,
 					     callback, context);
 	}
@@ -214,15 +211,14 @@
 	if (ret > 0 && view->trans_seq1 <= seq && view->trans_seq2 >= seq &&
 	    mail_cache_lookup_offset(view->cache, view->trans_view,
 				     seq, &offset)) {
-		buffer_set_used_size(view->offsets_buf, 0);
+		array_clear(&view->tmp_offsets);
 		while (offset != 0 && ret > 0) {
-			if (buffer_find_offset(view->offsets_buf, offset)) {
+			if (find_offset(view, offset)) {
 				mail_cache_set_corrupted(view->cache,
 					"record list is circular");
 				return -1;
 			}
-			buffer_append(view->offsets_buf,
-				      &offset, sizeof(offset));
+			array_append(&view->tmp_offsets, &offset, 1);
 			ret = mail_cache_foreach_rec(view, &offset,
 						     callback, context);
 		}

Index: mail-cache-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache-private.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- mail-cache-private.h	16 Jan 2005 19:18:24 -0000	1.23
+++ mail-cache-private.h	12 Mar 2005 18:16:29 -0000	1.24
@@ -155,7 +155,8 @@
 	struct mail_cache_transaction_ctx *transaction;
 	uint32_t trans_seq1, trans_seq2;
 
-	buffer_t *offsets_buf; /* temporary buffer, just to avoid mallocs */
+	/* temporary array, just to avoid mallocs. */
+	array_t ARRAY_DEFINE(tmp_offsets, uint32_t);
 
 	/* if cached_exists_buf[field] == cached_exists_value, it's cached.
 	   this allows us to avoid constantly clearing the whole buffer.

Index: mail-cache.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache.c,v
retrieving revision 1.63
retrieving revision 1.64
diff -u -d -r1.63 -r1.64
--- mail-cache.c	31 Jan 2005 18:03:43 -0000	1.63
+++ mail-cache.c	12 Mar 2005 18:16:29 -0000	1.64
@@ -459,7 +459,7 @@
 	view = i_new(struct mail_cache_view, 1);
 	view->cache = cache;
 	view->view = iview;
-	view->offsets_buf = buffer_create_dynamic(default_pool, 128);
+	ARRAY_CREATE(&view->tmp_offsets, default_pool, uint32_t, 32);
 	view->cached_exists_buf =
 		buffer_create_dynamic(default_pool,
 				      cache->file_fields_count + 10);
@@ -474,7 +474,7 @@
 	if (view->trans_view != NULL)
 		mail_index_view_close(view->trans_view);
 
-	buffer_free(view->offsets_buf);
+	array_free(&view->tmp_offsets);
 	buffer_free(view->cached_exists_buf);
 	i_free(view);
 }

Index: mail-index-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-private.h,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -d -r1.50 -r1.51
--- mail-index-private.h	5 Mar 2005 19:19:24 -0000	1.50
+++ mail-index-private.h	12 Mar 2005 18:16:29 -0000	1.51
@@ -87,8 +87,8 @@
 	unsigned int records_count;
 
 	pool_t extension_pool;
-	buffer_t *extensions; /* struct mail_index_ext[] */
-	buffer_t *ext_id_map; /* uint32_t[] (index -> file) */
+	array_t ARRAY_DEFINE(extensions, struct mail_index_ext);
+	array_t ARRAY_DEFINE(ext_id_map, uint32_t); /* index -> file */
 
 	void *mmap_base;
 	size_t mmap_size, mmap_used_size;
@@ -113,11 +113,12 @@
 	gid_t gid;
 
 	pool_t extension_pool;
-	buffer_t *extensions; /* struct mail_index_ext[] */
+	array_t ARRAY_DEFINE(extensions, struct mail_index_ext);
 
-	buffer_t *expunge_handlers; /* mail_index_expunge_handler_t*[] */
-	buffer_t *sync_handlers; /* mail_index_sync_handler_t*[] */
-	buffer_t *sync_lost_handlers; /* mail_index_sync_lost_handler_t*[] */
+	array_t ARRAY_DEFINE(expunge_handlers, mail_index_expunge_handler_t *);
+	array_t ARRAY_DEFINE(sync_handlers, struct mail_index_sync_handler);
+	array_t ARRAY_DEFINE(sync_lost_handlers,
+			     mail_index_sync_lost_handler_t *);
 
 	char *filepath;
 	int fd;

Index: mail-index-sync-ext.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync-ext.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- mail-index-sync-ext.c	26 Jan 2005 18:58:49 -0000	1.5
+++ mail-index-sync-ext.c	12 Mar 2005 18:16:29 -0000	1.6
@@ -10,46 +10,48 @@
 
 void mail_index_sync_init_expunge_handlers(struct mail_index_sync_map_ctx *ctx)
 {
-	const mail_index_expunge_handler_t *const *handlers;
+	mail_index_expunge_handler_t *const *handlers;
         const struct mail_index_ext *extensions;
 	const uint32_t *id_map;
+	void **contexts;
 	struct mail_index_expunge_handler eh;
-	size_t handlers_count, id_map_size, size;
+	unsigned int count, ext_count, id_map_count;
+	unsigned int handlers_count, context_count;
 	uint32_t idx_ext_id, map_ext_id;
 
-	if (ctx->view->map->extensions == NULL)
+	if (!array_is_created(&ctx->view->map->extensions))
 		return;
 
-	handlers = buffer_get_data(ctx->view->index->expunge_handlers,
-				   &handlers_count);
-	handlers_count /= sizeof(*handlers);
+	handlers = array_get(&ctx->view->index->expunge_handlers,
+			     &handlers_count);
 
 	if (handlers_count == 0)
 		return;
 
 	/* set expunge handlers */
 	memset(&eh, 0, sizeof(eh));
-	if (ctx->expunge_handlers != NULL)
-		buffer_set_used_size(ctx->expunge_handlers, 0);
+	if (array_is_created(&ctx->expunge_handlers))
+		array_clear(&ctx->expunge_handlers);
 	else {
-		ctx->expunge_handlers =
-			buffer_create_dynamic(default_pool, 256);
+		ARRAY_CREATE(&ctx->expunge_handlers, default_pool,
+			     struct mail_index_expunge_handler, 64);
 	}
 
-	extensions = ctx->view->map->extensions->data;
-	id_map = buffer_get_data(ctx->view->map->ext_id_map, &id_map_size);
-	id_map_size /= sizeof(*id_map);
+	extensions = array_get(&ctx->view->map->extensions, &ext_count);
+	id_map = array_get(&ctx->view->map->ext_id_map, &id_map_count);
+	contexts = array_get_modifyable(&ctx->extra_contexts, &context_count);
 
-	size = I_MIN(handlers_count, id_map_size);
-	for (idx_ext_id = 0; idx_ext_id < size; idx_ext_id++) {
+	count = I_MIN(handlers_count, id_map_count);
+	for (idx_ext_id = 0; idx_ext_id < count; idx_ext_id++) {
 		map_ext_id = id_map[idx_ext_id];
 		if (handlers[idx_ext_id] == NULL || map_ext_id == (uint32_t)-1)
 			continue;
 
+		i_assert(map_ext_id < context_count);
 		eh.handler = handlers[idx_ext_id];
-		eh.context = &ctx->extra_context[map_ext_id];
+		eh.context = &contexts[map_ext_id];
 		eh.record_offset = extensions[map_ext_id].record_offset;
-		buffer_append(ctx->expunge_handlers, &eh, sizeof(eh));
+		array_append(&ctx->expunge_handlers, &eh, 1);
 	}
 	ctx->expunge_handlers_set = TRUE;
 	ctx->expunge_handlers_used = TRUE;
@@ -59,42 +61,40 @@
 mail_index_sync_deinit_expunge_handlers(struct mail_index_sync_map_ctx *ctx)
 {
 	const struct mail_index_expunge_handler *eh;
-	size_t i, size;
+	unsigned int i, count;
 
-	if (ctx->expunge_handlers == NULL)
+	if (!array_is_created(&ctx->expunge_handlers))
 		return;
 
-	eh = buffer_get_data(ctx->expunge_handlers, &size);
-	size /= sizeof(*eh);
-
-	for (i = 0; i < size; i++) {
+	eh = array_get(&ctx->expunge_handlers, &count);
+	for (i = 0; i < count; i++) {
 		if (eh->context != NULL)
 			eh[i].handler(ctx, 0, NULL, eh->context);
 	}
 
-	buffer_free(ctx->expunge_handlers);
+	array_free(&ctx->expunge_handlers);
 }
 
 void mail_index_sync_init_handlers(struct mail_index_sync_map_ctx *ctx)
 {
-	size_t size;
+	unsigned int count;
 
-	if (ctx->view->map->extensions == NULL)
+	if (!array_is_created(&ctx->view->map->extensions))
 		return;
 
 	/* set space for extra contexts */
-	size = sizeof(void *) * (ctx->view->index->extensions->used /
-				 sizeof(struct mail_index_ext));
-	if (ctx->extra_context_buf == NULL) {
-		ctx->extra_context_buf =
-			buffer_create_dynamic(default_pool, size);
-	} else {
-		buffer_set_used_size(ctx->extra_context_buf, 0);
+	count = array_count(&ctx->view->index->extensions);
+	i_assert(count > 0);
+
+	if (array_is_created(&ctx->extra_contexts))
+		array_clear(&ctx->extra_contexts);
+	else {
+		ARRAY_CREATE(&ctx->extra_contexts, default_pool,
+			     void *, count);
 	}
-	buffer_append_zero(ctx->extra_context_buf, size);
-	ctx->extra_context =
-		buffer_get_modifyable_data(ctx->extra_context_buf, NULL);
 
+	/* fill the context array with NULLs */
+	(void)array_modifyable_idx(&ctx->extra_contexts, count - 1);
 	ctx->expunge_handlers_set = FALSE;
 }
 
@@ -102,32 +102,33 @@
 {
 	const struct mail_index_sync_handler *sync_handlers;
 	const struct mail_index_ext *ext;
-	size_t i, synch_size, size;
+	void **extra_contexts;
+	unsigned int i, count, synch_count, context_count;
 
-	if (ctx->extra_context == NULL)
+	if (!array_is_created(&ctx->extra_contexts))
 		return;
 
-	sync_handlers = buffer_get_data(ctx->view->index->sync_handlers,
-					&synch_size);
-	synch_size /= sizeof(*sync_handlers);
-
-	i_assert(synch_size <= ctx->extra_context_buf->used / sizeof(void *));
+	sync_handlers =
+		array_get(&ctx->view->index->sync_handlers, &synch_count);
 
-	ext = buffer_get_data(ctx->view->map->extensions, &size);
-	size /= sizeof(*ext);
-	i_assert(size <= synch_size);
+	ext = array_get(&ctx->view->map->extensions, &count);
+	i_assert(count <= synch_count);
 
 	/* sync_handlers[] is ordered by index->extensions while
-	   extra_context is ordered by map->extensions. */
-	for (i = 0; i < size; i++) {
-		if (ctx->extra_context[i] != NULL) {
+	   extra_contexts[] is ordered by map->extensions. */
+	extra_contexts =
+		array_get_modifyable(&ctx->extra_contexts, &context_count);
+	i_assert(count <= context_count);
+
+	for (i = 0; i < count; i++) {
+		if (extra_contexts[i] != NULL) {
 			sync_handlers[ext[i].index_idx].
 				callback(ctx, 0, NULL, NULL,
-					 &ctx->extra_context[i]);
+					 &extra_contexts[i]);
 		}
 	}
 
-	buffer_free(ctx->extra_context_buf);
+	array_free(&ctx->extra_contexts);
 }
 
 static struct mail_index_ext_header *
@@ -164,22 +165,21 @@
 	struct mail_index_ext_header *ext_hdr;
 	uint16_t *old_offsets, min_align;
 	uint32_t offset, old_records_count, rec_idx;
+	unsigned int i, count;
 	const void *src;
-	size_t i, size;
 
 	t_push();
-	ext = buffer_get_modifyable_data(map->extensions, &size);
-	size /= sizeof(*ext);
+	ext = array_get_modifyable(&map->extensions, &count);
 
 	/* @UNSAFE */
-	old_offsets = t_new(uint16_t, size);
-	sorted = t_new(struct mail_index_ext *, size);
-	for (i = 0; i < size; i++) {
+	old_offsets = t_new(uint16_t, count);
+	sorted = t_new(struct mail_index_ext *, count);
+	for (i = 0; i < count; i++) {
 		old_offsets[i] = ext[i].record_offset;
 		ext[i].record_offset = 0;
 		sorted[i] = &ext[i];
 	}
-	qsort(sorted, size, sizeof(struct mail_index_ext *),
+	qsort(sorted, count, sizeof(struct mail_index_ext *),
 	      mail_index_ext_align_cmp);
 
 	/* we simply try to use the extensions with largest alignment
@@ -188,7 +188,7 @@
 	offset = sizeof(struct mail_index_record);
 	for (;;) {
 		min_align = (uint16_t)-1;
-		for (i = 0; i < size; i++) {
+		for (i = 0; i < count; i++) {
 			if (sorted[i]->record_offset == 0) {
 				if ((offset % sorted[i]->record_align) == 0)
 					break;
@@ -196,7 +196,7 @@
 					min_align = sorted[i]->record_align;
 			}
 		}
-		if (i == size) {
+		if (i == count) {
 			if (min_align == (uint16_t)-1) {
 				/* all done */
 				break;
@@ -234,7 +234,7 @@
 	for (rec_idx = 0; rec_idx < old_records_count; rec_idx++) {
 		buffer_write(new_map->buffer, offset, src,
 			     sizeof(struct mail_index_record));
-		for (i = 0; i < size; i++) {
+		for (i = 0; i < count; i++) {
 			buffer_write(new_map->buffer,
 				     offset + ext[i].record_offset,
 				     CONST_PTR_OFFSET(src, old_offsets[i]),
@@ -259,7 +259,7 @@
 	i_assert(new_map->records_count == new_map->hdr.messages_count);
 
 	/* update record offsets in headers */
-	for (i = 0; i < size; i++) {
+	for (i = 0; i < count; i++) {
                 ext_hdr = get_ext_header(new_map, &ext[i]);
 		ext_hdr->record_offset = ext[i].record_offset;
 	}
@@ -278,8 +278,7 @@
 	uint32_t old_size, new_size, old_record_size;
 	int modified = FALSE;
 
-	ext = buffer_get_modifyable_data(map->extensions, NULL);
-	ext += ext_id;
+	ext = array_modifyable_idx(&map->extensions, ext_id);
 
 	old_size = MAIL_INDEX_HEADER_SIZE_ALIGN(ext->hdr_size);
 	new_size = MAIL_INDEX_HEADER_SIZE_ALIGN(u->hdr_size);
@@ -320,7 +319,7 @@
 
 	if (new_size != old_size) {
 		/* move all hdr_offset of all extensions after this one */
-		size_t i, count = map->extensions->used / sizeof(*ext);
+		unsigned i, count = array_count(&map->extensions);
 
 		ext -= ext_id;
 		for (i = ext_id + 1; i < count; i++) {
@@ -347,8 +346,8 @@
 	uint32_t ext_id, hdr_offset;
 
 	if (u->ext_id != (uint32_t)-1 &&
-	    (map->extensions == NULL ||
-	     u->ext_id >= map->extensions->used / sizeof(*ext))) {
+	    (!array_is_created(&map->extensions) ||
+	     u->ext_id >= array_count(&map->extensions))) {
 		mail_transaction_log_view_set_corrupted(ctx->view->log_view,
 			"Extension introduction for unknown id %u", u->ext_id);
 		return -1;
@@ -371,8 +370,7 @@
 
 	if (ext_id != (uint32_t)-1) {
 		/* exists already */
-		ext = map->extensions->data;
-		ext += ext_id;
+		ext = array_idx(&map->extensions, ext_id);
 
 		if (u->reset_id == ext->reset_id) {
 			/* check if we need to resize anything */
@@ -406,8 +404,7 @@
 					     u->record_size, u->record_align,
 					     u->reset_id);
 
-	ext = map->extensions->data;
-	ext += ext_id;
+	ext = array_idx(&map->extensions, ext_id);
 
 	/* <ext_hdr> <name> [padding] [header data] */
 	memset(&ext_hdr, 0, sizeof(ext_hdr));
@@ -460,8 +457,7 @@
 	if (ctx->cur_ext_ignore)
 		return 1;
 
-	ext = buffer_get_modifyable_data(map->extensions, NULL);
-	ext += ctx->cur_ext_id;
+	ext = array_modifyable_idx(&map->extensions, ctx->cur_ext_id);
 	ext->reset_id = u->new_reset_id;
 
 	memset(buffer_get_space_unsafe(map->hdr_copy_buf, ext->hdr_offset,
@@ -495,9 +491,7 @@
 	if (ctx->cur_ext_ignore)
 		return 1;
 
-	ext = map->extensions->data;
-	ext += ctx->cur_ext_id;
-
+	ext = array_idx(&map->extensions, ctx->cur_ext_id);
 	buffer_write(map->hdr_copy_buf, ext->hdr_offset + u->offset,
 		     u + 1, u->size);
 	map->hdr_base = map->hdr_copy_buf->data;
@@ -525,19 +519,20 @@
 	if (seq == 0)
 		return 1;
 
-	ext = view->map->extensions->data;
-	ext += ctx->cur_ext_id;
+	ext = array_idx(&view->map->extensions, ctx->cur_ext_id);
 
 	rec = MAIL_INDEX_MAP_IDX(view->map, seq-1);
 	old_data = PTR_OFFSET(rec, ext->record_offset);
 
-	sync_handlers = view->index->sync_handlers->data;
-	sync_handlers += ext->index_idx;
+	sync_handlers = array_idx(&view->index->sync_handlers, ext->index_idx);
 
 	/* call sync handlers only when we're syncing index (not view) */
 	if ((sync_handlers->type & ctx->type) != 0) {
+		void **extra_context =
+			array_modifyable_idx(&ctx->extra_contexts,
+					     ctx->cur_ext_id);
 		ret = sync_handlers->callback(ctx, seq, old_data, u + 1,
-					&ctx->extra_context[ctx->cur_ext_id]);
+					      extra_context);
 		if (ret <= 0)
 			return ret;
 	}

Index: mail-index-sync-keywords.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync-keywords.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- mail-index-sync-keywords.c	5 Feb 2005 12:01:49 -0000	1.3
+++ mail-index-sync-keywords.c	12 Mar 2005 18:16:29 -0000	1.4
@@ -117,9 +117,7 @@
 	ext_id = mail_index_map_lookup_ext(map, "keywords");
 	if (ext_id != (uint32_t)-1) {
 		/* update existing header */
-		ext = map->extensions->data;
-		ext += ext_id;
-
+		ext = array_idx(&map->extensions, ext_id);
 		buf = keywords_get_header_buf(map, ext, 1, &keywords_count,
 					      &rec_offset, &name_offset_root,
 					      &name_offset);
@@ -171,8 +169,7 @@
 			ext_id = mail_index_map_lookup_ext(map, "keywords");
 			i_assert(ext_id != (uint32_t)-1);
 		}
-		ext = map->extensions->data;
-		ext += ext_id;
+		ext = array_idx(&map->extensions, ext_id);
 
 		i_assert(ext->hdr_size == buf->used);
 	}
@@ -280,9 +277,7 @@
 		return 1;
 	}
 
-	ext = ctx->view->map->extensions->data;
-	ext += ext_id;
-
+	ext = array_idx(&ctx->view->map->extensions, ext_id);
 	if (ext->record_size == 0) {
 		/* nothing to do */
 		i_assert(rec->modify_type == MODIFY_REMOVE);
@@ -334,9 +329,7 @@
 		return 1;
 	}
 
-	ext = map->extensions->data;
-	ext += ext_id;
-
+	ext = array_idx(&map->extensions, ext_id);
 	end = CONST_PTR_OFFSET(r, hdr->size);
 	for (; r != end; r++) {
 		if (mail_index_lookup_uid_range(ctx->view, r->uid1, r->uid2,

Index: mail-index-sync-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync-private.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- mail-index-sync-private.h	5 Feb 2005 12:01:49 -0000	1.22
+++ mail-index-sync-private.h	12 Mar 2005 18:16:29 -0000	1.23
@@ -10,7 +10,7 @@
 
 	const struct mail_transaction_expunge *expunges;
 	const struct mail_transaction_flag_update *updates;
-	size_t expunges_count, updates_count;
+	unsigned int expunges_count, updates_count;
 
 	uint32_t append_uid_first, append_uid_last;
 
@@ -37,10 +37,10 @@
 	struct mail_index_view *view;
 	uint32_t cur_ext_id;
 
-	buffer_t *expunge_handlers; /* struct mail_index_expunge_handler[] */
+	array_t ARRAY_DEFINE(expunge_handlers,
+			     struct mail_index_expunge_handler);
 
-	buffer_t *extra_context_buf;
-	void **extra_context;
+	array_t ARRAY_DEFINE(extra_contexts, void *);
 
         enum mail_index_sync_handler_type type;
 

Index: mail-index-sync-update.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync-update.c,v
retrieving revision 1.81
retrieving revision 1.82
diff -u -d -r1.81 -r1.82
--- mail-index-sync-update.c	5 Mar 2005 19:11:19 -0000	1.81
+++ mail-index-sync-update.c	12 Mar 2005 18:16:29 -0000	1.82
@@ -80,8 +80,8 @@
 	struct mail_index_map *map = view->map;
 	struct mail_index_record *rec;
 	uint32_t count, seq, seq1, seq2;
-        struct mail_index_expunge_handler *expunge_handlers, *eh;
-	size_t i, expunge_handlers_count;
+        const struct mail_index_expunge_handler *expunge_handlers, *eh;
+	unsigned int i, expunge_handlers_count;
 
 	if (e->uid1 > e->uid2 || e->uid1 == 0) {
 		mail_transaction_log_view_set_corrupted(ctx->view->log_view,
@@ -114,11 +114,9 @@
 		mail_index_sync_init_expunge_handlers(ctx);
 
 	if (ctx->type != MAIL_INDEX_SYNC_HANDLER_VIEW &&
-	    ctx->expunge_handlers != NULL) {
-		expunge_handlers =
-			buffer_get_modifyable_data(ctx->expunge_handlers,
-						   &expunge_handlers_count);
-		expunge_handlers_count /= sizeof(*expunge_handlers);
+	    array_is_created(&ctx->expunge_handlers)) {
+		expunge_handlers = array_get(&ctx->expunge_handlers,
+					     &expunge_handlers_count);
 	} else {
 		expunge_handlers = NULL;
 		expunge_handlers_count = 0;
@@ -479,8 +477,8 @@
 			break;
 		}
 
-		ext = ctx->view->map->extensions->data;
-		record_size = sizeof(*rec) + ext[ctx->cur_ext_id].record_size;
+		ext = array_idx(&ctx->view->map->extensions, ctx->cur_ext_id);
+		record_size = sizeof(*rec) + ext->record_size;
 
 		rec = data;
 		end = CONST_PTR_OFFSET(data, hdr->size);

Index: mail-index-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -d -r1.50 -r1.51
--- mail-index-sync.c	8 Feb 2005 23:02:42 -0000	1.50
+++ mail-index-sync.c	12 Mar 2005 18:16:29 -0000	1.51
@@ -181,7 +181,6 @@
 mail_index_sync_read_and_sort(struct mail_index_sync_ctx *ctx,
 			      int *seen_external_r)
 {
-	size_t size;
 	int ret;
 
 	*seen_external_r = FALSE;
@@ -207,17 +206,17 @@
 			mail_index_sync_add_transaction(ctx);
 	}
 
-	if (ctx->trans->expunges == NULL)
+	if (!array_is_created(&ctx->trans->expunges))
 		ctx->expunges_count = 0;
 	else {
-		ctx->expunges = buffer_get_data(ctx->trans->expunges, &size);
-		ctx->expunges_count = size / sizeof(*ctx->expunges);
+		ctx->expunges = array_get(&ctx->trans->expunges,
+					  &ctx->expunges_count);
 	}
-	if (ctx->trans->updates == NULL)
+	if (!array_is_created(&ctx->trans->updates))
 		ctx->updates_count = 0;
 	else {
-		ctx->updates = buffer_get_data(ctx->trans->updates, &size);
-		ctx->updates_count = size / sizeof(*ctx->updates);
+		ctx->updates = array_get(&ctx->trans->updates,
+					 &ctx->updates_count);
 	}
 	return ret;
 }

Index: mail-index-transaction-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-transaction-private.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- mail-index-transaction-private.h	5 Feb 2005 12:01:49 -0000	1.22
+++ mail-index-transaction-private.h	12 Mar 2005 18:16:29 -0000	1.23
@@ -7,23 +7,22 @@
 	int refcount;
 	struct mail_index_view *view;
 
-        buffer_t *appends;
+        array_t ARRAY_DEFINE(appends, struct mail_index_record);
 	uint32_t first_new_seq, last_new_seq;
 
-	buffer_t *expunges;
-
-	buffer_t *updates;
+	array_t ARRAY_DEFINE(expunges, struct mail_transaction_expunge);
+	array_t ARRAY_DEFINE(updates, struct mail_transaction_flag_update);
 	size_t last_update_idx;
 
 	unsigned char hdr_change[sizeof(struct mail_index_header)];
 	unsigned char hdr_mask[sizeof(struct mail_index_header)];
 
-	buffer_t *ext_rec_updates; /* buffer_t*[] */
-	buffer_t *ext_resizes; /* struct mail_transaction_ext_intro[] */
-	buffer_t *ext_resets; /* uint32_t[] */
+	array_t ARRAY_DEFINE(ext_rec_updates, array_t);
+	array_t ARRAY_DEFINE(ext_resizes, struct mail_transaction_ext_intro);
+	array_t ARRAY_DEFINE(ext_resets, uint32_t);
 
-	buffer_t *keyword_updates; /* buffer_t*[] */
-	buffer_t *keyword_resets; /* buffer_t*[] */
+	array_t ARRAY_DEFINE(keyword_updates, array_t);
+	array_t ARRAY_DEFINE(keyword_resets, struct seq_range);
 
         struct mail_cache_transaction_ctx *cache_trans_ctx;
 
@@ -40,7 +39,7 @@
 void mail_index_transaction_ref(struct mail_index_transaction *t);
 void mail_index_transaction_unref(struct mail_index_transaction *t);
 
-int mail_index_seq_buffer_lookup(buffer_t *buffer, uint32_t seq,
-				 size_t record_size, size_t *pos_r);
+int mail_index_seq_array_lookup(const array_t *buffer, uint32_t seq,
+				unsigned int *idx_r);
 
 #endif

Index: mail-index-transaction-view.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-transaction-view.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- mail-index-transaction-view.c	29 Nov 2004 17:22:40 -0000	1.11
+++ mail-index-transaction-view.c	12 Mar 2005 18:16:29 -0000	1.12
@@ -104,6 +104,7 @@
 	struct mail_index_view_transaction *tview =
 		(struct mail_index_view_transaction *)view;
 	const struct mail_index_record *rec;
+	unsigned int append_count;
 	uint32_t seq, message_count;
 
 	if (tview->parent->lookup_first(view, flags, flags_mask, seq_r) < 0)
@@ -112,9 +113,11 @@
 	if (*seq_r != 0)
 		return 0;
 
-	rec = buffer_get_data(tview->t->appends, NULL);
+	rec = array_get(&tview->t->appends, &append_count);
 	seq = tview->t->first_new_seq;
 	message_count = tview->t->last_new_seq;
+	i_assert(append_count == message_count - seq + 1);
+
 	for (; seq <= message_count; seq++, rec++) {
 		if ((rec->flags & flags_mask) == (uint8_t)flags) {
 			*seq_r = seq;
@@ -133,37 +136,36 @@
 	struct mail_index_view_transaction *tview =
 		(struct mail_index_view_transaction *)view;
         const struct mail_index_ext *ext;
-	buffer_t *const *ext_bufs;
-	size_t size, pos;
-
-	i_assert(ext_id < view->index->extensions->used / sizeof(*ext));
-
-	ext = view->index->extensions->data;
-	ext += ext_id;
+	const array_t *ext_buf;
+	ARRAY_ARG_SET_TYPE(ext_buf, void *);
+	const void *data;
+	unsigned int idx;
 
-	if (tview->t->ext_rec_updates == NULL) {
-		ext_bufs = NULL;
-		size = 0;
-	} else {
-		ext_bufs = buffer_get_data(tview->t->ext_rec_updates, &size);
-		size /= sizeof(*ext_bufs);
-	}
+	i_assert(ext_id < array_count(&view->index->extensions));
 
 	*map_r = view->index->map;
-	if (size <= ext_id || ext_bufs[ext_id] == NULL ||
-	    !mail_index_seq_buffer_lookup(ext_bufs[ext_id], seq,
-					  ext->record_size, &pos)) {
-		/* not updated, return the existing value */
-		if (seq < tview->t->first_new_seq) {
-			return tview->parent->lookup_ext_full(view, seq, ext_id,
-							      map_r, data_r);
+
+	ext = array_idx(&view->index->extensions, ext_id);
+	if (array_is_created(&tview->t->ext_rec_updates) &&
+	    ext_id < array_count(&tview->t->ext_rec_updates)) {
+		/* there are some ext updates in transaction.
+		   see if there's any for this sequence. */
+		ext_buf = array_idx(&tview->t->ext_rec_updates, ext_id);
+		if (array_is_created(ext_buf) &&
+		    mail_index_seq_array_lookup(ext_buf, seq, &idx)) {
+			data = array_idx(ext_buf, idx);
+			*data_r = CONST_PTR_OFFSET(data, sizeof(uint32_t));
+			return 1;
 		}
+	}
 
-		*data_r = NULL;
-		return 1;
+	/* not updated, return the existing value */
+	if (seq < tview->t->first_new_seq) {
+		return tview->parent->lookup_ext_full(view, seq, ext_id,
+						      map_r, data_r);
 	}
 
-	*data_r = CONST_PTR_OFFSET(ext_bufs[ext_id]->data, pos + sizeof(seq));
+	*data_r = NULL;
 	return 1;
 }
 

Index: mail-index-transaction.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-transaction.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -d -r1.53 -r1.54
--- mail-index-transaction.c	8 Feb 2005 22:58:42 -0000	1.53
+++ mail-index-transaction.c	12 Mar 2005 18:16:29 -0000	1.54
@@ -42,45 +42,41 @@
 
 static void mail_index_transaction_free(struct mail_index_transaction *t)
 {
-	buffer_t **recs;
-	size_t i, size;
+	array_t *recs;
+	unsigned i, count;
 
-	if (t->ext_rec_updates != NULL) {
-		recs = buffer_get_modifyable_data(t->ext_rec_updates, &size);
-		size /= sizeof(*recs);
+	if (array_is_created(&t->ext_rec_updates)) {
+		recs = array_get_modifyable(&t->ext_rec_updates, &count);
 
-		for (i = 0; i < size; i++) {
-			if (recs[i] != NULL)
-				buffer_free(recs[i]);
+		for (i = 0; i < count; i++) {
+			if (array_is_created(&recs[i]))
+				array_free(&recs[i]);
 		}
-		buffer_free(t->ext_rec_updates);
+		array_free(&t->ext_rec_updates);
 	}
 
-	if (t->keyword_updates != NULL) {
-		buffer_t **buf;
-
-		buf = buffer_get_modifyable_data(t->keyword_updates, &size);
-		size /= sizeof(*buf);
+	if (array_is_created(&t->keyword_updates)) {
+		recs = array_get_modifyable(&t->keyword_updates, &count);
 
-		for (i = 0; i < size; i++) {
-			if (buf[i] != NULL)
-				buffer_free(buf[i]);
+		for (i = 0; i < count; i++) {
+			if (array_is_created(&recs[i]))
+				array_free(&recs[i]);
 		}
-		buffer_free(t->keyword_updates);
+		array_free(&t->keyword_updates);
 	}
-	if (t->keyword_resets != NULL)
-		buffer_free(t->keyword_resets);
+	if (array_is_created(&t->keyword_resets))
+		array_free(&t->keyword_resets);
 
-	if (t->appends != NULL)
-		buffer_free(t->appends);
-	if (t->expunges != NULL)
-		buffer_free(t->expunges);
-	if (t->updates != NULL)
-		buffer_free(t->updates);
-	if (t->ext_resizes != NULL)
-		buffer_free(t->ext_resizes);
-	if (t->ext_resets != NULL)
-		buffer_free(t->ext_resets);
+	if (array_is_created(&t->appends))
+		array_free(&t->appends);
+	if (array_is_created(&t->expunges))
+		array_free(&t->expunges);
+	if (array_is_created(&t->updates))
+		array_free(&t->updates);
+	if (array_is_created(&t->ext_resizes))
+		array_free(&t->ext_resizes);
+	if (array_is_created(&t->ext_resets))
+		array_free(&t->ext_resets);
 
 	mail_index_view_transaction_unref(t->view);
 	mail_index_view_close(t->view);
@@ -100,22 +96,21 @@
 
 static void
 mail_index_buffer_convert_to_uids(struct mail_index_transaction *t,
-				  buffer_t *buf, size_t record_size, int range)
+				  array_t *array, int range)
 {
+        ARRAY_ARG_SET_TYPE(array, uint32_t);
         struct mail_index_view *view = t->view;
 	const struct mail_index_record *rec;
-	unsigned char *data;
-	size_t size, i;
 	uint32_t *seq;
+	unsigned int i, count;
 	int j;
 
-	if (buf == NULL)
+	if (!array_is_created(array))
 		return;
 
-	/* @UNSAFE */
-	data = buffer_get_modifyable_data(buf, &size);
-	for (i = 0; i < size; i += record_size) {
-		seq = (uint32_t *)&data[i];
+	count = array_count(array);
+	for (i = 0; i < count; i++) {
+		seq = array_modifyable_idx(array, i);
 
 		for (j = 0; j <= range; j++, seq++) {
 			if (*seq >= t->first_new_seq) {
@@ -131,51 +126,36 @@
 	}
 }
 
-static int
-mail_index_transaction_convert_to_uids(struct mail_index_transaction *t)
+static void arrays_convert_to_uids(struct mail_index_transaction *t,
+				   array_t *array)
 {
-	struct mail_index *index = t->view->index;
-        const struct mail_index_ext *extensions;
-	buffer_t **updates;
-	size_t i, size;
-
-	if (mail_index_view_lock(t->view) < 0)
-		return -1;
-
-	if (t->ext_rec_updates != NULL) {
-		extensions = buffer_get_data(index->extensions, NULL);
-		updates = buffer_get_modifyable_data(t->ext_rec_updates, &size);
-		size /= sizeof(*updates);
+	ARRAY_ARG_SET_TYPE(array, array_t);
+	array_t *updates;
+	unsigned int i, count;
 
-		for (i = 0; i < size; i++) {
-			if (updates[i] == NULL)
-				continue;
+	if (!array_is_created(array))
+		return;
 
-			mail_index_buffer_convert_to_uids(t, updates[i],
-				sizeof(uint32_t) + extensions[i].record_size,
-				FALSE);
+	updates = array_get_modifyable(array, &count);
+	for (i = 0; i < count; i++) {
+		if (array_is_created(&updates[i])) {
+			mail_index_buffer_convert_to_uids(t, &updates[i],
+							  FALSE);
 		}
 	}
+}
 
-	if (t->keyword_updates != NULL) {
-		buffer_t **buf;
-
-		buf = buffer_get_modifyable_data(t->keyword_updates, &size);
-		size /= sizeof(*buf);
-
-		for (i = 0; i < size; i++) {
-			if (buf[i] == NULL)
-				continue;
+static int
+mail_index_transaction_convert_to_uids(struct mail_index_transaction *t)
+{
+	if (mail_index_view_lock(t->view) < 0)
+		return -1;
 
-			mail_index_buffer_convert_to_uids(t, buf[i],
-				sizeof(uint32_t) * 2, TRUE);
-		}
-	}
+	arrays_convert_to_uids(t, &t->ext_rec_updates);
+	arrays_convert_to_uids(t, &t->keyword_updates);
 
-	mail_index_buffer_convert_to_uids(t, t->expunges,
-		sizeof(struct mail_transaction_expunge), TRUE);
-	mail_index_buffer_convert_to_uids(t, t->updates,
-		sizeof(struct mail_transaction_flag_update), TRUE);
+	mail_index_buffer_convert_to_uids(t, &t->expunges, TRUE);
+	mail_index_buffer_convert_to_uids(t, &t->updates, TRUE);
 	return 0;
 }
 
@@ -218,13 +198,9 @@
 struct mail_index_record *
 mail_index_transaction_lookup(struct mail_index_transaction *t, uint32_t seq)
 {
-	size_t pos;
-
 	i_assert(seq >= t->first_new_seq && seq <= t->last_new_seq);
 
-	pos = (seq - t->first_new_seq) * sizeof(struct mail_index_record);
-	return buffer_get_space_unsafe(t->appends, pos,
-				       sizeof(struct mail_index_record));
+	return array_modifyable_idx(&t->appends, seq - t->first_new_seq);
 }
 
 void mail_index_append(struct mail_index_transaction *t, uint32_t uid,
@@ -236,8 +212,10 @@
 
 	t->log_updates = TRUE;
 
-	if (t->appends == NULL)
-		t->appends = buffer_create_dynamic(default_pool, 4096);
+	if (!array_is_created(&t->appends)) {
+		ARRAY_CREATE(&t->appends, default_pool,
+			     struct mail_index_record, 32);
+	}
 
 	/* sequence number is visible only inside given view,
 	   so let it generate it */
@@ -246,32 +224,30 @@
 	else
 		*seq_r = t->last_new_seq = t->first_new_seq;
 
-	rec = buffer_append_space_unsafe(t->appends, sizeof(*rec));
-	memset(rec, 0, sizeof(*rec));
+	rec = array_modifyable_append(&t->appends);
 	rec->uid = uid;
 }
 
 void mail_index_append_assign_uids(struct mail_index_transaction *t,
 				   uint32_t first_uid, uint32_t *next_uid_r)
 {
-        struct mail_index_record *rec, *end;
-	size_t size;
+	struct mail_index_record *recs;
+	unsigned int i, count;
 
-	if (t->appends == NULL)
+	if (!array_is_created(&t->appends))
 		return;
 
-	rec = buffer_get_modifyable_data(t->appends, &size);
-	end = PTR_OFFSET(rec, size);
+	recs = array_get_modifyable(&t->appends, &count);
 
 	/* find the first mail with uid = 0 */
-	for (; rec != end; rec++) {
-		if (rec->uid == 0)
+	for (i = 0; i < count; i++) {
+		if (recs[i].uid == 0)
 			break;
 	}
 
-	for (; rec != end; rec++) {
-		i_assert(rec->uid == 0);
-		rec->uid = first_uid++;
+	for (; i < count; i++) {
+		i_assert(recs[i].uid == 0);
+		recs[i].uid = first_uid++;
 	}
 
 	*next_uid_r = first_uid;
@@ -282,36 +258,33 @@
 };
 
 static void
-mail_index_seq_range_buffer_add(buffer_t **buffer_p, size_t initial_size,
-				uint32_t seq)
+mail_index_seq_range_array_add(array_t *array, unsigned int init_count,
+			       uint32_t seq)
 {
-	buffer_t *buffer;
+        ARRAY_ARG_SET_TYPE(array, struct seq_range);
 	struct seq_range *data, value;
-	unsigned int idx, left_idx, right_idx;
-	size_t size;
+	unsigned int idx, left_idx, right_idx, count;
 
-	if (*buffer_p == NULL) {
-		*buffer_p = buffer_create_dynamic(default_pool, initial_size);
-		buffer_append(*buffer_p, &seq, sizeof(seq));
-		buffer_append(*buffer_p, &seq, sizeof(seq));
+	value.seq1 = value.seq2 = seq;
+
+	if (!array_is_created(array)) {
+		array_create(array, default_pool,
+			     sizeof(struct seq_range), init_count);
+		array_append(array, &value, 1);
 		return;
 	}
-	buffer = *buffer_p;
-
-	value.seq1 = value.seq2 = seq;
 
-	data = buffer_get_modifyable_data(buffer, &size);
-	size /= sizeof(*data);
-	i_assert(size > 0);
+	data = array_get_modifyable(array, &count);
+	i_assert(count > 0);
 
 	/* quick checks */
-	if (data[size-1].seq2 == seq-1) {
+	if (data[count-1].seq2 == seq-1) {
 		/* grow last range */
-		data[size-1].seq2 = seq;
+		data[count-1].seq2 = seq;
 		return;
 	}
-	if (data[size-1].seq2 < seq) {
-		buffer_append(buffer, &value, sizeof(value));
+	if (data[count-1].seq2 < seq) {
+		array_append(array, &value, 1);
 		return;
 	}
 	if (data[0].seq1 == seq+1) {
@@ -320,13 +293,13 @@
 		return;
 	}
 	if (data[0].seq1 > seq) {
-		buffer_insert(buffer, 0, &value, sizeof(value));
+		array_insert(array, 0, &value, 1);
 		return;
 	}
 
 	/* somewhere in the middle, array is sorted so find it with
 	   binary search */
-	idx = 0; left_idx = 0; right_idx = size;
+	idx = 0; left_idx = 0; right_idx = count;
 	while (left_idx < right_idx) {
 		idx = (left_idx + right_idx) / 2;
 
@@ -344,8 +317,8 @@
 	if (data[idx].seq2 < seq)
 		idx++;
 
-        /* idx == size couldn't happen because we already handle it above */
-	i_assert(idx < size && data[idx].seq1 >= seq);
+        /* idx == count couldn't happen because we already handle it above */
+	i_assert(idx < count && data[idx].seq1 >= seq);
 	i_assert(data[idx].seq1 > seq || data[idx].seq2 < seq);
 
 	if (data[idx].seq1 == seq+1) {
@@ -353,45 +326,41 @@
 		if (idx > 0 && data[idx-1].seq2 == seq-1) {
 			/* merge */
 			data[idx-1].seq2 = data[idx].seq2;
-			buffer_delete(buffer, idx * sizeof(*data),
-				      sizeof(*data));
+			array_delete(array, idx, 1);
 		}
 	} else if (data[idx].seq2 == seq-1) {
-		i_assert(idx+1 < size); /* already handled above */
+		i_assert(idx+1 < count); /* already handled above */
 		data[idx].seq2 = seq;
 		if (data[idx+1].seq1 == seq+1) {
 			/* merge */
 			data[idx+1].seq1 = data[idx].seq1;
-			buffer_delete(buffer, idx * sizeof(*data),
-				      sizeof(*data));
+			array_delete(array, idx, 1);
 		}
 	} else {
-		buffer_insert(buffer, idx * sizeof(*data),
-                              &value, sizeof(value));
+		array_insert(array, idx, &value, 1);
 	}
 }
 
-static void mail_index_seq_range_buffer_remove(buffer_t *buffer, uint32_t seq)
+static void mail_index_seq_range_array_remove(array_t *array, uint32_t seq)
 {
+        ARRAY_ARG_SET_TYPE(array, struct seq_range);
 	struct seq_range *data, value;
-	unsigned int idx, left_idx, right_idx;
-	size_t size;
+	unsigned int idx, left_idx, right_idx, count;
 
-	if (buffer == NULL)
+	if (!array_is_created(array))
 		return;
 
-	data = buffer_get_modifyable_data(buffer, &size);
-	size /= sizeof(*data);
-	i_assert(size > 0);
+	data = array_get_modifyable(array, &count);
+	i_assert(count > 0);
 
 	/* quick checks */
-	if (seq > data[size-1].seq2 || seq < data[0].seq1) {
+	if (seq > data[count-1].seq2 || seq < data[0].seq1) {
 		/* outside the range */
 		return;
 	}
-	if (data[size-1].seq2 == seq) {
+	if (data[count-1].seq2 == seq) {
 		/* shrink last range */
-		data[size-1].seq2--;
+		data[count-1].seq2--;
 		return;
 	}
 	if (data[0].seq1 == seq) {
@@ -402,7 +371,7 @@
 
 	/* somewhere in the middle, array is sorted so find it with
 	   binary search */
-	idx = 0; left_idx = 0; right_idx = size;
+	idx = 0; left_idx = 0; right_idx = count;
 	while (left_idx < right_idx) {
 		idx = (left_idx + right_idx) / 2;
 
@@ -416,9 +385,7 @@
 				if (data[idx].seq1 == data[idx].seq2) {
 					/* a single sequence range.
 					   remove it entirely */
-					buffer_delete(buffer,
-						      idx * sizeof(*data),
-						      sizeof(*data));
+					array_delete(array, idx, 1);
 				} else {
 					/* shrink the range */
 					data[idx].seq1++;
@@ -432,8 +399,7 @@
 				value.seq2 = data[idx].seq2;
 				data[idx].seq2 = seq - 1;
 
-				buffer_insert(buffer, idx * sizeof(*data),
-					      &value, sizeof(value));
+				array_insert(array, idx, &value, 1);
 			}
 			break;
 		}
@@ -447,7 +413,7 @@
 	t->log_updates = TRUE;
 
 	/* expunges is a sorted array of {seq1, seq2, ..}, .. */
-	mail_index_seq_range_buffer_add(&t->expunges, 512, seq);
+	mail_index_seq_range_array_add(&t->expunges, 128, seq);
 }
 
 static void
@@ -456,13 +422,12 @@
 			      uint32_t left_idx, uint32_t right_idx)
 {
 	struct mail_transaction_flag_update *updates, tmp_update;
-	size_t size;
+	unsigned int count;
 	uint32_t idx, move;
 
-	updates = buffer_get_modifyable_data(t->updates, &size);
-	size /= sizeof(*updates);
+	updates = array_get_modifyable(&t->updates, &count);
 
-	i_assert(left_idx <= right_idx && right_idx <= size);
+	i_assert(left_idx <= right_idx && right_idx <= count);
 
 	/* find the first update with either overlapping range,
 	   or the update which will come after our insert */
@@ -477,14 +442,14 @@
 		else
 			break;
 	}
-	if (idx < size && updates[idx].uid2 < u.uid1)
+	if (idx < count && updates[idx].uid2 < u.uid1)
 		idx++;
 
 	/* overlapping ranges, split/merge them */
 	i_assert(idx == 0 || updates[idx-1].uid2 < u.uid1);
-	i_assert(idx == size || updates[idx].uid2 >= u.uid1);
+	i_assert(idx == count || updates[idx].uid2 >= u.uid1);
 
-	for (; idx < size && u.uid2 >= updates[idx].uid1; idx++) {
+	for (; idx < count && u.uid2 >= updates[idx].uid1; idx++) {
 		if (u.uid1 != updates[idx].uid1 &&
 		    (updates[idx].add_flags != u.add_flags ||
 		     updates[idx].remove_flags != u.remove_flags)) {
@@ -504,10 +469,9 @@
 			i_assert(tmp_update.uid1 <= tmp_update.uid2);
 			i_assert(updates[idx].uid1 <= updates[idx].uid2);
 
-			buffer_insert(t->updates, idx * sizeof(tmp_update),
-				      &tmp_update, sizeof(tmp_update));
-			updates = buffer_get_modifyable_data(t->updates, NULL);
-			size++; idx += move;
+			array_insert(&t->updates, idx, &tmp_update, 1);
+			updates = array_get_modifyable(&t->updates, &count);
+			idx += move;
 		} else if (u.uid1 < updates[idx].uid1) {
 			updates[idx].uid1 = u.uid1;
 		}
@@ -523,10 +487,8 @@
 			i_assert(tmp_update.uid1 <= tmp_update.uid2);
 			i_assert(updates[idx].uid1 <= updates[idx].uid2);
 
-			buffer_insert(t->updates, idx * sizeof(tmp_update),
-				      &tmp_update, sizeof(tmp_update));
-			updates = buffer_get_modifyable_data(t->updates, NULL);
-			size++;
+			array_insert(&t->updates, idx, &tmp_update, 1);
+			updates = array_get_modifyable(&t->updates, &count);
 		}
 
 		updates[idx].add_flags =
@@ -543,12 +505,12 @@
 			break;
 		}
 	}
-	i_assert(idx <= size);
+	i_assert(idx <= count);
 
 	if (u.uid1 <= u.uid2) {
 		i_assert(idx == 0 || updates[idx-1].uid2 < u.uid1);
-		i_assert(idx == size || updates[idx].uid1 > u.uid2);
-		buffer_insert(t->updates, idx * sizeof(u), &u, sizeof(u));
+		i_assert(idx == count || updates[idx].uid1 > u.uid2);
+		array_insert(&t->updates, idx, &u, 1);
 	}
 	t->last_update_idx = idx;
 }
@@ -577,7 +539,7 @@
 {
 	struct mail_index_record *rec;
 	struct mail_transaction_flag_update u, *last_update;
-	size_t size;
+	unsigned int count;
 
 	t->log_updates = TRUE;
 
@@ -616,23 +578,22 @@
 		break;
 	}
 
-	if (t->updates == NULL) {
-		t->updates = buffer_create_dynamic(default_pool, 4096);
-		buffer_append(t->updates, &u, sizeof(u));
+	if (!array_is_created(&t->updates)) {
+		ARRAY_CREATE(&t->updates, default_pool,
+			     struct mail_transaction_flag_update, 256);
+		array_append(&t->updates, &u, 1);
 		return;
 	}
 
-	last_update = buffer_get_modifyable_data(t->updates, &size);
-	size /= sizeof(*last_update);
-
-	if (t->last_update_idx < size) {
+	last_update = array_get_modifyable(&t->updates, &count);
+	if (t->last_update_idx < count) {
 		/* fast path - hopefully we're updating the next message,
 		   or a message that is to be appended as last update */
 		last_update += t->last_update_idx;
 		if (seq1 - 1 == last_update->uid2) {
 			if (u.add_flags == last_update->add_flags &&
 			    u.remove_flags == last_update->remove_flags &&
-			    (t->last_update_idx + 1 == size ||
+			    (t->last_update_idx + 1 == count ||
 			     last_update[1].uid1 > seq2)) {
 				/* we can just update the UID range */
 				last_update->uid2 = seq2;
@@ -645,8 +606,8 @@
 		}
 	}
 
-	if (t->last_update_idx == size) {
-		buffer_append(t->updates, &u, sizeof(u));
+	if (t->last_update_idx == count) {
+		array_append(&t->updates, &u, 1);
 		return;
 	}
 
@@ -654,7 +615,7 @@
 	if (seq1 > last_update->uid2) {
 		/* added after this */
 		mail_index_insert_flag_update(t, u, t->last_update_idx + 1,
-					      size);
+					      count);
 	} else {
 		/* added before this or on top of this */
 		mail_index_insert_flag_update(t, u, 0, t->last_update_idx + 1);
@@ -668,72 +629,71 @@
 	mail_index_update_flags_range(t, seq, seq, modify_type, flags);
 }
 
-int mail_index_seq_buffer_lookup(buffer_t *buffer, uint32_t seq,
-				 size_t record_size, size_t *pos_r)
+int mail_index_seq_array_lookup(const array_t *array, uint32_t seq,
+				unsigned int *idx_r)
 {
-	unsigned int idx, left_idx, right_idx;
-	void *data;
-	uint32_t full_record_size, *seq_p;
-	size_t size;
-
-	full_record_size = record_size + sizeof(seq);
+        ARRAY_ARG_SET_TYPE(array, uint32_t);
+	unsigned int idx, left_idx, right_idx, count;
+	const uint32_t *seq_p;
 
-	data = buffer_get_modifyable_data(buffer, &size);
+	count = array_count(array);
+	if (count == 0) {
+		*idx_r = 0;
+		return FALSE;
+	}
 
 	/* we're probably appending it, check */
-	if (size == 0)
-		idx = 0;
-	else if (*((uint32_t *)PTR_OFFSET(data, size-full_record_size)) < seq)
-		idx = size / full_record_size;
+	seq_p = array_idx(array, count-1);
+	if (*seq_p < seq)
+		idx = count;
 	else {
-		idx = 0; left_idx = 0; right_idx = size / full_record_size;
+		idx = 0; left_idx = 0; right_idx = count;
 		while (left_idx < right_idx) {
 			idx = (left_idx + right_idx) / 2;
 
-			seq_p = PTR_OFFSET(data, idx * full_record_size);
+			seq_p = array_idx(array, idx);
 			if (*seq_p < seq)
 				left_idx = idx+1;
 			else if (*seq_p > seq)
 				right_idx = idx;
 			else {
-				*pos_r = idx * full_record_size;
+				*idx_r = idx;
 				return TRUE;
 			}
 		}
 	}
 
-	*pos_r = idx * full_record_size;
+	*idx_r = idx;
 	return FALSE;
 }
 
-static int mail_index_seq_buffer_add(buffer_t **buffer, uint32_t seq,
-				     const void *record, size_t record_size,
-				     void *old_record)
+static int mail_index_seq_array_add(array_t *array, uint32_t seq,
+				    const void *record, size_t record_size,
+				    void *old_record)
 {
+        ARRAY_ARG_SET_TYPE(array, void *);
 	void *p;
-	size_t pos;
+	unsigned int idx;
 
-	if (*buffer == NULL) {
-		*buffer = buffer_create_dynamic(default_pool, 1024);
-		buffer_append(*buffer, &seq, sizeof(seq));
-		buffer_append(*buffer, record, record_size);
-		return FALSE;
+	if (!array_is_created(array)) {
+		array_create(array, default_pool,
+			     sizeof(seq) + record_size,
+			     1024 / (sizeof(seq) + record_size));
 	}
+	i_assert(array->element_size == sizeof(seq) + record_size);
 
-	if (mail_index_seq_buffer_lookup(*buffer, seq, record_size, &pos)) {
+	if (mail_index_seq_array_lookup(array, seq, &idx)) {
 		/* already there, update */
-		p = buffer_get_space_unsafe(*buffer, pos + sizeof(seq),
-					    record_size);
+		p = array_modifyable_idx(array, idx);
 		if (old_record != NULL)
 			memcpy(old_record, p, record_size);
-		memcpy(p, record, record_size);
+		memcpy(PTR_OFFSET(p, sizeof(seq)), record, record_size);
 		return TRUE;
 	} else {
 		/* insert */
-		buffer_copy(*buffer, pos + sizeof(seq) + record_size,
-			    *buffer, pos, (size_t)-1);
-		buffer_write(*buffer, pos, &seq, sizeof(seq));
-		buffer_write(*buffer, pos + sizeof(seq), record, record_size);
+                p = array_modifyable_insert(array, idx);
+		memcpy(p, &seq, sizeof(seq));
+		memcpy(PTR_OFFSET(p, sizeof(seq)), record, record_size);
 		return FALSE;
 	}
 }
@@ -763,55 +723,53 @@
 
 	if (!mail_index_map_get_ext_idx(t->view->map, ext_id, &intro.ext_id)) {
 		intro.ext_id = (uint32_t)-1;
-		ext = t->view->index->extensions->data;
-		ext += ext_id;
+		ext = array_idx(&t->view->index->extensions, ext_id);
 	} else {
-		ext = t->view->map->extensions->data;
-		ext += ext_id;
+		ext = array_idx(&t->view->map->extensions, ext_id);
 	}
 
-	/* allow only header size changes if something was already written */
-	i_assert(t->ext_rec_updates == NULL ||
+	/* allow only header size changes if extension records have already
+	   been changed in transaction */
+	i_assert(!array_is_created(&t->ext_rec_updates) ||
 		 (ext->record_size == record_size &&
 		  ext->record_align == record_align));
 
 	t->log_updates = TRUE;
 
-	if (t->ext_resizes == NULL)
-		t->ext_resizes = buffer_create_dynamic(default_pool, 128);
+	if (!array_is_created(&t->ext_resizes)) {
+		ARRAY_CREATE(&t->ext_resizes, default_pool,
+			     struct mail_transaction_ext_intro, ext_id + 2);
+	}
 
 	intro.hdr_size = hdr_size;
 	intro.record_size = record_size;
 	intro.record_align = record_align;
 	intro.name_size = 1;
-	buffer_write(t->ext_resizes, ext_id * sizeof(intro),
-		     &intro, sizeof(intro));
+	array_idx_set(&t->ext_resizes, ext_id, &intro);
 }
 
 void mail_index_ext_reset(struct mail_index_transaction *t, uint32_t ext_id,
 			  uint32_t reset_id)
 {
-	size_t pos;
-
 	i_assert(reset_id != 0);
 
 	t->log_updates = TRUE;
 
-	if (t->ext_rec_updates != NULL &&
-	    ext_id < t->ext_rec_updates->used / sizeof(buffer_t *)) {
-		buffer_t *const *buf = t->ext_rec_updates->data;
-		buf += ext_id;
+	if (array_is_created(&t->ext_rec_updates) &&
+	    ext_id < array_count(&t->ext_rec_updates)) {
+		/* if extension records have been updated, clear them */
+		array_t *array;
 
-		if (*buf != NULL) 
-			buffer_set_used_size(*buf, 0);
+		array = array_modifyable_idx(&t->ext_rec_updates, ext_id);
+		if (array_is_created(array))
+			array_clear(array);
 	}
 
-	pos = ext_id * sizeof(uint32_t);
-	if (t->ext_resets == NULL) {
-		t->ext_resets = buffer_create_dynamic(default_pool,
-						      pos + sizeof(uint32_t));
+	if (!array_is_created(&t->ext_resets)) {
+		ARRAY_CREATE(&t->ext_resets, default_pool,
+			     uint32_t, ext_id + 2);
 	}
-	buffer_write(t->ext_resets, pos, &reset_id, sizeof(reset_id));
+	array_idx_set(&t->ext_resets, ext_id, &reset_id);
 }
 
 void mail_index_update_header_ext(struct mail_index_transaction *t,
@@ -827,40 +785,40 @@
 	struct mail_index *index = t->view->index;
         const struct mail_index_ext *ext;
 	const struct mail_transaction_ext_intro *intro;
-	buffer_t **buf;
 	uint16_t record_size;
-	size_t size;
+	array_t *array;
+	unsigned int count;
 
 	i_assert(seq > 0 &&
 		 (seq <= mail_index_view_get_messages_count(t->view) ||
 		  seq <= t->last_new_seq));
-	i_assert(ext_id < index->extensions->used / sizeof(*ext));
+	i_assert(ext_id < array_count(&index->extensions));
 
 	t->log_updates = TRUE;
 
-	if (t->ext_resizes == NULL) {
+	if (!array_is_created(&t->ext_resizes)) {
 		intro = NULL;
-		size = 0;
+		count = 0;
 	} else {
-		intro = buffer_get_data(t->ext_resizes, &size);
+		intro = array_get(&t->ext_resizes, &count);
 	}
-	if (ext_id < size / sizeof(*intro) && intro[ext_id].name_size != 0) {
+	if (ext_id < count && intro[ext_id].name_size != 0) {
 		/* resized record */
 		record_size = intro[ext_id].record_size;
 	} else {
-		ext = index->extensions->data;
-		record_size = ext[ext_id].record_size;
+		ext = array_idx(&index->extensions, ext_id);
+		record_size = ext->record_size;
 	}
 
-	if (t->ext_rec_updates == NULL)
-		t->ext_rec_updates = buffer_create_dynamic(default_pool, 128);
-	buf = buffer_get_space_unsafe(t->ext_rec_updates,
-				      ext_id * sizeof(buffer_t *),
-				      sizeof(buffer_t *));
+	if (!array_is_created(&t->ext_rec_updates)) {
+		ARRAY_CREATE(&t->ext_rec_updates, default_pool,
+			     array_t, ext_id + 2);
+	}
+	array = array_modifyable_idx(&t->ext_rec_updates, ext_id);
 
 	/* @UNSAFE */
-	if (!mail_index_seq_buffer_add(buf, seq, data, record_size,
-				       old_data_r)) {
+	if (!mail_index_seq_array_add(array, seq, data, record_size,
+				      old_data_r)) {
 		if (old_data_r != NULL)
 			memset(old_data_r, 0, record_size);
 	}
@@ -939,9 +897,8 @@
 				enum modify_type modify_type,
 				struct mail_keywords *keywords)
 {
-	buffer_t **buf;
-	unsigned int i;
-	size_t pos;
+	array_t *arr;
+	unsigned int i, idx;
 
 	i_assert(seq > 0 &&
 		 (seq <= mail_index_view_get_messages_count(t->view) ||
@@ -956,50 +913,42 @@
 	   If t->keyword_resets is set for the sequence, there's no need to
 	   update remove_seq as it will remove all keywords. */
 
-	if (t->keyword_updates == NULL) {
+	if (!array_is_created(&t->keyword_updates)) {
 		uint32_t max_idx = keywords->idx[keywords->count-1];
 
-		t->keyword_updates =
-			buffer_create_dynamic(default_pool,
-					      max_idx * 2 * sizeof(buffer_t *));
+		ARRAY_CREATE(&t->keyword_updates, default_pool,
+			     array_t, max_idx * 2);
 	}
 
 	switch (modify_type) {
 	case MODIFY_ADD:
 		for (i = 0; i < keywords->count; i++) {
-			pos = keywords->idx[i] * 2 * sizeof(buffer_t *);
-			buf = buffer_get_space_unsafe(t->keyword_updates, pos,
-						      sizeof(buffer_t *));
-			mail_index_seq_range_buffer_add(buf, 64, seq);
+			idx = keywords->idx[i] * 2;
+			arr = array_modifyable_idx(&t->keyword_updates, idx);
+			mail_index_seq_range_array_add(arr, 16, seq);
 
-			buf = buffer_get_space_unsafe(t->keyword_updates,
-						      pos + sizeof(buffer_t *),
-						      sizeof(buffer_t *));
-			mail_index_seq_range_buffer_remove(*buf, seq);
+			arr = array_modifyable_idx(&t->keyword_updates, idx+1);
+			mail_index_seq_range_array_remove(arr, seq);
 		}
 		break;
 	case MODIFY_REMOVE:
 		for (i = 0; i < keywords->count; i++) {
-			pos = keywords->idx[i] * 2 * sizeof(buffer_t *);
-			buf = buffer_get_space_unsafe(t->keyword_updates, pos,
-						      sizeof(buffer_t *));
-			mail_index_seq_range_buffer_remove(*buf, seq);
+			idx = keywords->idx[i] * 2;
+			arr = array_modifyable_idx(&t->keyword_updates, idx);
+			mail_index_seq_range_array_remove(arr, seq);
 
-			buf = buffer_get_space_unsafe(t->keyword_updates,
-						      pos + sizeof(buffer_t *),
-						      sizeof(buffer_t *));
-			mail_index_seq_range_buffer_add(buf, 64, seq);
+			arr = array_modifyable_idx(&t->keyword_updates, idx+1);
+			mail_index_seq_range_array_add(arr, 16, seq);
 		}
 		break;
 	case MODIFY_REPLACE:
 		for (i = 0; i < keywords->count; i++) {
-			pos = keywords->idx[i] * 2 * sizeof(buffer_t *);
-			buf = buffer_get_space_unsafe(t->keyword_updates, pos,
-						      sizeof(buffer_t *));
-			mail_index_seq_range_buffer_add(buf, 64, seq);
+			idx = keywords->idx[i] * 2;
+			arr = array_modifyable_idx(&t->keyword_updates, idx);
+			mail_index_seq_range_array_add(arr, 16, seq);
 		}
 
-		mail_index_seq_range_buffer_add(&t->keyword_resets, 64, seq);
+		mail_index_seq_range_array_add(&t->keyword_resets, 16, seq);
 		break;
 	}
 

Index: mail-index-view.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-view.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- mail-index-view.c	26 Dec 2004 09:12:40 -0000	1.32
+++ mail-index-view.c	12 Mar 2005 18:16:29 -0000	1.33
@@ -387,10 +387,9 @@
 		return ret;
 	}
 
-	ext = (*map_r)->extensions->data;
-	ext += idx;
-
+	ext = array_idx(&(*map_r)->extensions, idx);
 	offset = ext->record_offset;
+
 	*data_r = offset == 0 ? NULL : CONST_PTR_OFFSET(rec, offset);
 	return ret;
 }
@@ -418,9 +417,7 @@
 		return 0;
 	}
 
-	ext = map->extensions->data;
-	ext += idx;
-
+	ext = array_idx(&map->extensions, idx);
 	*data_r = CONST_PTR_OFFSET(map->hdr_base, ext->hdr_offset);
 	*data_size_r = ext->hdr_size;
 	return 0;
@@ -484,9 +481,7 @@
 		return ret;
 	}
 
-	ext = map->extensions->data;
-	ext += idx;
-
+	ext = array_idx(&map->extensions, idx);
 	for (i = 0, idx = 0; i < ext->record_size; i++) {
 		if (((const char *)data)[i] == 0)
 			continue;
@@ -606,12 +601,10 @@
 const struct mail_index_ext *
 mail_index_view_get_ext(struct mail_index_view *view, uint32_t ext_id)
 {
-	const struct mail_index_ext *ext;
 	uint32_t idx;
 
 	if (!mail_index_map_get_ext_idx(view->map, ext_id, &idx))
 		return 0;
 
-	ext = view->map->extensions->data;
-	return &ext[idx];
+	return array_idx(&view->map->extensions, idx);
 }

Index: mail-index.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index.c,v
retrieving revision 1.191
retrieving revision 1.192
diff -u -d -r1.191 -r1.192
--- mail-index.c	5 Mar 2005 19:19:24 -0000	1.191
+++ mail-index.c	12 Mar 2005 18:16:29 -0000	1.192
@@ -27,10 +27,15 @@
 	index->fd = -1;
 
 	index->extension_pool = pool_alloconly_create("extension", 256);
-	index->extensions = buffer_create_dynamic(index->extension_pool, 64);
-        index->sync_handlers = buffer_create_dynamic(default_pool, 64);
-        index->sync_lost_handlers = buffer_create_dynamic(default_pool, 64);
-        index->expunge_handlers = buffer_create_dynamic(default_pool, 32);
+	ARRAY_CREATE(&index->extensions, index->extension_pool,
+		     struct mail_index_ext, 5);
+
+	ARRAY_CREATE(&index->expunge_handlers, default_pool,
+		     mail_index_expunge_handler_t *, 4);
+	ARRAY_CREATE(&index->sync_handlers, default_pool,
+		     struct mail_index_sync_handler, 4);
+	ARRAY_CREATE(&index->sync_lost_handlers, default_pool,
+		     mail_index_sync_lost_handler_t *, 4);
 
 	index->mode = 0600;
 	index->gid = (gid_t)-1;
@@ -50,9 +55,9 @@
 	pool_unref(index->extension_pool);
 	pool_unref(index->keywords_pool);
 
-	buffer_free(index->sync_handlers);
-	buffer_free(index->sync_lost_handlers);
-	buffer_free(index->expunge_handlers);
+	array_free(&index->sync_handlers);
+	array_free(&index->sync_lost_handlers);
+	array_free(&index->expunge_handlers);
 	buffer_free(index->keywords_buf);
 
 	i_free(index->error);
@@ -75,14 +80,11 @@
 {
         const struct mail_index_ext *extensions;
 	struct mail_index_ext ext;
-	size_t ext_count;
-	unsigned int i;
+	unsigned int i, ext_count;
 
-	extensions = buffer_get_data(index->extensions, &ext_count);
-	ext_count /= sizeof(*extensions);
+	extensions = array_get(&index->extensions, &ext_count);
 
-	i_assert(index->sync_handlers->used /
-		 sizeof(struct mail_index_sync_handler) == ext_count);
+	i_assert(array_count(&index->sync_handlers) == ext_count);
 
 	/* see if it's already there */
 	for (i = 0; i < ext_count; i++) {
@@ -97,9 +99,8 @@
 	ext.record_size = default_record_size;
 	ext.record_align = default_record_align;
 
-	buffer_append(index->extensions, &ext, sizeof(ext));
-	buffer_append_zero(index->sync_handlers,
-			   sizeof(struct mail_index_sync_handler));
+	array_append(&index->extensions, &ext, 1);
+	(void)array_modifyable_append(&index->sync_handlers);
 	return ext_count;
 }
 
@@ -107,37 +108,34 @@
 					 uint32_t ext_id,
 					 mail_index_expunge_handler_t *cb)
 {
-	buffer_write(index->expunge_handlers, ext_id * sizeof(cb),
-		     &cb, sizeof(cb));
+	array_idx_set(&index->expunge_handlers, ext_id, &cb);
 }
 
 void mail_index_register_sync_handler(struct mail_index *index, uint32_t ext_id,
 				      mail_index_sync_handler_t *cb,
 				      enum mail_index_sync_handler_type type)
 {
-	struct mail_index_sync_handler h;
+	struct mail_index_sync_handler *h;
 
-	memset(&h, 0, sizeof(h));
-	h.callback = cb;
-	h.type = type;
-	buffer_write(index->sync_handlers, ext_id * sizeof(h), &h, sizeof(h));
+	h = array_modifyable_idx(&index->sync_handlers, ext_id);
+	h->callback = cb;
+	h->type = type;
 }
 
 void mail_index_register_sync_lost_handler(struct mail_index *index,
 					   mail_index_sync_lost_handler_t *cb)
 {
-	buffer_append(index->sync_lost_handlers, &cb, sizeof(cb));
+	array_append(&index->sync_lost_handlers, &cb, 1);
 }
 
 static void mail_index_map_init_extbufs(struct mail_index_map *map,
 					unsigned int initial_count)
 {
-	size_t ext_size, ext_id_map_size, size;
+	size_t size;
 
-	ext_size = initial_count * sizeof(struct mail_index_ext);
-	ext_id_map_size = initial_count * sizeof(uint32_t);
 	if (map->extension_pool == NULL) {
-		size = ext_size + ext_id_map_size +
+		size = initial_count * sizeof(struct mail_index_ext) +
+                        initial_count * sizeof(uint32_t) +
 			(initial_count * 20); /* for names */
 		map->extension_pool =
 			pool_alloconly_create("extensions",
@@ -146,22 +144,21 @@
 		p_clear(map->extension_pool);
 	}
 
-	map->extensions = buffer_create_dynamic(map->extension_pool, ext_size);
-	map->ext_id_map =
-		buffer_create_dynamic(map->extension_pool, ext_id_map_size);
+	ARRAY_CREATE(&map->extensions, map->extension_pool,
+		     struct mail_index_ext, initial_count);
+	ARRAY_CREATE(&map->ext_id_map, map->extension_pool,
+		     uint32_t, initial_count);
 }
 
 uint32_t mail_index_map_lookup_ext(struct mail_index_map *map, const char *name)
 {
 	const struct mail_index_ext *extensions;
-	size_t i, size;
+	unsigned int i, size;
 
-	if (map->extensions == NULL)
+	if (!array_is_created(&map->extensions))
 		return (uint32_t)-1;
 
-	extensions = buffer_get_data(map->extensions, &size);
-	size /= sizeof(*extensions);
-
+	extensions = array_get(&map->extensions, &size);
 	for (i = 0; i < size; i++) {
 		if (strcmp(extensions[i].name, name) == 0)
 			return i;
@@ -177,17 +174,17 @@
 			    uint32_t record_align, uint32_t reset_id)
 {
 	struct mail_index_ext *ext;
-	uint32_t idx, ext_id, empty_id = (uint32_t)-1;
+	uint32_t idx, empty_idx = (uint32_t)-1;
 
-	if (map->extensions == NULL) {
+	if (!array_is_created(&map->extensions)) {
                 mail_index_map_init_extbufs(map, 5);
 		idx = 0;
 	} else {
-		idx = map->extensions->used / sizeof(*ext);
+		idx = array_count(&map->extensions);
 	}
 	i_assert(mail_index_map_lookup_ext(map, name) == (uint32_t)-1);
 
-	ext = buffer_append_space_unsafe(map->extensions, sizeof(*ext));
+	ext = array_modifyable_append(&map->extensions);
 	memset(ext, 0, sizeof(*ext));
 
 	ext->name = p_strdup(map->extension_pool, name);
@@ -198,14 +195,12 @@
 	ext->record_align = record_align;
 	ext->reset_id = reset_id;
 
-	ext_id = mail_index_ext_register(index, name, hdr_size,
-					 record_size, record_align);
-	ext->index_idx = ext_id;
+	ext->index_idx = mail_index_ext_register(index, name, hdr_size,
+						 record_size, record_align);
 
-	while (map->ext_id_map->used < ext_id * sizeof(uint32_t))
-		buffer_append(map->ext_id_map, &empty_id, sizeof(empty_id));
-	buffer_write(map->ext_id_map, ext_id * sizeof(uint32_t),
-		     &idx, sizeof(idx));
+	while (array_count(&map->ext_id_map) < ext->index_idx)
+		array_append(&map->ext_id_map, &empty_idx, 1);
+	array_idx_set(&map->ext_id_map, ext->index_idx, &idx);
 	return idx;
 }
 
@@ -240,12 +235,12 @@
 		return 1;
 	}
 
-	old_count = index->extensions->used / sizeof(struct mail_index_ext);
+	old_count = array_count(&index->extensions);
 	mail_index_map_init_extbufs(map, old_count + 5);
 
 	ext_id = (uint32_t)-1;
 	for (i = 0; i < old_count; i++)
-		buffer_append(map->ext_id_map, &ext_id, sizeof(ext_id));
+		array_append(&map->ext_id_map, &ext_id, 1);
 
 	while (offset < map->hdr.header_size) {
 		ext_hdr = CONST_PTR_OFFSET(map->hdr_base, offset);
@@ -307,8 +302,7 @@
 		return 0;
 	}
 
-	ext = map->extensions->data;
-	ext += ext_id;
+	ext = array_idx(&map->extensions, ext_id);
 
 	kw_hdr = CONST_PTR_OFFSET(map->hdr_base, ext->hdr_offset);
 	kw_rec = (const void *)(kw_hdr + 1);
@@ -761,8 +755,7 @@
 					  int sync_to_index)
 {
 	mail_index_sync_lost_handler_t *const *handlers;
-	size_t size;
-	unsigned int i;
+	unsigned int i, count;
 	int ret, retry;
 
 	if (index->log_locked) {
@@ -785,10 +778,8 @@
 	}
 
 	/* notify all "sync lost" handlers */
-	handlers = buffer_get_data(index->sync_lost_handlers, &size);
-	size /= sizeof(*handlers);
-
-	for (i = 0; i < size; i++)
+	handlers = array_get(&index->sync_lost_handlers, &count);
+	for (i = 0; i < count; i++)
 		(*handlers[i])(index);
 
 	for (i = 0; i < MAIL_INDEX_ESTALE_RETRY_COUNT; i++) {
@@ -979,18 +970,15 @@
 	mem_map->hdr_base = hdr;
 
 	/* copy extensions */
-	if (map->ext_id_map != NULL) {
-		count = map->ext_id_map->used / sizeof(uint32_t);
+	if (array_is_created(&map->ext_id_map)) {
+		count = array_count(&map->ext_id_map);
 		mail_index_map_init_extbufs(mem_map, count + 2);
 
-		buffer_append_buf(mem_map->extensions, map->extensions,
-				  0, (size_t)-1);
-		buffer_append_buf(mem_map->ext_id_map, map->ext_id_map,
-				  0, (size_t)-1);
+		array_append_array(&mem_map->extensions, &map->extensions);
+		array_append_array(&mem_map->ext_id_map, &map->ext_id_map);
 
 		/* fix the name pointers to use our own pool */
-		extensions = buffer_get_modifyable_data(mem_map->extensions,
-							NULL);
+		extensions = array_get_modifyable(&mem_map->extensions, &count);
 		for (i = 0; i < count; i++) {
 			extensions[i].name = p_strdup(mem_map->extension_pool,
 						      extensions[i].name);
@@ -1003,14 +991,14 @@
 int mail_index_map_get_ext_idx(struct mail_index_map *map,
 			       uint32_t ext_id, uint32_t *idx_r)
 {
-	const uint32_t *id_map;
+	const uint32_t *id;
 
-	if (map->ext_id_map == NULL ||
-	    map->ext_id_map->used / sizeof(*id_map) <= ext_id)
+	if (!array_is_created(&map->ext_id_map) ||
+	    ext_id >= array_count(&map->ext_id_map))
 		return 0;
 
-	id_map = map->ext_id_map->data;
-	*idx_r = id_map[ext_id];
+	id = array_idx(&map->ext_id_map, ext_id);
+	*idx_r = *id;
 	return *idx_r != (uint32_t)-1;
 }
 

Index: mail-transaction-log-append.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-transaction-log-append.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- mail-transaction-log-append.c	5 Mar 2005 19:15:52 -0000	1.4
+++ mail-transaction-log-append.c	12 Mar 2005 18:16:29 -0000	1.5
@@ -105,26 +105,23 @@
         struct mail_transaction_ext_intro *intro;
 	buffer_t *buf;
 	uint32_t idx;
-	size_t size;
+	unsigned int count;
 
 	if (!mail_index_map_get_ext_idx(t->view->map, ext_id, &idx)) {
 		/* new extension */
 		idx = (uint32_t)-1;
 	}
 
-	ext = t->view->index->extensions->data;
-	ext += ext_id;
-
-	if (t->ext_resizes == NULL) {
+	ext = array_idx(&t->view->index->extensions, ext_id);
+	if (!array_is_created(&t->ext_resizes)) {
 		intro = NULL;
-		size = 0;
+		count = 0;
 	} else {
-		intro = buffer_get_modifyable_data(t->ext_resizes, &size);
-		size /= sizeof(*intro);
+		intro = array_get(&t->ext_resizes, &count);
 	}
 
 	buf = buffer_create_dynamic(pool_datastack_create(), 128);
-	if (ext_id < size && intro[ext_id].name_size != 0) {
+	if (ext_id < count && intro[ext_id].name_size != 0) {
 		/* we're resizing it */
 		intro += ext_id;
 
@@ -148,9 +145,7 @@
 	} else if (idx != (uint32_t)-1) {
 		/* use the existing reset_id */
 		const struct mail_index_ext *map_ext =
-			t->view->map->extensions->data;
-		map_ext += idx;
-
+			array_idx(&t->view->map->extensions, idx);
 		intro->reset_id = map_ext->reset_id;
 	} else {
 		/* new extension, reset_id defaults to 0 */
@@ -170,34 +165,31 @@
 {
         const struct mail_transaction_ext_intro *resize;
 	struct mail_transaction_ext_reset ext_reset;
-	uint32_t ext_id, ext_count, update_count, resize_count, reset_count;
+	unsigned int update_count, resize_count, reset_count, ext_count;
+	uint32_t ext_id;
 	const uint32_t *reset;
-	const buffer_t *const *update;
+	const array_t *update;
 	buffer_t *buf;
-	size_t size;
 
-	if (t->ext_rec_updates == NULL) {
+	if (!array_is_created(&t->ext_rec_updates)) {
 		update = NULL;
 		update_count = 0;
 	} else {
-		update = buffer_get_data(t->ext_rec_updates, &size);
-		update_count = size / sizeof(*update);
+		update = array_get(&t->ext_rec_updates, &update_count);
 	}
 
-	if (t->ext_resizes == NULL) {
+	if (!array_is_created(&t->ext_resizes)) {
 		resize = NULL;
 		resize_count = 0;
 	} else {
-		resize = buffer_get_data(t->ext_resizes, &size);
-		resize_count = size / sizeof(*resize);
+		resize = array_get(&t->ext_resizes, &resize_count);
 	}
 
-	if (t->ext_resets == NULL) {
+	if (!array_is_created(&t->ext_resets)) {
 		reset = NULL;
 		reset_count = 0;
 	} else {
-		reset = buffer_get_data(t->ext_resets, &size);
-		reset_count = size / sizeof(*reset);
+		reset = array_get(&t->ext_resets, &reset_count);
 	}
 
 	memset(&ext_reset, 0, sizeof(ext_reset));
@@ -212,7 +204,8 @@
 			ext_id < reset_count && reset[ext_id] != 0 ?
 			reset[ext_id] : 0;
 		if ((ext_id < resize_count && resize[ext_id].name_size) ||
-		    (ext_id < update_count && update[ext_id] != NULL) ||
+		    (ext_id < update_count &&
+		     array_is_created(&update[ext_id])) ||
 		    ext_reset.new_reset_id != 0) {
 			if (log_append_ext_intro(file, t, ext_id, 0) < 0)
 				return -1;
@@ -231,29 +224,27 @@
 static int log_append_ext_rec_updates(struct mail_transaction_log_file *file,
 				      struct mail_index_transaction *t)
 {
-	buffer_t **updates;
+	array_t *updates;
 	const uint32_t *reset;
-	uint32_t ext_id, reset_id, reset_count;
-	size_t size;
+	unsigned int ext_id, count, reset_count;
+	uint32_t reset_id;
 
-	if (t->ext_rec_updates == NULL) {
+	if (!array_is_created(&t->ext_rec_updates)) {
 		updates = NULL;
-		size = 0;
+		count = 0;
 	} else {
-		updates = buffer_get_modifyable_data(t->ext_rec_updates, &size);
-		size /= sizeof(*updates);
+		updates = array_get_modifyable(&t->ext_rec_updates, &count);
 	}
 
-	if (t->ext_resets == NULL) {
+	if (!array_is_created(&t->ext_resets)) {
 		reset = NULL;
 		reset_count = 0;
 	} else {
-		reset = buffer_get_data(t->ext_resets, &size);
-		reset_count = size / sizeof(*reset);
+		reset = array_get_modifyable(&t->ext_resets, &reset_count);
 	}
 
-	for (ext_id = 0; ext_id < size; ext_id++) {
-		if (updates[ext_id] == NULL)
+	for (ext_id = 0; ext_id < count; ext_id++) {
+		if (!array_is_created(&updates[ext_id]))
 			continue;
 
 		reset_id = ext_id < reset_count && reset[ext_id] != 0 ?
@@ -261,7 +252,7 @@
 		if (log_append_ext_intro(file, t, ext_id, reset_id) < 0)
 			return -1;
 
-		if (log_append_buffer(file, updates[ext_id], NULL,
+		if (log_append_buffer(file, updates[ext_id].buffer, NULL,
 				      MAIL_TRANSACTION_EXT_REC_UPDATE,
 				      t->external) < 0)
 			return -1;
@@ -274,15 +265,15 @@
 {
 	struct mail_index *index = t->view->index;
 	struct mail_transaction_keyword_update kt_hdr;
-	buffer_t *hdr_buf, **buf;
-	size_t i, size;
+	buffer_t *hdr_buf;
+	array_t *updates;
+	unsigned int i, count;
 
 	hdr_buf = buffer_create_dynamic(pool_datastack_create(), 64);
 
-	buf = buffer_get_modifyable_data(t->keyword_updates, &size);
-	size /= sizeof(*buf);
-	for (i = 0; i < size; i++) {
-		if (buf[i] == NULL)
+	updates = array_get_modifyable(&t->keyword_updates, &count);
+	for (i = 0; i < count; i++) {
+		if (!array_is_created(&updates[i]))
 			continue;
 
 		buffer_set_used_size(hdr_buf, 0);
@@ -296,7 +287,7 @@
 		if ((hdr_buf->used % 4) != 0)
 			buffer_append_zero(hdr_buf, 4 - (hdr_buf->used % 4));
 
-		if (log_append_buffer(file, buf[i], hdr_buf,
+		if (log_append_buffer(file, updates[i].buffer, hdr_buf,
 				      MAIL_TRANSACTION_KEYWORD_UPDATE,
 				      t->external) < 0)
 			return -1;
@@ -316,7 +307,7 @@
 	struct mail_index_header idx_hdr;
 	uoff_t append_offset;
 	unsigned int lock_id;
-	int ret;
+	int ret, visibility_changes = FALSE;
 
 	index = mail_index_view_get_index(view);
 	log = index->log;
@@ -383,30 +374,35 @@
 	   to avoid resize overhead as much as possible */
         ret = mail_transaction_log_append_ext_intros(file, t);
 
-	if (t->appends != NULL && ret == 0) {
-		ret = log_append_buffer(file, t->appends, NULL,
+	if (array_is_created(&t->appends) && ret == 0) {
+                visibility_changes = TRUE;
+		ret = log_append_buffer(file, t->appends.buffer, NULL,
 					MAIL_TRANSACTION_APPEND, t->external);
 	}
-	if (t->updates != NULL && ret == 0) {
-		ret = log_append_buffer(file, t->updates, NULL,
+	if (array_is_created(&t->updates) && ret == 0) {
+                visibility_changes = TRUE;
+		ret = log_append_buffer(file, t->updates.buffer, NULL,
 					MAIL_TRANSACTION_FLAG_UPDATE,
 					t->external);
 	}
 
-	if (t->ext_rec_updates != NULL && ret == 0)
+	if (array_is_created(&t->ext_rec_updates) && ret == 0)
 		ret = log_append_ext_rec_updates(file, t);
 
 	/* keyword resets before updates */
-	if (t->keyword_resets != NULL && ret == 0) {
-		ret = log_append_buffer(file, t->keyword_resets, NULL,
+	if (array_is_created(&t->keyword_resets) && ret == 0) {
+                visibility_changes = TRUE;
+		ret = log_append_buffer(file, t->keyword_resets.buffer, NULL,
 					MAIL_TRANSACTION_KEYWORD_RESET,
 					t->external);
 	}
-	if (t->keyword_updates != NULL && ret == 0)
+	if (array_is_created(&t->keyword_updates) && ret == 0) {
+                visibility_changes = TRUE;
 		ret = log_append_keyword_updates(file, t);
+	}
 
-	if (t->expunges != NULL && ret == 0) {
-		ret = log_append_buffer(file, t->expunges, NULL,
+	if (array_is_created(&t->expunges) && ret == 0) {
+		ret = log_append_buffer(file, t->expunges.buffer, NULL,
 					MAIL_TRANSACTION_EXPUNGE, t->external);
 	}
 	if (t->hdr_changed && ret == 0) {
@@ -420,8 +416,7 @@
 						  "pwrite()");
 	}
 
-	if (ret == 0 && (t->updates != NULL || t->appends != NULL) &&
-	    t->hide_transaction) {
+	if (ret == 0 && visibility_changes && t->hide_transaction) {
 		mail_index_view_add_synced_transaction(view, file->hdr.file_seq,
 						       append_offset);
 	}



More information about the dovecot-cvs mailing list