From: Kevin McCarthy Date: Fri, 6 Jan 2017 22:23:28 +0000 (-0800) Subject: Create a uid hash for imap. (see #3905) X-Git-Tag: neomutt-20170225~33^2~20 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8fe673fc8bf0f5fbf4ac3149ee46461641cb5d4b;p=neomutt Create a uid hash for imap. (see #3905) This hash will allow for more efficient UID SEARCH processing, replacing a linear scan with a hash lookup. --- diff --git a/imap/imap.c b/imap/imap.c index abeb3feb5..39b6961b4 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -281,6 +281,8 @@ void imap_expunge_mailbox (IMAP_DATA* idata) FREE (&idata->cache[cacheno].path); } + int_hash_delete (idata->uid_hash, HEADER_DATA(h)->uid, h, NULL); + imap_free_header_data ((IMAP_HEADER_DATA**)&h->data); } } @@ -1391,6 +1393,7 @@ int imap_close_mailbox (CONTEXT* ctx) /* mailbox may not have fully loaded */ if (ctx->hdrs[i] && ctx->hdrs[i]->data) imap_free_header_data ((IMAP_HEADER_DATA**)&(ctx->hdrs[i]->data)); + hash_destroy (&idata->uid_hash, NULL); for (i = 0; i < IMAP_CACHE_LEN; i++) { diff --git a/imap/imap_private.h b/imap/imap_private.h index 9f5d6d50e..b7d6d145a 100644 --- a/imap/imap_private.h +++ b/imap/imap_private.h @@ -215,6 +215,7 @@ typedef struct unsigned char reopen; unsigned int newMailCount; IMAP_CACHE cache[IMAP_CACHE_LEN]; + HASH *uid_hash; unsigned int uid_validity; unsigned int uidnext; body_cache_t *bcache; diff --git a/imap/message.c b/imap/message.c index 528bc8abf..f912dcc72 100644 --- a/imap/message.c +++ b/imap/message.c @@ -52,6 +52,23 @@ static int msg_fetch_header (CONTEXT* ctx, IMAP_HEADER* h, char* buf, static int msg_parse_fetch (IMAP_HEADER* h, char* s); static char* msg_parse_flags (IMAP_HEADER* h, char* s); +static void imap_update_context (IMAP_DATA *idata, int oldmsgcount) +{ + CONTEXT *ctx; + HEADER *h; + int msgno; + + ctx = idata->ctx; + if (!idata->uid_hash) + idata->uid_hash = int_hash_create (MAX (6 * ctx->msgcount / 5, 30)); + + for (msgno = oldmsgcount; msgno < ctx->msgcount; msgno++) + { + h = ctx->hdrs[msgno]; + int_hash_insert (idata->uid_hash, HEADER_DATA(h)->uid, h, 0); + } +} + /* imap_read_headers: * Changed to read many headers instead of just one. It will return the * msgno of the last message read. It will return a value other than @@ -377,6 +394,7 @@ int imap_read_headers (IMAP_DATA* idata, int msgbegin, int msgend) { mx_alloc_memory(ctx); mx_update_context (ctx, ctx->msgcount - oldmsgcount); + imap_update_context (idata, oldmsgcount); } idata->reopen |= IMAP_REOPEN_ALLOW;