Repository: james-project
Updated Branches:
  refs/heads/master d9a6b0f18 -> 23e0f09c8


JAMES-1935 search should be wider in order to prevent further DB reads

For N mailboxes, with cassandra implementation, previous implementation lead to 
:
 - A first read returning N mailboxes
 - For these N mailboxes, a new DB call was made to see if we have children

 By doing a wilder query, we can also retrieve children of the mailbox and 
avoid making these N DB call. Complexity of searching mailboxes is then greatly 
reduced.


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/aede6817
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/aede6817
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/aede6817

Branch: refs/heads/master
Commit: aede6817f6623dff066d6d50a8fcc36ef2dbc863
Parents: a4d8c8e
Author: Benoit Tellier <[email protected]>
Authored: Fri Feb 10 15:01:29 2017 +0700
Committer: Antoine Duprat <[email protected]>
Committed: Fri Feb 10 16:40:05 2017 +0100

----------------------------------------------------------------------
 .../mailbox/hbase/mail/model/HBaseMailbox.java  |  7 +++++
 .../mailbox/jcr/mail/model/JCRMailbox.java      |  7 +++++
 .../mailbox/jpa/mail/model/JPAMailbox.java      |  6 ++++
 .../LuceneMailboxMessageSearchIndexTest.java    |  6 ++++
 .../mailbox/store/StoreMailboxManager.java      | 33 +++++++++++++++-----
 .../james/mailbox/store/mail/model/Mailbox.java |  3 ++
 .../mailbox/store/mail/model/MailboxUtil.java   | 30 ++++++++++++++++++
 .../store/mail/model/impl/SimpleMailbox.java    |  6 ++++
 .../store/mail/model/ListMailboxAssertTest.java |  7 +++++
 9 files changed, 98 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/aede6817/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/model/HBaseMailbox.java
----------------------------------------------------------------------
diff --git 
a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/model/HBaseMailbox.java
 
b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/model/HBaseMailbox.java
index bbcea74..ea0a360 100644
--- 
a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/model/HBaseMailbox.java
+++ 
b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/model/HBaseMailbox.java
@@ -20,12 +20,14 @@ package org.apache.james.mailbox.hbase.mail.model;
 
 import java.util.UUID;
 
