Discussion:
imap-2007f performance patch
Deniss
2012-07-13 12:21:00 UTC
Permalink
hello here !

we run c-client with php and discovered that on fetching overview by UID
sequence c-client does "UID FETCH uid UID" request to server for each
UID in sequence to resolve UID to sequence index which is used
internally in c-client.

so call of imap_fetch_overview($mbox,"1:100",FT_UID); from php results
to c-client will do 100 requests to imap server to get sequence number
for each message in sequence.

But same may be done by one request listing all UID: "UID FETCH
uid1,uid2,uid3 UID"


the patch is used to pre-cache sequence indexes in one request. That
bust performance a lot on huge mailboxes.

diff -ur imap-2007f.orig/src/c-client/imap4r1.c
imap-2007f/src/c-client/imap4r1.c
--- imap-2007f.orig/src/c-client/imap4r1.c 2011-07-23
03:20:18.000000000 +0300
+++ imap-2007f/src/c-client/imap4r1.c 2012-07-11 13:22:26.000000000 +0300
@@ -180,6 +180,7 @@
long flags);
unsigned long imap_uid (MAILSTREAM *stream,unsigned long msgno);
unsigned long imap_msgno (MAILSTREAM *stream,unsigned long uid);
+void imap_msgnos (MAILSTREAM *stream, unsigned char *uids);
void imap_flag (MAILSTREAM *stream,char *sequence,char *flag,long flags);
long imap_search (MAILSTREAM *stream,char *charset,SEARCHPGM *pgm,long
flags);
unsigned long *imap_sort (MAILSTREAM *stream,char *charset,SEARCHPGM *spg,
@@ -294,6 +295,7 @@
imap_msgdata, /* fetch partial message */
imap_uid, /* unique identifier */
imap_msgno, /* message number */
+ imap_msgnos, /* message numbers */
imap_flag, /* modify flags */
NIL, /* per-message modify flags */
imap_search, /* search for message based on criteria */
@@ -1947,6 +1949,26 @@
}
return 0; /* didn't find the UID anywhere */
}
+
+/*
+* MR, this is dummy function just to fill cache
+* does not care what it returns, if result is good, then cache will be
filled
+*/
+void imap_msgnos (MAILSTREAM *stream, unsigned char *uids)
+{
+ IMAPPARSEDREPLY *reply;
+ IMAPARG *args[3],aseq,aatt;
+ char seq[MAILTMPLEN];
+
+ aseq.type = SEQUENCE; aseq.text = (void *) seq;
+ aatt.type = ATOM; aatt.text = (void *) "UID";
+ args[0] = &aseq; args[1] = &aatt; args[2] = NIL;
+ sprintf (seq,"%s",uids);
+ /* send "UID FETCH uid UID" */
+ if (!imap_OK (stream,reply = imap_send (stream,"UID FETCH",args)))
+ mm_log (reply->text,ERROR);
+}
+


/* IMAP modify flags
* Accepts: MAIL stream
diff -ur imap-2007f.orig/src/c-client/mail.c imap-2007f/src/c-client/mail.c
--- imap-2007f.orig/src/c-client/mail.c 2011-07-23 03:20:18.000000000 +0300
+++ imap-2007f/src/c-client/mail.c 2012-07-11 13:28:29.000000000 +0300
@@ -3251,6 +3265,10 @@
{
unsigned long i,j,k,x,y;
for (i = 1; i <= stream->nmsgs; i++) mail_elt (stream,i)->sequence = NIL;
+
+ //MR: this issues sequence lookup mseq and fills cache
+ imap_msgnos (stream, sequence);
+
while (sequence && *sequence){/* while there is something to parse */
if (*sequence == '*') { /* maximum message */
i = stream->nmsgs ? mail_uid (stream,stream->nmsgs) :
stream->uid_last;
diff -ur imap-2007f.orig/src/c-client/mail.h imap-2007f/src/c-client/mail.h
--- imap-2007f.orig/src/c-client/mail.h 2011-07-23 03:20:18.000000000 +0300
+++ imap-2007f/src/c-client/mail.h 2012-07-11 13:26:16.000000000 +0300
@@ -1476,6 +1476,8 @@
unsigned long (*uid) (MAILSTREAM *stream,unsigned long msgno);
/* return message number from UID */
unsigned long (*msgno) (MAILSTREAM *stream,unsigned long uid);
+ /* fill cache from UID list */
+ void (*msgnos) (MAILSTREAM *stream, unsigned char *sequence);
/* modify flags */
void (*flag) (MAILSTREAM *stream,char *sequence,char *flag,long flags);
/* per-message modify flags */
Deniss
2012-07-23 15:48:46 UTC
Permalink
new version that does not suffer from buffer overflow
Post by Deniss
hello here !
Loading...