From 677accfd84c9b55416a886f6e5240f33c397eea8 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 10 Mar 2017 17:40:54 +0100 Subject: [PATCH] streamline syncing of old entries the order of the conditionals was purely historical (pre 4ec56f8cf, anno 2005) and hard to follow, as were the comments. --- src/sync.c | 70 +++++++++++++++++++----------------------------------- 1 file changed, 24 insertions(+), 46 deletions(-) diff --git a/src/sync.c b/src/sync.c index 7919981..78f30e9 100644 --- a/src/sync.c +++ b/src/sync.c @@ -141,34 +141,6 @@ typedef struct sync_rec { char tuid[TUIDL]; } sync_rec_t; - -/* cases: - a) both non-null - b) only master null - b.1) uid[M] 0 - b.2) uid[M] -1 - b.3) master not scanned - b.4) master gone - c) only slave null - c.1) uid[S] 0 - c.2) uid[S] -1 - c.3) slave not scanned - c.4) slave gone - d) both null - d.1) both gone - d.2) uid[M] 0, slave not scanned - d.3) uid[M] -1, slave not scanned - d.4) master gone, slave not scanned - d.5) uid[M] 0, slave gone - d.6) uid[M] -1, slave gone - d.7) uid[S] 0, master not scanned - d.8) uid[S] -1, master not scanned - d.9) slave gone, master not scanned - d.10) uid[S] 0, master gone - d.11) uid[S] -1, master gone - impossible cases: both uid[M] & uid[S] 0 or -1, both not scanned -*/ - typedef struct { int t[2]; void (*cb)( int sts, void *aux ), *aux; @@ -1502,14 +1474,18 @@ box_loaded( int sts, void *aux ) if (srec->status & S_DEAD) continue; debug( "pair (%d,%d)\n", srec->uid[M], srec->uid[S] ); + // no[] means that a message is known to be not there. no[M] = !srec->msg[M] && (svars->ctx[M]->opts & OPEN_OLD); no[S] = !srec->msg[S] && (svars->ctx[S]->opts & OPEN_OLD); if (no[M] && no[S]) { + // It does not matter whether one side was already known to be missing + // (never stored [skipped or failed] or expunged [possibly expired]) - + // now both are missing, so the entry is superfluous. debug( " vanished\n" ); - /* d.1) d.5) d.6) d.10) d.11) */ srec->status = S_DEAD; jFprintf( svars, "- %d %d\n", srec->uid[M], srec->uid[S] ); } else { + // del[] means that a message becomes known to have been expunged. del[M] = no[M] && (srec->uid[M] > 0); del[S] = no[S] && (srec->uid[S] > 0); @@ -1517,12 +1493,17 @@ box_loaded( int sts, void *aux ) srec->aflags[t] = srec->dflags[t] = 0; if (srec->msg[t] && (srec->msg[t]->flags & F_DELETED)) srec->status |= S_DEL(t); - /* excludes (push) c.3) d.2) d.3) d.4) / (pull) b.3) d.7) d.8) d.9) */ - if (!srec->uid[t]) { - /* b.1) / c.1) */ - debug( " no more %s\n", str_ms[t] ); + if (del[t]) { + // The target was newly expunged, so there is nothing to update. + // The deletion is propagated in the opposite iteration. + } else if (srec->uid[t] <= 0) { + // The target was never stored, or was previously expunged, so there + // is nothing to update. + // Note: the opposite UID must be valid, as otherwise the entry would + // have been pruned already. } else if (del[1-t]) { - /* c.4) d.9) / b.4) d.4) */ + // The source was newly expunged, so possibly propagate the deletion. + // The target may be in an unknown state (not fetched). if ((t == M) && (srec->status & (S_EXPIRE|S_EXPIRED))) { /* Don't propagate deletion resulting from expiration. */ debug( " slave expired, orphaning master\n" ); @@ -1539,14 +1520,12 @@ box_loaded( int sts, void *aux ) debug( " not %sing delete\n", str_hl[t] ); } } - } else if (!srec->msg[1-t]) - /* c.1) c.2) d.7) d.8) / b.1) b.2) d.2) d.3) */ - ; - else if (srec->uid[t] < 0) - /* b.2) / c.2) */ - ; /* handled as new messages (sort of) */ - else if (!del[t]) { - /* a) & b.3) / c.3) */ + } else if (!srec->msg[1-t]) { + // We have no source to work with, because it was never stored, + // it was previously expunged, or we did not fetch it. + debug( " no %s\n", str_ms[1-t] ); + } else { + // We have a source. The target may be in an unknown state. if (svars->chan->ops[t] & OP_FLAGS) { sflags = srec->msg[1-t]->flags; if ((t == M) && (srec->status & (S_EXPIRE|S_EXPIRED))) { @@ -1556,15 +1535,14 @@ box_loaded( int sts, void *aux ) } srec->aflags[t] = sflags & ~srec->flags; srec->dflags[t] = ~sflags & srec->flags; - if (DFlags & DEBUG_SYNC) { + if ((DFlags & DEBUG_SYNC) && (srec->aflags[t] || srec->dflags[t])) { char afbuf[16], dfbuf[16]; /* enlarge when support for keywords is added */ make_flags( srec->aflags[t], afbuf ); make_flags( srec->dflags[t], dfbuf ); debug( " %sing flags: +%s -%s\n", str_hl[t], afbuf, dfbuf ); } - } else - debug( " not %sing flags\n", str_hl[t] ); - } /* else b.4) / c.4) */ + } + } } } }