commit 677accfd84c9b55416a886f6e5240f33c397eea8
parent 990c8a14046153f8ebc2036a200fa6680d18d6ad
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date: Fri, 10 Mar 2017 17:40:54 +0100
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.
Diffstat:
M | src/sync.c | | | 70 | ++++++++++++++++++++++++---------------------------------------------- |
1 file changed, 24 insertions(+), 46 deletions(-)
diff --git 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) */
+ }
+ }
}
}
}