+import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.hbase.HBaseId;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.SimpleMailboxACL;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.mail.model.MailboxUtil;
 
 /**
  * This class implements a mailbox. Most of the code is done after mailbox-jpa 
@@ -215,5 +217,10 @@ public class HBaseMailbox implements Mailbox {
     public void setACL(MailboxACL acl) {
         // TODO ACL support
     }
+
+    @Override
+    public boolean isChildOf(Mailbox potentialParent, MailboxSession 
mailboxSession) {
+        return MailboxUtil.isMailboxChildOf(this, potentialParent, 
mailboxSession);
+    }
     
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/aede6817/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/model/JCRMailbox.java
----------------------------------------------------------------------
diff --git 
a/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/model/JCRMailbox.java
 
b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/model/JCRMailbox.java
index fdd8fd3..0c7a51c 100644
--- 
a/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/model/JCRMailbox.java
+++ 
b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/model/JCRMailbox.java
@@ -23,6 +23,7 @@ import javax.jcr.RepositoryException;
 
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.util.Text;
+import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.jcr.JCRId;
 import org.apache.james.mailbox.jcr.JCRImapConstants;
 import org.apache.james.mailbox.jcr.Persistent;
@@ -31,6 +32,7 @@ import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.SimpleMailboxACL;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.mail.model.MailboxUtil;
 import org.slf4j.Logger;
 
 
@@ -324,5 +326,10 @@ public class JCRMailbox implements Mailbox, 
JCRImapConstants, Persistent{
     public void setACL(MailboxACL acl) {
         // TODO ACL support
     }
+
+    @Override
+    public boolean isChildOf(Mailbox potentialParent, MailboxSession 
mailboxSession) {
+        return MailboxUtil.isMailboxChildOf(this, potentialParent, 
mailboxSession);
+    }
     
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/aede6817/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAMailbox.java
----------------------------------------------------------------------
diff --git 
a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAMailbox.java
 
b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAMailbox.java
index f47f222..da4b354 100644
--- 
a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAMailbox.java
+++ 
b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAMailbox.java
@@ -27,12 +27,14 @@ import javax.persistence.NamedQueries;
 import javax.persistence.NamedQuery;
 import javax.persistence.Table;
 
+import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.jpa.JPAId;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.SimpleMailboxACL;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.mail.model.MailboxUtil;
 
 @Entity(name="Mailbox")
 @Table(name="JAMES_MAILBOX")
@@ -238,4 +240,8 @@ public class JPAMailbox implements Mailbox {
     public void setACL(MailboxACL acl) {
     }
 
+    @Override
+    public boolean isChildOf(Mailbox potentialParent, MailboxSession 
mailboxSession) {
+        return MailboxUtil.isMailboxChildOf(this, potentialParent, 
mailboxSession);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/aede6817/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMailboxMessageSearchIndexTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMailboxMessageSearchIndexTest.java
 
b/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMailboxMessageSearchIndexTest.java
index 054ec1c..e93cdb6 100644
--- 
a/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMailboxMessageSearchIndexTest.java
+++ 
b/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMailboxMessageSearchIndexTest.java
@@ -688,5 +688,11 @@ public class LuceneMailboxMessageSearchIndexTest {
         }
 
 
+        @Override
+        public boolean isChildOf(Mailbox potentialParent, MailboxSession 
mailboxSession) {
+            throw new UnsupportedOperationException("Not supported");
+        }
+
+
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/aede6817/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
index b4d83b4..9d14622 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
@@ -82,6 +82,9 @@ import org.apache.james.mailbox.store.transaction.Mapper;
 import org.apache.james.mailbox.store.transaction.TransactionalMapper;
 import org.slf4j.Logger;
 
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+
 /**
  * This base class of an {@link MailboxManager} implementation provides a 
high-level api for writing your own
  * {@link MailboxManager} implementation. If you plan to write your own {@link 
MailboxManager} its most times so easiest
@@ -665,14 +668,15 @@ public class StoreMailboxManager implements 
MailboxManager {
         } else {
             baseLength = baseName.length();
         }
-        final String combinedName = mailboxExpression.getCombinedName()
+        String combinedName = mailboxExpression.getCombinedName()
                 .replace(freeWildcard, SQL_WILDCARD_CHAR)
-                .replace(localWildcard, SQL_WILDCARD_CHAR);
-        final MailboxPath search = new 
MailboxPath(mailboxExpression.getBase(), combinedName);
+                .replace(localWildcard, SQL_WILDCARD_CHAR)
+            + SQL_WILDCARD_CHAR;
+        MailboxPath search = new MailboxPath(mailboxExpression.getBase(), 
combinedName);
 
-        final MailboxMapper mapper = 
mailboxSessionMapperFactory.getMailboxMapper(session);
-        final List<Mailbox> mailboxes = mapper.findMailboxWithPathLike(search);
-        final List<MailboxMetaData> results = new 
ArrayList<MailboxMetaData>(mailboxes.size());
+        List<Mailbox> mailboxes = 
mailboxSessionMapperFactory.getMailboxMapper(session)
+            .findMailboxWithPathLike(search);
+        List<MailboxMetaData> results = new 
ArrayList<MailboxMetaData>(mailboxes.size());
         for (Mailbox mailbox : mailboxes) {
             final String name = mailbox.getName();
             if(belongsToNamespaceAndUser(mailboxExpression.getBase(), 
mailbox)) {
@@ -680,7 +684,8 @@ public class StoreMailboxManager implements MailboxManager {
                     final String match = name.substring(baseLength);
                     if (mailboxExpression.isExpressionMatch(match)) {
                         final MailboxMetaData.Children inferiors;
-                        if (mapper.hasChildren(mailbox, 
session.getPathDelimiter())) {
+                        List<Mailbox> potentialChildren = mailboxes;
+                        if (hasChildIn(mailbox, potentialChildren, session)) {
                             inferiors = MailboxMetaData.Children.HAS_CHILDREN;
                         } else {
                             inferiors = 
MailboxMetaData.Children.HAS_NO_CHILDREN;
@@ -695,6 +700,20 @@ public class StoreMailboxManager implements MailboxManager 
{
         return results;
     }
 
+    private boolean hasChildIn(Mailbox parentMailbox, List<Mailbox> 
mailboxesWithPathLike, MailboxSession mailboxSession) {
+        return FluentIterable.from(mailboxesWithPathLike)
+            .anyMatch(isChildren(parentMailbox, mailboxSession));
+    }
+
+    private Predicate<Mailbox> isChildren(final Mailbox parentMailbox, final 
MailboxSession mailboxSession) {
+        return new Predicate<Mailbox>() {
+            @Override
+            public boolean apply(Mailbox mailbox) {
+                return mailbox.isChildOf(parentMailbox, mailboxSession);
+            }
+        };
+    }
+
     @Override
     public List<MessageId> search(MultimailboxesSearchQuery expression, 
MailboxSession session, long limit) throws MailboxException {
         return index.search(session, expression, limit);

http://git-wip-us.apache.org/repos/asf/james-project/blob/aede6817/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/Mailbox.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/Mailbox.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/Mailbox.java
index 1cc9f26..9f077f3 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/Mailbox.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/Mailbox.java
@@ -18,6 +18,7 @@
  ****************************************************************/
 package org.apache.james.mailbox.store.mail.model;
 
