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