You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2022/03/22 02:03:43 UTC
[james-project] 14/25: JAMES-3722 Fix for IMAP SELECT QRESYNC known sequences application
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit e33ef693b603cc674e177fb5f0f59493129c5d7b
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue Mar 8 14:54:15 2022 +0700
JAMES-3722 Fix for IMAP SELECT QRESYNC known sequences application
Known sequence sets are buggy and never restrict vanished replies
Known sequence sets are a way to restrict the scope of vanished
responses for servers not storing deletion sequences.
Applying correctly the known sequence trick will dramatically reduce
the amount of 'VANISHED' notifications sent in a real world scenario,
saving network, bandwidth and processing time.
---
.../imap/processor/AbstractSelectionProcessor.java | 82 ++++++++--------------
.../james/imapserver/netty/IMAPServerTest.java | 7 --
2 files changed, 28 insertions(+), 61 deletions(-)
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java
index 5dfa2dc..0fcb04c 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java
@@ -21,7 +21,9 @@ package org.apache.james.imap.processor;
import java.util.ArrayList;
import java.util.List;
+import java.util.stream.IntStream;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.james.events.EventBus;
import org.apache.james.imap.api.ImapConstants;
import org.apache.james.imap.api.ImapMessage;
@@ -62,6 +64,8 @@ import org.slf4j.LoggerFactory;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
+import io.vavr.Tuple;
+
abstract class AbstractSelectionProcessor<R extends AbstractMailboxSelectionRequest> extends AbstractMailboxProcessor<R> implements PermitEnableCapabilityProcessor {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSelectionProcessor.class);
private static final List<Capability> CAPS = ImmutableList.of(ImapConstants.SUPPORTS_QRESYNC, ImapConstants.SUPPORTS_CONDSTORE);
@@ -259,63 +263,33 @@ abstract class AbstractSelectionProcessor<R extends AbstractMailboxSelectionRequ
@VisibleForTesting
UidRange[] recomputeUidSet(IdRange[] knownSequences, UidRange[] knownUids, SelectedMailbox selected, UidRange[] uidSet) {
- // Add all uids which are contained in the knownuidsset to a List so we can later access them via the index
- List<MessageUid> knownUidsList = new ArrayList<>();
- for (UidRange range : knownUids) {
- for (MessageUid uid : range) {
- knownUidsList.add(uid);
- }
- }
-
- // loop over the known sequences and check the UID for MSN X again the known UID X
- MessageUid firstUid = MessageUid.MIN_VALUE;
- int index = 0;
- for (IdRange knownSequence : knownSequences) {
- boolean done = false;
- for (Long msn : knownSequence) {
-
- // Check if we have uids left to check against
- if (knownUidsList.size() > index) {
- int msnAsInt = msn.intValue();
- MessageUid knownUid = knownUidsList.get(index);
-
- // Check if the uid match if not we are done here
- done = selected.uid(msnAsInt)
- .filter(selectedUid -> selectedUid.equals(knownUid))
- .isPresent();
- if (done) {
- break;
- } else {
- firstUid = knownUid;
- }
- index += 1;
- } else {
- done = true;
- break;
- }
- }
-
- // We found the first uid to start with
- if (done) {
- firstUid = firstUid.next();
-
- // Ok now its time to filter out the IdRanges which we are not interested in
- List<UidRange> filteredUidSet = new ArrayList<>();
- for (UidRange r : uidSet) {
- if (r.getLowVal().compareTo(firstUid) < 0) {
- if (r.getHighVal().compareTo(firstUid) > 0) {
- filteredUidSet.add(new UidRange(firstUid, r.getHighVal()));
- }
- } else {
- filteredUidSet.add(r);
- }
+ int size = Math.min(knownSequences.length, knownUids.length);
+ MessageUid firstKnownUid = IntStream.range(0, size)
+ .mapToObj(i -> Pair.of(knownSequences[i], knownUids[i]))
+ // We are guarantied of the ranges being individual items
+ .map(pair -> Pair.of(pair.getLeft().getLowVal(), pair.getRight().getLowVal()))
+ // T3(MSN, UID, MATCH)
+ .map(pair -> Tuple.of(pair.getLeft(), pair.getRight(),
+ selected.uid(pair.getLeft().intValue())
+ .filter(selectedUid -> selectedUid.equals(pair.getRight()))
+ .isPresent()))
+ .takeWhile(t3 -> t3._3)
+ .map(t3 -> t3._2)
+ .reduce((t3_1, t3_2) -> t3_2)
+ .orElse(MessageUid.MIN_VALUE);
+
+ // Ok now its time to filter out the IdRanges which we are not interested in
+ List<UidRange> filteredUidSet = new ArrayList<>();
+ for (UidRange r : uidSet) {
+ if (r.getLowVal().compareTo(firstKnownUid) < 0) {
+ if (r.getHighVal().compareTo(firstKnownUid) > 0) {
+ filteredUidSet.add(new UidRange(firstKnownUid, r.getHighVal()));
}
- uidSet = filteredUidSet.toArray(UidRange[]::new);
-
- break;
+ } else {
+ filteredUidSet.add(r);
}
}
- return uidSet;
+ return filteredUidSet.toArray(UidRange[]::new);
}
diff --git a/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/IMAPServerTest.java b/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/IMAPServerTest.java
index aa00b8d..5c0c424 100644
--- a/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/IMAPServerTest.java
+++ b/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/IMAPServerTest.java
@@ -63,7 +63,6 @@ import javax.net.ssl.X509TrustManager;
import org.apache.commons.configuration2.HierarchicalConfiguration;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.configuration2.tree.ImmutableNode;
-import org.apache.commons.io.IOUtils;
import org.apache.commons.net.imap.AuthenticatingIMAPClient;
import org.apache.commons.net.imap.IMAPReply;
import org.apache.commons.net.imap.IMAPSClient;
@@ -1579,9 +1578,6 @@ class IMAPServerTest {
.hasSize(1);
}
- @Disabled("JAMES-3722 Known sequence sets are buggy and never restrict vanished replies." +
- "Known sequence sets are a way to restrict the scope of vanished responses for servers " +
- "not storing deletion sequences.")
@Test
void knownUidSetShouldBeUsedToRestrictVanishedResponses() throws Exception {
inbox.delete(ImmutableList.of(MessageUid.MIN_VALUE), mailboxSession);
@@ -1617,9 +1613,6 @@ class IMAPServerTest {
.hasSize(1);
}
- @Disabled("JAMES-3722 Known sequence sets are buggy and never restrict vanished replies." +
- "Known sequence sets are a way to restrict the scope of vanished responses for servers " +
- "not storing deletion sequences.")
@Test
void knownUidSetShouldTorelateDeletedMessages() throws Exception {
inbox.delete(ImmutableList.of(MessageUid.MIN_VALUE), mailboxSession);
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org