dovecot: Changed record buffers to arrays.

dovecot at dovecot.org dovecot at dovecot.org
Wed Jul 4 04:48:24 EEST 2007


details:   http://hg.dovecot.org/dovecot/rev/989abd5017a4
changeset: 5890:989abd5017a4
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Jul 04 04:47:28 2007 +0300
description:
Changed record buffers to arrays.

diffstat:

1 file changed, 63 insertions(+), 82 deletions(-)
src/lib-storage/index/maildir/maildir-uidlist.c |  145 +++++++++--------------

diffs (truncated from 332 to 300 lines):

diff -r 8117a34abdbd -r 989abd5017a4 src/lib-storage/index/maildir/maildir-uidlist.c
--- a/src/lib-storage/index/maildir/maildir-uidlist.c	Wed Jul 04 04:47:00 2007 +0300
+++ b/src/lib-storage/index/maildir/maildir-uidlist.c	Wed Jul 04 04:47:28 2007 +0300
@@ -2,7 +2,7 @@
 
 #include "lib.h"
 #include "ioloop.h"
-#include "buffer.h"
+#include "array.h"
 #include "hash.h"
 #include "istream.h"
 #include "str.h"
@@ -34,6 +34,7 @@ struct maildir_uidlist_rec {
 	uint32_t flags;
 	char *filename;
 };
