[dovecot-cvs] dovecot/src/imap imap-thread.c,1.29,1.30
tss at dovecot.org
tss at dovecot.org
Sun Nov 26 15:20:14 UTC 2006
- Previous message: [dovecot-cvs] dovecot/src/pop3 client.c, 1.68, 1.69 common.h, 1.13, 1.14 main.c, 1.51, 1.52
- Next message: [dovecot-cvs] dovecot/src/lib-index mail-hash.c, 1.24, 1.25 mail-hash.h, 1.10, 1.11
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /var/lib/cvs/dovecot/src/imap
In directory talvi:/tmp/cvs-serv13569/imap
Modified Files:
imap-thread.c
Log Message:
Resize the hash when needed. Also other fixes and cleanups.
Index: imap-thread.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/imap/imap-thread.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- imap-thread.c 25 Nov 2006 22:17:40 -0000 1.29
+++ imap-thread.c 26 Nov 2006 15:20:12 -0000 1.30
@@ -202,6 +202,12 @@
pool_unref(ctx->msgid_pool);
}
+static uint32_t crc32_str_nonzero(const char *str)
+{
+ uint32_t value = crc32_str(str);
+ return value == 0 ? 1 : value;
+}
+
static int
mail_thread_rec_idx(struct thread_context *ctx, uint32_t idx,
const struct mail_thread_rec **rec_r)
@@ -217,7 +223,7 @@
return 0;
}
-static unsigned int mail_thread_rec_hash(const void *key)
+static unsigned int mail_thread_hash_key(const void *key)
{
const struct msgid_rec *key_rec = key;
@@ -241,7 +247,7 @@
msgids = mail_get_first_header(ctx->tmp_mail, HDR_IN_REPLY_TO);
msgid = msgids == NULL ? NULL : message_id_get_next(&msgids);
if (msgid != NULL) {
- if (crc32_str(msgid) == msgid_crc32)
+ if (crc32_str_nonzero(msgid) == msgid_crc32)
found_msgid = msgid;
}
@@ -252,7 +258,7 @@
}
while ((msgid = message_id_get_next(&msgids)) != NULL) {
- if (crc32_str(msgid) == msgid_crc32) {
+ if (crc32_str_nonzero(msgid) == msgid_crc32) {
if (found_msgid != NULL) {
/* hash collisions, we can't figure this out */
return -1;
@@ -284,6 +290,12 @@
/* each non-dummy child must have a valid In-Reply-To or
References header pointing to the parent, otherwise it
wouldn't be our child */
+ if (parent_rec->msgid_crc32 == 0) {
+ mail_hash_set_corrupted(ctx->msgid_hash,
+ "msgid_crc32=0 node has children");
+ return NULL;
+ }
+
if (mail_thread_find_child_msgid(ctx, child_rec->rec.uid,
parent_rec->msgid_crc32,
&msgid) == 0)
@@ -324,8 +336,8 @@
return *p;
}
-static bool mail_thread_rec_msgid_cmp(const void *key, const void *data,
- void *context)
+static bool mail_thread_hash_cmp(const void *key, const void *data,
+ void *context)
{
struct imap_thread_mailbox *tbox = context;
struct thread_context *ctx = tbox->ctx;
@@ -350,6 +362,13 @@
return strcmp(msgid, key_rec->msgid) == 0;
}
+static unsigned int mail_thread_hash_rec(const void *p)
+{
+ const struct mail_thread_rec *rec = p;
+
+ return rec->msgid_crc32;
+}
+
static int
imap_thread_context_init(struct imap_thread_mailbox *tbox,
struct client *client, const char *charset,
@@ -364,6 +383,15 @@
STATUS_MESSAGES | STATUS_UIDNEXT, &status) < 0)
return -1;
+ if (search_args->type != SEARCH_ALL ||
+ search_args->next != NULL) {
+ /* each search condition requires their own separate thread
+ index. for now we don't bother to support anything else than
+ "search all" threading, since that's what pretty much all
+ the clients do anyway. */
+ ctx->msgid_hash = NULL;
+ }
+
if (ctx->msgid_hash != NULL) {
if (mail_hash_lock(ctx->msgid_hash) <= 0)
ctx->msgid_hash = NULL;
@@ -380,36 +408,34 @@
ctx->msgid_hash = NULL;
} else {
/* rebuild */
- if (mail_hash_reset(ctx->msgid_hash) < 0) {
- mail_hash_unlock(ctx->msgid_hash);
+ if (mail_hash_reset(ctx->msgid_hash, 0) < 0)
ctx->msgid_hash = NULL;
- }
}
- } else if (search_args->next == NULL &&
- search_args->type == SEARCH_ALL) {
- /* threading everything. this is the only case we're trying
- to optimize. */
- if (hdr->last_uid != 0) {
- /* messages already exist in the hash. add only the
- new messages in there. */
- if (mailbox_get_uids(client->mailbox, 1, hdr->last_uid,
- &ctx->seqset.seq1,
- &ctx->seqset.seq2) < 0)
- return -1;
+ } else if (hdr->last_uid != 0) {
+ /* non-empty hash. add only the new messages in there. */
+ if (mailbox_get_uids(client->mailbox, 1, hdr->last_uid,
+ &ctx->seqset.seq1,
+ &ctx->seqset.seq2) < 0) {
+ mail_hash_unlock(ctx->msgid_hash);
+ return -1;
+ }
- if (ctx->seqset.seq2 != hdr->message_count) {
- /* some messages have been expunged.
- have to rebuild. */
- if (mail_hash_reset(ctx->msgid_hash) < 0) {
- mail_hash_unlock(ctx->msgid_hash);
- ctx->msgid_hash = NULL;
- }
- } else {
- ctx->tmp_search_arg.type = SEARCH_SEQSET;
- ctx->tmp_search_arg.value.seqset = &ctx->seqset;
- ctx->tmp_search_arg.not = TRUE;
- search_args = &ctx->tmp_search_arg;
- }
+ if (ctx->seqset.seq2 != hdr->message_count) {
+ /* some messages have been expunged. have to rebuild. */
+ if (mail_hash_reset(ctx->msgid_hash, 0) < 0)
+ ctx->msgid_hash = NULL;
+ } else {
+ /* after all these checks, this is the only case we
+ can actually optimize. */
+ ctx->tmp_search_arg.type = SEARCH_SEQSET;
+ ctx->tmp_search_arg.value.seqset = &ctx->seqset;
+ ctx->tmp_search_arg.not = TRUE;
+ search_args = &ctx->tmp_search_arg;
+
+ if (mail_hash_resize_if_needed(ctx->msgid_hash,
+ status.messages -
+ hdr->message_count) < 0)
+ ctx->msgid_hash = NULL;
}
}
@@ -422,9 +448,10 @@
mail_hash_open(ibox->index, ".thread",
MAIL_HASH_OPEN_FLAG_CREATE |
MAIL_HASH_OPEN_FLAG_IN_MEMORY,
- sizeof(struct mail_thread_rec),
- mail_thread_rec_hash,
- mail_thread_rec_msgid_cmp,
+ sizeof(struct mail_thread_rec), 0,
+ mail_thread_hash_key,
+ mail_thread_hash_rec,
+ mail_thread_hash_cmp,
tbox);
}
@@ -436,6 +463,8 @@
ctx->box = client->mailbox;
ctx->output = client->output;
+ /* at this point the hash is either locked or we're using in-memory
+ hash where it doesn't matter */
hdr = mail_hash_get_header(ctx->msgid_hash);
count = client->messages_count < hdr->record_count ? 0 :
client->messages_count - hdr->record_count;
@@ -571,7 +600,7 @@
mail_thread_rec_get_msgid(ctx, rec, idx);
if (key.msgid == NULL)
return -1;
- key.msgid_crc32 = crc32_str(key.msgid);
+ key.msgid_crc32 = crc32_str_nonzero(key.msgid);
if (mail_hash_remove_idx(ctx->msgid_hash, idx, &key) < 0) {
ctx->failed = TRUE;
@@ -782,7 +811,7 @@
memset(&rec, 0, sizeof(rec));
rec.rec.uid = uid;
- rec.msgid_crc32 = msgid == NULL ? 0 : crc32_str(msgid);
+ rec.msgid_crc32 = msgid == NULL ? 0 : crc32_str_nonzero(msgid);
rec.refcount = 1;
rec.sent_date = sent_date;
@@ -842,6 +871,7 @@
uint32_t orig_idx = idx;
orig_rec = *recp;
+ rec.msgid_crc32 = 0;
if (mail_hash_insert(ctx->msgid_hash, NULL, &rec, &idx) < 0) {
ctx->failed = TRUE;
return -1;
@@ -975,7 +1005,7 @@
int ret;
key.msgid = msgid;
- key.msgid_crc32 = crc32_str(msgid);
+ key.msgid_crc32 = crc32_str_nonzero(msgid);
ret = mail_hash_lookup(ctx->msgid_hash, &key, &value, idx_r);
if (ret < 0 || ctx->failed) {
@@ -1816,7 +1846,7 @@
key_r->msgid = message_id_get_next(&message_id);
if (key_r->msgid == NULL)
return 0;
- key_r->msgid_crc32 = crc32_str(key_r->msgid);
+ key_r->msgid_crc32 = crc32_str_nonzero(key_r->msgid);
if (mail_hash_lookup(ctx->msgid_hash, key_r, &value, idx_r) <= 0)
return -1;
@@ -1851,7 +1881,7 @@
references = t_strdup(references);
do {
key.msgid = msgid;
- key.msgid_crc32 = crc32_str(msgid);
+ key.msgid_crc32 = crc32_str_nonzero(msgid);
ctx->cmp_match_count = 0;
ctx->cmp_last_idx = 0;
@@ -2005,9 +2035,11 @@
tbox->msgid_hash =
mail_hash_open(ibox->index, ".thread", create ?
MAIL_HASH_OPEN_FLAG_CREATE : 0,
- sizeof(struct mail_thread_rec),
- mail_thread_rec_hash,
- mail_thread_rec_msgid_cmp, tbox);
+ sizeof(struct mail_thread_rec), 0,
+ mail_thread_hash_key,
+ mail_thread_hash_rec,
+ mail_thread_hash_cmp,
+ tbox);
if (tbox->msgid_hash == NULL)
return;
- Previous message: [dovecot-cvs] dovecot/src/pop3 client.c, 1.68, 1.69 common.h, 1.13, 1.14 main.c, 1.51, 1.52
- Next message: [dovecot-cvs] dovecot/src/lib-index mail-hash.c, 1.24, 1.25 mail-hash.h, 1.10, 1.11
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list