+import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxId;
 
@@ -88,5 +89,7 @@ public interface Mailbox {
      * @param acl
      */
     void setACL(MailboxACL acl);
+
+    boolean isChildOf(Mailbox potentialParent, MailboxSession mailboxSession);
     
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/aede6817/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/MailboxUtil.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/MailboxUtil.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/MailboxUtil.java
new file mode 100644
index 0000000..56e9fa8
--- /dev/null
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/MailboxUtil.java
@@ -0,0 +1,30 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+package org.apache.james.mailbox.store.mail.model;
+
+import org.apache.james.mailbox.MailboxSession;
+
+public class MailboxUtil {
+
+    public static boolean isMailboxChildOf(Mailbox mailbox, Mailbox 
potentialParent, MailboxSession mailboxSession) {
+        return mailbox.getNamespace().equals(potentialParent.getNamespace())
+            && mailbox.getUser().equals(potentialParent.getUser())
+            && mailbox.getName().startsWith(potentialParent.getName() + 
mailboxSession.getPathDelimiter());
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/aede6817/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailbox.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailbox.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailbox.java
index 69e7bf0..49b79f0 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailbox.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailbox.java
@@ -18,11 +18,13 @@
  ****************************************************************/
 package org.apache.james.mailbox.store.mail.model.impl;
 
+import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.SimpleMailboxACL;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.mail.model.MailboxUtil;
 
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
@@ -160,4 +162,8 @@ public class SimpleMailbox implements Mailbox {
         this.acl = acl;
     }
 
+    @Override
+    public boolean isChildOf(Mailbox potentialParent, MailboxSession 
mailboxSession) {
+        return MailboxUtil.isMailboxChildOf(this, potentialParent, 
mailboxSession);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/aede6817/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/ListMailboxAssertTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/ListMailboxAssertTest.java
 
b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/ListMailboxAssertTest.java
index 1410ab9..6e8e408 100644
--- 
a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/ListMailboxAssertTest.java
+++ 
b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/ListMailboxAssertTest.java
@@ -24,6 +24,8 @@ import static 
org.apache.james.mailbox.store.mail.model.ListMailboxAssert.assert
 
 import java.util.List;
 
+import org.apache.commons.lang.NotImplementedException;
+import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
@@ -113,6 +115,11 @@ public class ListMailboxAssertTest {
             public MailboxACL getACL() {
                 return null;
             }
+
+            @Override
+            public boolean isChildOf(Mailbox potentialParent, MailboxSession 
mailboxSession) {
+                throw new NotImplementedException();
+            }
         };
     }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to