+ARRAY_DEFINE_TYPE(maildir_uidlist_rec_p, struct maildir_uidlist_rec *);
 
 struct maildir_uidlist {
 	struct maildir_mailbox *mbox;
@@ -45,7 +46,7 @@ struct maildir_uidlist {
 	time_t last_mtime;
 
 	pool_t record_pool;
-	buffer_t *record_buf;
+	ARRAY_TYPE(maildir_uidlist_rec_p) records;
 	struct hash_table *files;
 	struct dotlock_settings dotlock_settings;
 	struct dotlock *dotlock;
@@ -66,7 +67,7 @@ struct maildir_uidlist_sync_ctx {
 	enum maildir_uidlist_sync_flags sync_flags;
 
 	pool_t record_pool;
-	buffer_t *record_buf;
+	ARRAY_TYPE(maildir_uidlist_rec_p) records;
 	struct hash_table *files;
 
 	unsigned int first_new_pos;
@@ -78,7 +79,7 @@ struct maildir_uidlist_sync_ctx {
 };
 
 struct maildir_uidlist_iter_ctx {
-	const struct maildir_uidlist_rec *const *next, *const *end;
+	struct maildir_uidlist_rec *const *next, *const *end;
 };
 
 static int maildir_uidlist_lock_timeout(struct maildir_uidlist *uidlist,
@@ -182,7 +183,7 @@ struct maildir_uidlist *maildir_uidlist_
 	uidlist->fname =
 		i_strconcat(mbox->control_dir, "/" MAILDIR_UIDLIST_NAME, NULL);
 	uidlist->lock_fd = -1;
-	uidlist->record_buf = buffer_create_dynamic(default_pool, 512);
+	i_array_init(&uidlist->records, 128);
 	uidlist->files = hash_create(default_pool, default_pool, 4096,
 				     maildir_hash, maildir_cmp);
 	uidlist->next_uid = 1;
@@ -205,7 +206,7 @@ void maildir_uidlist_deinit(struct maild
 	if (uidlist->record_pool != NULL)
 		pool_unref(uidlist->record_pool);
 
-	buffer_free(uidlist->record_buf);
+	array_free(&uidlist->records);
 	i_free(uidlist->fname);
 	i_free(uidlist);
 }
@@ -277,7 +278,7 @@ static int maildir_uidlist_next(struct m
 	rec->flags = MAILDIR_UIDLIST_REC_FLAG_NONSYNCED;
 	rec->filename = p_strdup(uidlist->record_pool, line);
 	hash_insert(uidlist->files, rec->filename, rec);
-	buffer_append(uidlist->record_buf, &rec, sizeof(rec));
+	array_append(&uidlist->records, &rec, 1);
 	return 1;
 }
 
@@ -430,9 +431,8 @@ maildir_uidlist_lookup_rec(struct maildi
 maildir_uidlist_lookup_rec(struct maildir_uidlist *uidlist, uint32_t uid,
 			   unsigned int *idx_r)
 {
-	const struct maildir_uidlist_rec *const *rec_p;
+	struct maildir_uidlist_rec *const *recs;
 	unsigned int idx, left_idx, right_idx;
-	size_t size;
 
 	if (!uidlist->initial_read) {
 		/* first time we need to read uidlist */
@@ -440,23 +440,18 @@ maildir_uidlist_lookup_rec(struct maildi
 			return NULL;
 	}
 
-	rec_p = buffer_get_data(uidlist->record_buf, &size);
-	size /= sizeof(*rec_p);
-
-	idx = 0;
-	left_idx = 0;
-	right_idx = size;
-
+	idx = left_idx = 0;
+	recs = array_get(&uidlist->records, &right_idx);
 	while (left_idx < right_idx) {
 		idx = (left_idx + right_idx) / 2;
 
-		if (rec_p[idx]->uid < uid)
+		if (recs[idx]->uid < uid)
 			left_idx = idx+1;
-		else if (rec_p[idx]->uid > uid)
+		else if (recs[idx]->uid > uid)
 			right_idx = idx;
 		else {
 			*idx_r = idx;
-			return rec_p[idx];
+			return recs[idx];
 		}
 	}
 
@@ -508,10 +503,9 @@ bool maildir_uidlist_is_recent(struct ma
 
 uint32_t maildir_uidlist_get_recent_count(struct maildir_uidlist *uidlist)
 {
-	const struct maildir_uidlist_rec *const *rec_p;
-	unsigned int idx;
-	size_t size;
-	uint32_t count;
+	struct maildir_uidlist_rec *const *recs;
+	unsigned int idx, count;
+	uint32_t recent_count;
 
 	if (!uidlist->initial_sync) {
 		/* we haven't synced yet, trust index */
@@ -527,15 +521,13 @@ uint32_t maildir_uidlist_get_recent_coun
 	if (uidlist->first_recent_uid == 0)
 		return 0;
 
-	rec_p = buffer_get_data(uidlist->record_buf, &size);
-	size /= sizeof(*rec_p);
-
+	recs = array_get(&uidlist->records, &count);
 	maildir_uidlist_lookup_rec(uidlist, uidlist->first_recent_uid, &idx);
-	for (count = 0; idx < size; idx++) {
-		if ((rec_p[idx]->flags & MAILDIR_UIDLIST_REC_FLAG_RECENT) != 0)
-			count++;
-	}
-	return count;
+	for (recent_count = 0; idx < count; idx++) {
+		if ((recs[idx]->flags & MAILDIR_UIDLIST_REC_FLAG_RECENT) != 0)
+			recent_count++;
+	}
+	return recent_count;
 }
 
 uint32_t maildir_uidlist_get_uid_validity(struct maildir_uidlist *uidlist)
@@ -686,18 +678,16 @@ static void maildir_uidlist_mark_all(str
 static void maildir_uidlist_mark_all(struct maildir_uidlist *uidlist,
 				     bool nonsynced)
 {
-	struct maildir_uidlist_rec **rec_p;
-	size_t i, size;
-
-	rec_p = buffer_get_modifiable_data(uidlist->record_buf, &size);
-	size /= sizeof(*rec_p);
-
+	struct maildir_uidlist_rec **recs;
+	unsigned int i, count;
+
+	recs = array_get_modifiable(&uidlist->records, &count);
 	if (nonsynced) {
-		for (i = 0; i < size; i++)
-			rec_p[i]->flags |= MAILDIR_UIDLIST_REC_FLAG_NONSYNCED;
+		for (i = 0; i < count; i++)
+			recs[i]->flags |= MAILDIR_UIDLIST_REC_FLAG_NONSYNCED;
 	} else {
-		for (i = 0; i < size; i++)
-			rec_p[i]->flags &= ~MAILDIR_UIDLIST_REC_FLAG_NONSYNCED;
+		for (i = 0; i < count; i++)
+			recs[i]->flags &= ~MAILDIR_UIDLIST_REC_FLAG_NONSYNCED;
 	}
 }
 
@@ -706,7 +696,6 @@ int maildir_uidlist_sync_init(struct mai
 			      struct maildir_uidlist_sync_ctx **sync_ctx_r)
 {
 	struct maildir_uidlist_sync_ctx *ctx;
-	size_t size;
 	int ret;
 
 	if ((ret = maildir_uidlist_lock(uidlist)) <= 0)
@@ -728,8 +717,7 @@ int maildir_uidlist_sync_init(struct mai
 	ctx->files = hash_create(default_pool, ctx->record_pool, 4096,
 				 maildir_hash, maildir_cmp);
 
-	size = buffer_get_used_size(uidlist->record_buf);
-	ctx->record_buf = buffer_create_dynamic(default_pool, size);
+	i_array_init(&ctx->records, array_count(&uidlist->records));
 	return 1;
 }
 
@@ -746,11 +734,8 @@ maildir_uidlist_sync_next_partial(struct
 	i_assert(rec != NULL || UIDLIST_IS_LOCKED(uidlist));
 
 	if (rec == NULL) {
-		if (ctx->new_files_count == 0) {
-			ctx->first_new_pos =
-				buffer_get_used_size(uidlist->record_buf) /
-				sizeof(rec);
-		}
+		if (ctx->new_files_count == 0)
+			ctx->first_new_pos = array_count(&uidlist->records);
 		ctx->new_files_count++;
 
 		if (uidlist->record_pool == NULL) {
@@ -763,7 +748,7 @@ maildir_uidlist_sync_next_partial(struct
 		rec = p_new(uidlist->record_pool,
 			    struct maildir_uidlist_rec, 1);
 		rec->uid = (uint32_t)-1;
-		buffer_append(uidlist->record_buf, &rec, sizeof(rec));
+		array_append(&uidlist->records, &rec, 1);
 	}
 
 	if ((flags & MAILDIR_UIDLIST_REC_FLAG_RECENT) != 0 &&
@@ -833,7 +818,7 @@ int maildir_uidlist_sync_next(struct mai
 			ctx->new_files_count++;
 		}
 
-		buffer_append(ctx->record_buf, &rec, sizeof(rec));
+		array_append(&ctx->records, &rec, 1);
 	}
 
 	if ((flags & MAILDIR_UIDLIST_REC_FLAG_RECENT) != 0 &&
@@ -890,29 +875,27 @@ static void maildir_uidlist_assign_uids(
 static void maildir_uidlist_assign_uids(struct maildir_uidlist_sync_ctx *ctx,
 					unsigned int first_new_pos)
 {
-	struct maildir_uidlist_rec **rec_p;
-	unsigned int dest;
-	size_t size;
+	struct maildir_uidlist_rec **recs;
+	unsigned int dest, count;
 
 	i_assert(UIDLIST_IS_LOCKED(ctx->uidlist));
 
-	rec_p = buffer_get_modifiable_data(ctx->uidlist->record_buf, &size);
-	size /= sizeof(*rec_p);
+	recs = array_get_modifiable(&ctx->uidlist->records, &count);
 
 	/* sort new files and assign UIDs for them */
 	if ((ctx->sync_flags & MAILDIR_UIDLIST_SYNC_ORDERED) == 0) {
-		qsort(rec_p + first_new_pos, size - first_new_pos,
-		      sizeof(*rec_p), maildir_time_cmp);
-	}
-	for (dest = first_new_pos; dest < size; dest++) {
-		i_assert(rec_p[dest]->uid == (uint32_t)-1);
-		rec_p[dest]->uid = ctx->uidlist->next_uid++;
-		rec_p[dest]->flags &= ~MAILDIR_UIDLIST_REC_FLAG_MOVED;
-
-		if ((rec_p[dest]->flags &
+		qsort(recs + first_new_pos, count - first_new_pos,
+		      sizeof(*recs), maildir_time_cmp);
+	}
+	for (dest = first_new_pos; dest < count; dest++) {
+		i_assert(recs[dest]->uid == (uint32_t)-1);
+		recs[dest]->uid = ctx->uidlist->next_uid++;
+		recs[dest]->flags &= ~MAILDIR_UIDLIST_REC_FLAG_MOVED;
+
+		if ((recs[dest]->flags &
 		     MAILDIR_UIDLIST_REC_FLAG_RECENT) != 0) {
 			maildir_uidlist_mark_recent(ctx->uidlist,
-						    rec_p[dest]->uid);
+						    recs[dest]->uid);
 		}
 	}
 
@@ -930,17 +913,16 @@ static void maildir_uidlist_swap(struct 
 static void maildir_uidlist_swap(struct maildir_uidlist_sync_ctx *ctx)
 {
 	struct maildir_uidlist *uidlist = ctx->uidlist;
-	struct maildir_uidlist_rec **rec_p;
-	size_t size;
+	struct maildir_uidlist_rec **recs;
+	unsigned int count;
 
 	/* buffer is unsorted, sort it by UID */
-	rec_p = buffer_get_modifiable_data(ctx->record_buf, &size);
-	size /= sizeof(*rec_p);
-	qsort(rec_p, size, sizeof(*rec_p), maildir_uid_cmp);
-
-	buffer_free(uidlist->record_buf);
-	uidlist->record_buf = ctx->record_buf;
-	ctx->record_buf = NULL;
+	recs = array_get_modifiable(&ctx->records, &count);
+	qsort(recs, count, sizeof(*recs), maildir_uid_cmp);
+
+	array_free(&uidlist->records);
+	uidlist->records = ctx->records;
+	ctx->records.arr.buffer = NULL;
 
 	hash_destroy(uidlist->files);
 	uidlist->files = ctx->files;
@@ -952,7 +934,7 @@ static void maildir_uidlist_swap(struct 
 	ctx->record_pool = NULL;
 
 	if (ctx->new_files_count != 0)


More information about the dovecot-cvs mailing list