]> granicus.if.org Git - neomutt/commitdiff
Create a uid hash for imap. (see #3905)
authorKevin McCarthy <kevin@8t8.us>
Fri, 6 Jan 2017 22:23:28 +0000 (14:23 -0800)
committerKevin McCarthy <kevin@8t8.us>
Fri, 6 Jan 2017 22:23:28 +0000 (14:23 -0800)
This hash will allow for more efficient UID SEARCH processing,
replacing a linear scan with a hash lookup.

imap/imap.c
imap/imap_private.h
imap/message.c

index 89bbdb848a08dc91ef29a96240295dae47300ee8..36f94aa366d3206730b2c712fad5c5a0170c9cdd 100644 (file)
@@ -280,6 +280,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);
     }
   }
@@ -1392,6 +1394,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++)
   {
index 67fea27e4d9e534bef0c0c33fe93d45117f89544..4baa266039b6d4d402efd33f04a0d7c617c72f04 100644 (file)
@@ -214,6 +214,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;
index 5ce585868f716b9e987aaa79c29182f372f6cff1..61672efa414c6c3c83c9a41e56e1c00754f9f66a 100644 (file)
@@ -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;