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]
