commit f9fe75602e36878d92c8476ba2a3dac524712e1c
Author: Oswald Buddenhagen <o...@users.sf.net>
Date:   Sun Dec 18 21:22:52 2016 +0100

    don't fetch message size unless necessary
    
    when syncing flags but not re-newing non-fetched messages, there is no
    need to query the message size for all messages, as the old ones are
    queried only for their flags.

 src/driver.h      |   11 ++++++---
 src/drv_imap.c    |    9 +++++--
 src/drv_maildir.c |    7 +++--
 src/sync.c        |   46 +++++++++++++++++++++++++++++++++-----------
 4 files changed, 51 insertions(+), 22 deletions(-)

diff --git a/src/driver.h b/src/driver.h
index 42000e8..d9e5f4c 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -74,7 +74,8 @@ typedef struct message {
 #define OPEN_OLD        (1<<0)
 #define OPEN_NEW        (1<<1)
 #define OPEN_FLAGS      (1<<2)
-#define OPEN_SIZE       (1<<3)
+#define OPEN_OLD_SIZE   (1<<3)
+#define OPEN_NEW_SIZE   (1<<4)
 #define OPEN_EXPUNGE    (1<<5)
 #define OPEN_SETFLAGS   (1<<6)
 #define OPEN_APPEND     (1<<7)
@@ -205,9 +206,11 @@ struct driver {
        /* Load the message attributes needed to perform the requested 
operations.
         * Consider only messages with UIDs between minuid and maxuid 
(inclusive)
         * and those named in the excs array (smaller than minuid).
-        * The driver takes ownership of the excs array. Messages below newuid 
do not need
-        * to have the TUID populated even if OPEN_FIND is set. */
-       void (*load_box)( store_t *ctx, int minuid, int maxuid, int newuid, 
int_array_t excs,
+        * The driver takes ownership of the excs array.
+        * Messages starting with newuid need to have the TUID populated when 
OPEN_FIND is set.
+        * Messages up to seenuid need to have the size populated when 
OPEN_OLD_SIZE is set;
+        * likewise messages above seenuid when OPEN_NEW_SIZE is set. */
+       void (*load_box)( store_t *ctx, int minuid, int maxuid, int newuid, int 
seenuid, int_array_t excs,
                          void (*cb)( int sts, void *aux ), void *aux );
 
        /* Fetch the contents and flags of the given message from the current 
mailbox. */
diff --git a/src/drv_imap.c b/src/drv_imap.c
index 1262c9b..88ff50e 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -2352,7 +2352,7 @@ imap_set_range( imap_range_t *ranges, int *nranges, int 
low_flags, int high_flag
 static void imap_submit_load( imap_store_t *, const char *, int, struct 
imap_cmd_refcounted_state * );
 
 static void
-imap_load_box( store_t *gctx, int minuid, int maxuid, int newuid, int_array_t 
excs,
+imap_load_box( store_t *gctx, int minuid, int maxuid, int newuid, int seenuid, 
int_array_t excs,
                void (*cb)( int sts, void *aux ), void *aux )
 {
        imap_store_t *ctx = (imap_store_t *)gctx;
@@ -2380,11 +2380,14 @@ imap_load_box( store_t *gctx, int minuid, int maxuid, 
int newuid, int_array_t ex
                if (maxuid == INT_MAX)
                        maxuid = ctx->gen.uidnext ? ctx->gen.uidnext - 1 : 
0x7fffffff;
                if (maxuid >= minuid) {
-                       imap_range_t ranges[2];
+                       imap_range_t ranges[3];
                        ranges[0].first = minuid;
                        ranges[0].last = maxuid;
-                       ranges[0].flags = shifted_bit( ctx->gen.opts, 
OPEN_SIZE, WantSize);
+                       ranges[0].flags = 0;
                        int nranges = 1;
+                       if (ctx->gen.opts & (OPEN_OLD_SIZE | OPEN_NEW_SIZE))
+                               imap_set_range( ranges, &nranges, shifted_bit( 
ctx->gen.opts, OPEN_OLD_SIZE, WantSize),
+                                                                 shifted_bit( 
ctx->gen.opts, OPEN_NEW_SIZE, WantSize), seenuid );
                        if (ctx->gen.opts & OPEN_FIND)
                                imap_set_range( ranges, &nranges, 0, WantTuids, 
newuid - 1 );
                        for (int r = 0; r < nranges; r++) {
diff --git a/src/drv_maildir.c b/src/drv_maildir.c
index 9c94e4e..64ed069 100644
--- a/src/drv_maildir.c
+++ b/src/drv_maildir.c
@@ -70,7 +70,7 @@ typedef struct maildir_message {
 typedef struct maildir_store {
        store_t gen;
        int uvfd, uvok, nuid, is_inbox, fresh[3];
-       int minuid, maxuid, newuid;
+       int minuid, maxuid, newuid, seenuid;
        int_array_t excs;
        char *trash;
 #ifdef USE_DB
@@ -1048,7 +1048,7 @@ maildir_scan( maildir_store_t *ctx, msg_t_array_alloc_t 
*msglist )
                                free( entry->base );
                                entry->base = nfstrndup( buf + bl + 4, fnl );
                        }
-                       int want_size = (ctx->gen.opts & OPEN_SIZE);
+                       int want_size = (uid > ctx->seenuid) ? (ctx->gen.opts & 
OPEN_NEW_SIZE) : (ctx->gen.opts & OPEN_OLD_SIZE);
                        int want_tuid = ((ctx->gen.opts & OPEN_FIND) && uid >= 
ctx->newuid);
                        if (!want_size && !want_tuid)
                                continue;
@@ -1280,7 +1280,7 @@ maildir_prepare_load_box( store_t *gctx, int opts )
 }
 
 static void
-maildir_load_box( store_t *gctx, int minuid, int maxuid, int newuid, 
int_array_t excs,
+maildir_load_box( store_t *gctx, int minuid, int maxuid, int newuid, int 
seenuid, int_array_t excs,
                   void (*cb)( int sts, void *aux ), void *aux )
 {
        maildir_store_t *ctx = (maildir_store_t *)gctx;
@@ -1291,6 +1291,7 @@ maildir_load_box( store_t *gctx, int minuid, int maxuid, 
int newuid, int_array_t
        ctx->minuid = minuid;
        ctx->maxuid = maxuid;
        ctx->newuid = newuid;
+       ctx->seenuid = seenuid;
        ARRAY_SQUEEZE( &excs );
        ctx->excs = excs;
 
diff --git a/src/sync.c b/src/sync.c
index 0ed73a7..2a61abd 100644
--- a/src/sync.c
+++ b/src/sync.c
@@ -1208,8 +1208,12 @@ box_opened2( sync_vars_t *svars, int t )
                                opts[1-t] |= OPEN_NEW;
                        if (chan->ops[t] & OP_EXPUNGE)
                                opts[1-t] |= OPEN_FLAGS;
-                       if (chan->stores[t]->max_size != INT_MAX)
-                               opts[1-t] |= OPEN_SIZE;
+                       if (chan->stores[t]->max_size != INT_MAX) {
+                               if (chan->ops[t] & OP_RENEW)
+                                       opts[1-t] |= OPEN_OLD_SIZE;
+                               if (chan->ops[t] & OP_NEW)
+                                       opts[1-t] |= OPEN_NEW_SIZE;
+                       }
                }
                if (chan->ops[t] & OP_EXPUNGE) {
                        opts[t] |= OPEN_EXPUNGE;
@@ -1298,28 +1302,46 @@ box_opened2( sync_vars_t *svars, int t )
        sync_deref( svars );
 }
 
+static int
+get_seenuid( sync_vars_t *svars, int t )
+{
+       int seenuid = 0;
+       for (sync_rec_t *srec = svars->srecs; srec; srec = srec->next)
+               if (!(srec->status & S_DEAD) && seenuid < srec->uid[t])
+                       seenuid = srec->uid[t];
+       return seenuid;
+}
+
 static void box_loaded( int sts, void *aux );
 
 static void
 load_box( sync_vars_t *svars, int t, int minwuid, int_array_t mexcs )
 {
-       sync_rec_t *srec;
-       int maxwuid;
+       int maxwuid, seenuid;
 
        if (svars->ctx[t]->opts & OPEN_NEW) {
                if (minwuid > svars->maxuid[t] + 1)
                        minwuid = svars->maxuid[t] + 1;
                maxwuid = INT_MAX;
+               if (svars->ctx[t]->opts & OPEN_OLD_SIZE)
+                       seenuid = get_seenuid( svars, t );
+               else
+                       seenuid = 0;
        } else if (svars->ctx[t]->opts & OPEN_OLD) {
-               maxwuid = 0;
-               for (srec = svars->srecs; srec; srec = srec->next)
-                       if (!(srec->status & S_DEAD) && srec->uid[t] > maxwuid)
-                               maxwuid = srec->uid[t];
+               maxwuid = seenuid = get_seenuid( svars, t );
        } else
-               maxwuid = 0;
+               maxwuid = seenuid = 0;
+       if (seenuid < svars->maxuid[t]) {
+               /* We cannot rely on the maxuid, as uni-directional syncing 
does not update it.
+                * But if it is there, use it to avoid a possible gap in the 
fetched range. */
+               seenuid = svars->maxuid[t];
+       }
        info( "Loading %s...\n", str_ms[t] );
-       debug( maxwuid == INT_MAX ? "loading %s [%d,inf]\n" : "loading %s 
[%d,%d]\n", str_ms[t], minwuid, maxwuid );
-       svars->drv[t]->load_box( svars->ctx[t], minwuid, maxwuid, 
svars->newuid[t], mexcs, box_loaded, AUX );
+       if (maxwuid == INT_MAX)
+               debug( "loading %s [%d,inf] (new >= %d, seen <= %d)\n", 
str_ms[t], minwuid, svars->newuid[t], seenuid );
+       else
+               debug( "loading %s [%d,%d] (new >= %d, seen <= %d)\n", 
str_ms[t], minwuid, maxwuid, svars->newuid[t], seenuid );
+       svars->drv[t]->load_box( svars->ctx[t], minwuid, maxwuid, 
svars->newuid[t], seenuid, mexcs, box_loaded, AUX );
 }
 
 typedef struct {
@@ -1384,7 +1406,7 @@ box_loaded( int sts, void *aux )
                uid = tmsg->uid;
                if (DFlags & DEBUG_SYNC) {
                        make_flags( tmsg->flags, fbuf );
-                       printf( svars->ctx[t]->opts & OPEN_SIZE ? "  message 
%5d, %-4s, %6lu: " : "  message %5d, %-4s: ", uid, fbuf, tmsg->size );
+                       printf( tmsg->size ? "  message %5d, %-4s, %6lu: " : "  
message %5d, %-4s: ", uid, fbuf, tmsg->size );
                }
                idx = (uint)((uint)uid * 1103515245U) % hashsz;
                while (srecmap[idx].uid) {

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
isync-devel mailing list
isync-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to