]> 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)
committerRichard Russon <rich@flatcap.org>
Fri, 10 Feb 2017 03:32:55 +0000 (03:32 +0000)
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 abeb3feb58697b278f95fd1831531e3b51e4671e..39b6961b4db164afe6049f5af006e82af693447b 100644 (file)
@@ -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++)
   {
index 9f5d6d50e5da5d639004bdb7318102508be4ebff..b7d6d145a7efce7e63ee332549cf7a739ef13a4e 100644 (file)
@@ -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;
index 528bc8abfc1e752aee7d226e3758e2d61dcc04b2..f912dcc722268885def7821106a236ef9e54a7b3 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;