Author: wstrzalka
Date: Wed Feb 23 20:05:21 2011
New Revision: 1073920

URL: http://svn.apache.org/viewvc?rev=1073920&view=rev
Log:
Fetch optimisation by moving batch responsibility to mailbox. See IMAP-258

Added:
    
james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageRangeException.java
      - copied, changed from r1070050, 
james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/base/MessageRangeException.java
Modified:
    
james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageManager.java
    
james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageRange.java
    
james/mailbox/trunk/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMessageMapper.java
    
james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java
    
james/mailbox/trunk/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java
    
james/mailbox/trunk/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMessageMapper.java
    
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
    
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/MessageMapper.java
    
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/transaction/Mapper.java
    
james/mailbox/trunk/torque/src/main/java/org/apache/james/mailbox/torque/TorqueMailbox.java

Modified: 
james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageManager.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageManager.java?rev=1073920&r1=1073919&r2=1073920&view=diff
==============================================================================
--- 
james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageManager.java
 (original)
+++ 
james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageManager.java
 Wed Feb 23 20:05:21 2011
@@ -112,6 +112,7 @@ public interface MessageManager {
     /**
      * Gets messages in the given range.
      * @param set
+     * @param fetchGroup data to fetch
      * @param mailboxSession not null
      * @return MessageResult with the fields defined by FetchGroup
      * @throws MailboxException
@@ -120,6 +121,19 @@ public interface MessageManager {
             MailboxSession mailboxSession) throws MailboxException;
     
     /**
+     * Gets messages in the given range.
+     * @param set
+     * @param fetchGroup data to fetch
+     * @param mailboxSession not null
+     * @param messageCallback data callback
+     * @return MessageResult with the fields defined by FetchGroup
+     * @throws MailboxException
+     */
+       void getMessages(MessageRange set, FetchGroup fetchGroup, 
+                       MailboxSession mailboxSession, MessageCallback 
messageCallback) 
+                       throws MailboxException;
+
+    /**
      * Gets current meta data for the mailbox.
      * Consolidates common calls together to allow improved performance.
      * The meta-data returned should be immutable and represent the current 
state
@@ -134,6 +148,13 @@ public interface MessageManager {
     MetaData getMetaData(boolean resetRecent, MailboxSession mailboxSession, 
MessageManager.MetaData.FetchGroup fetchGroup) throws MailboxException;
     
     /**
+     * Message batch read callback method 
+     */
+    public interface MessageCallback {
+       void onMessages(final Iterator<MessageResult> it) throws 
MailboxException;
+    }
+    
+    /**
      * Meta data about the current state of the mailbox.
      */
     public interface MetaData {

Modified: 
james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageRange.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageRange.java?rev=1073920&r1=1073919&r2=1073920&view=diff
==============================================================================
--- 
james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageRange.java
 (original)
+++ 
james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageRange.java
 Wed Feb 23 20:05:21 2011
@@ -38,35 +38,48 @@ public class MessageRange {
 
     private static final int NOT_A_UID = -1;
     
+    // return all rows at ones 
+    private static final int UNLIMITED_BATCH = 0;
+    
     /**
      * Constructs a range consisting of a single message only.
      * @param uid UID of the message
      * @return not null
      */
     public static MessageRange one(long uid) {
-        final MessageRange result = new MessageRange(Type.ONE, uid, uid);
+        final MessageRange result = new MessageRange(Type.ONE, uid, uid, 
UNLIMITED_BATCH);
         return result;
     }
-
+    
     /**
      * Constructs a range consisting of all messages.
+     * @param batchSize return max batchSize rows in chunk
      * @return not null
      */
-    public static MessageRange all() {
+    public static MessageRange all(int batchSize) {
         final MessageRange result = new MessageRange(Type.ALL, NOT_A_UID,
-                NOT_A_UID);
+                NOT_A_UID, batchSize);
         return result;
     }
 
     /**
+     * Constructs a range consisting of all messages.
+     * @return not null
+     */
+    public static MessageRange all() {
+       return all(UNLIMITED_BATCH);
+    }
+    
+    /**
      * Constructs an inclusive ranges of messages.
      * The parameters will be checked and {@link #from(long)}
      * used where appropriate.
      * @param from first message UID
      * @param to last message UID
+     * @param batchSize return max batchSize rows in chunk 
      * @return not null
      */
-    public static MessageRange range(long from, long to) {
+    public static MessageRange range(long from, long to, int batchSize) {
         final MessageRange result;
         if (to == Long.MAX_VALUE || to < from) {
             to = NOT_A_UID;
@@ -75,33 +88,58 @@ public class MessageRange {
             // from and to is the same so no need to construct a real range
             result = one(from);
         } else {
-            result = new MessageRange(Type.RANGE, from, to);
+            result = new MessageRange(Type.RANGE, from, to, batchSize);
         }
         return result;
     }
     
     /**
+     * Constructs an inclusive ranges of messages.
+     * The parameters will be checked and {@link #from(long)}
+     * used where appropriate.
+     * @param from first message UID
+     * @param to last message UID
+     * @return not null
+     */
+    public static MessageRange range(long from, long to) {
+       return range(from, to, UNLIMITED_BATCH);
+    }
+    
+    /**
      * Constructs an inclusive, open ended range of messages.
-     * @param from first messege UID in range
+     * @param from first message UID in range
+     * @param batchSize return max batchSize rows in chunk 
      * @return not null
      */
-    public static MessageRange from(long from) {
-        final MessageRange result= new MessageRange(Type.FROM, from, 
NOT_A_UID);
+    public static MessageRange from(long from, int batchSize) {
+        final MessageRange result= new MessageRange(Type.FROM, from, 
NOT_A_UID, batchSize);
         return result;
     }
+    
+    /**
+     * Constructs an inclusive, open ended range of messages.
+     * @param from first message UID in range
+     * @return not null
+     */
+    public static MessageRange from(long from) {
+        return from(from, UNLIMITED_BATCH);
+    }
 
     private final Type type;
 
     private final long uidFrom;
 
     private final long uidTo;
+    
+    private final int batchSize;
 
-    private MessageRange(final Type type, final long uidFrom,
-            final long uidTo) {
+    protected MessageRange(final Type type, final long uidFrom,
+            final long uidTo, final int batchSize) {
         super();
         this.type = type;
         this.uidFrom = uidFrom;
         this.uidTo = uidTo;
+        this.batchSize = batchSize;
     }
 
     public Type getType() {
@@ -116,6 +154,9 @@ public class MessageRange {
         return uidTo;
     }
 
+    public int getBatchSize() {
+        return batchSize;
+    }
 
     /**
      * Return true if the uid is within the range
@@ -146,6 +187,6 @@ public class MessageRange {
     }
     
     public String toString() {
-        return "TYPE: " + type + " UID: " + uidFrom + ":" + uidTo;
+        return "TYPE: " + type + " UID: " + uidFrom + ":" + uidTo + (batchSize 
> 0 ? " BATCH: "+batchSize : "");
     }
 }

Copied: 
james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageRangeException.java
 (from r1070050, 
james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/base/MessageRangeException.java)
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageRangeException.java?p2=james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageRangeException.java&p1=james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/base/MessageRangeException.java&r1=1070050&r2=1073920&rev=1073920&view=diff
==============================================================================
--- 
james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/base/MessageRangeException.java
 (original)
+++ 
james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageRangeException.java
 Wed Feb 23 20:05:21 2011
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.imap.processor.base;
+package org.apache.james.mailbox;
 
 
 /**

Modified: 
james/mailbox/trunk/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMessageMapper.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMessageMapper.java?rev=1073920&r1=1073919&r2=1073920&view=diff
==============================================================================
--- 
james/mailbox/trunk/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMessageMapper.java
 (original)
+++ 
james/mailbox/trunk/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMessageMapper.java
 Wed Feb 23 20:05:21 2011
@@ -40,8 +40,8 @@ import org.apache.jackrabbit.util.ISO907
 import org.apache.james.mailbox.MailboxException;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageRange;
-import org.apache.james.mailbox.MessageRange.Type;
 import org.apache.james.mailbox.SearchQuery;
+import org.apache.james.mailbox.MessageRange.Type;
 import org.apache.james.mailbox.SearchQuery.Criterion;
 import org.apache.james.mailbox.SearchQuery.NumericRange;
 import org.apache.james.mailbox.jcr.AbstractJCRMapper;
@@ -208,39 +208,54 @@ public class JCRMessageMapper extends Ab
      * 
org.apache.james.mailbox.store.mail.MessageMapper#findInMailbox(org.apache
      * .james.imap.mailbox.MessageRange)
      */
-    public List<MailboxMembership<String>> findInMailbox(Mailbox<String> 
mailbox, MessageRange set) throws MailboxException {
+    public void findInMailbox(Mailbox<String> mailbox, MessageRange set,
+               MailboxMembershipCallback<String> callback) throws 
MailboxException {
         try {
-            final List<MailboxMembership<String>> results;
-            final long from = set.getUidFrom();
+               List<MailboxMembership<String>> results;
+            long from = set.getUidFrom();
             final long to = set.getUidTo();
+            final int batchSize = set.getBatchSize();
             final Type type = set.getType();
-            switch (type) {
-                default:
-                case ALL:
-                    results = findMessagesInMailbox(mailbox);
-                    break;
-                case FROM:
-                    results = findMessagesInMailboxAfterUID(mailbox, from);
-                    break;
-                case ONE:
-                    results = findMessageInMailboxWithUID(mailbox, from);
-                    break;
-                case RANGE:
-                    results = findMessagesInMailboxBetweenUIDs(mailbox, from, 
to);
-                    break;       
-            }
-            return results;
+            
+            do {
+                   switch (type) {
+                       default:
+                       case ALL:
+                           results = findMessagesInMailbox(mailbox, batchSize);
+                           break;
+                       case FROM:
+                               results = 
findMessagesInMailboxAfterUID(mailbox, from, batchSize);
+                           break;
+                       case ONE:
+                               results = findMessageInMailboxWithUID(mailbox, 
from);
+                           break;
+                       case RANGE:
+                               results = 
findMessagesInMailboxBetweenUIDs(mailbox, from, to, batchSize);
+                           break;       
+                   }
+            
+                   if(results.size() > 0) {
+                                       callback.onMailboxMembers(results);
+                                                                               
+                                       // move the start UID behind the last 
fetched message UID                                       
+                                       from = 
results.get(results.size()-1).getUid()+1;
+                               }
+                   
+               } while(results.size() > 0 && batchSize > 0);
         } catch (RepositoryException e) {
             throw new MailboxException("Unable to search MessageRange " + set 
+ " in mailbox " + mailbox, e);
         }
     }
-
-    private List<MailboxMembership<String>> 
findMessagesInMailboxAfterUID(Mailbox<String> mailbox, long uid) throws 
RepositoryException {
+   
+    private List<MailboxMembership<String>> 
findMessagesInMailboxAfterUID(Mailbox<String> mailbox, long uid, int batchSize) 
throws RepositoryException {
         List<MailboxMembership<String>> list = new 
ArrayList<MailboxMembership<String>>();
         String queryString = "/jcr:root" + getMailboxPath(mailbox) + 
"//element(*,jamesMailbox:message)[@" + JCRMessage.UID_PROPERTY + ">=" + uid + 
"] order by @" + JCRMessage.UID_PROPERTY;
 
         QueryManager manager = getSession().getWorkspace().getQueryManager();
-        QueryResult result = manager.createQuery(queryString, 
Query.XPATH).execute();
+        Query query = manager.createQuery(queryString, Query.XPATH);
+        if(batchSize > 0)
+               query.setLimit(batchSize);
+        QueryResult result = query.execute();
 
         NodeIterator iterator = result.getNodes();
         while (iterator.hasNext()) {
@@ -264,12 +279,15 @@ public class JCRMessageMapper extends Ab
         return list;
     }
 
-    private List<MailboxMembership<String>> 
findMessagesInMailboxBetweenUIDs(Mailbox<String> mailbox, long from, long to) 
throws RepositoryException {
+    private List<MailboxMembership<String>> 
findMessagesInMailboxBetweenUIDs(Mailbox<String> mailbox, long from, long to, 
int batchSize) throws RepositoryException {
         List<MailboxMembership<String>> list = new 
ArrayList<MailboxMembership<String>>();
         String queryString = "/jcr:root" + getMailboxPath(mailbox) + 
"//element(*,jamesMailbox:message)[@" + JCRMessage.UID_PROPERTY + ">=" + from + 
" and @" + JCRMessage.UID_PROPERTY + "<=" + to + "] order by @" + 
JCRMessage.UID_PROPERTY;
         
         QueryManager manager = getSession().getWorkspace().getQueryManager();
-        QueryResult result = manager.createQuery(queryString, 
Query.XPATH).execute();
+        Query query = manager.createQuery(queryString, Query.XPATH);
+        if(batchSize > 0)
+               query.setLimit(batchSize);
+        QueryResult result = query.execute();
 
         NodeIterator iterator = result.getNodes();
         while (iterator.hasNext()) {
@@ -278,12 +296,15 @@ public class JCRMessageMapper extends Ab
         return list;
     }
     
-    private List<MailboxMembership<String>> 
findMessagesInMailbox(Mailbox<String> mailbox) throws RepositoryException {     
   
+    private List<MailboxMembership<String>> 
findMessagesInMailbox(Mailbox<String> mailbox, int batchSize) throws 
RepositoryException {        
         List<MailboxMembership<String>> list = new 
ArrayList<MailboxMembership<String>>();
         
         String queryString = "/jcr:root" + getMailboxPath(mailbox) + 
"//element(*,jamesMailbox:message) order by @" + JCRMessage.UID_PROPERTY;
         QueryManager manager = getSession().getWorkspace().getQueryManager();
-        QueryResult result = manager.createQuery(queryString, 
Query.XPATH).execute();
+        Query query = manager.createQuery(queryString, Query.XPATH);
+        if(batchSize > 0)
+               query.setLimit(batchSize);
+        QueryResult result = query.execute();
 
         NodeIterator iterator = result.getNodes();
         while (iterator.hasNext()) {
@@ -662,45 +683,50 @@ public class JCRMessageMapper extends Ab
      * (non-Javadoc)
      * @see 
org.apache.james.mailbox.store.mail.MessageMapper#updateFlags(org.apache.james.mailbox.store.mail.model.Mailbox,
 javax.mail.Flags, boolean, boolean, org.apache.james.mailbox.MessageRange)
      */
-    public Iterator<UpdatedFlags> updateFlags(Mailbox<String> mailbox, Flags 
flags, boolean value, boolean replace, MessageRange set) throws 
MailboxException {
+    public Iterator<UpdatedFlags> updateFlags(final Mailbox<String> mailbox, 
final Flags flags, final boolean value, final boolean replace, MessageRange 
set) throws MailboxException {
         final List<UpdatedFlags> updatedFlags = new ArrayList<UpdatedFlags>();
 
-        final List<MailboxMembership<String>> members = findInMailbox(mailbox, 
set);
-        for (final MailboxMembership<String> member:members) {
-            Flags originalFlags = member.createFlags();
-            if (replace) {
-                member.setFlags(flags);
-            } else {
-                Flags current = member.createFlags();
-                if (value) {
-                    current.add(flags);
-                } else {
-                    current.remove(flags);
-                }
-                member.setFlags(current);
-            }
-            Flags newFlags = member.createFlags();
-            
-            JCRMessage membership = (JCRMessage) member;
-            if (membership.isPersistent()) {
-                try {
-                    Node messageNode = 
getSession().getNodeByIdentifier(membership.getId());
-                    membership.merge(messageNode);
-                } catch (RepositoryException e) {
-                    throw new MailboxException("Unable to update flags for 
message " + membership + " in mailbox " + mailbox, e);
-
-                } catch (IOException e) {
-                    throw new MailboxException("Unable to update flags for 
message " + membership + " in mailbox " + mailbox, e);
-
-                }
-            }
-
-            
-            updatedFlags.add(new UpdatedFlags(member.getUid(),originalFlags, 
newFlags));
-        }
+        findInMailbox(mailbox, set, new MailboxMembershipCallback<String>() {
+                       
+                       public void 
onMailboxMembers(List<MailboxMembership<String>> members)
+                                       throws MailboxException {
+
+                               for (final MailboxMembership<String> 
member:members) {
+                           Flags originalFlags = member.createFlags();
+                           if (replace) {
+                               member.setFlags(flags);
+                           } else {
+                               Flags current = member.createFlags();
+                               if (value) {
+                                   current.add(flags);
+                               } else {
+                                   current.remove(flags);
+                               }
+                               member.setFlags(current);
+                           }
+                           Flags newFlags = member.createFlags();
+                           
+                           JCRMessage membership = (JCRMessage) member;
+                           if (membership.isPersistent()) {
+                               try {
+                                   Node messageNode = 
getSession().getNodeByIdentifier(membership.getId());
+                                   membership.merge(messageNode);
+                               } catch (RepositoryException e) {
+                                   throw new MailboxException("Unable to 
update flags for message " + membership + " in mailbox " + mailbox, e);
+
+                               } catch (IOException e) {
+                                   throw new MailboxException("Unable to 
update flags for message " + membership + " in mailbox " + mailbox, e);
+
+                               }
+                           }
+                           
+                           updatedFlags.add(new 
UpdatedFlags(member.getUid(),originalFlags, newFlags));
+                       }
+
+                               
+                       }
+               });
         
         return updatedFlags.iterator();       
     }
-    
-
 }

Modified: 
james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java?rev=1073920&r1=1073919&r2=1073920&view=diff
==============================================================================
--- 
james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java
 (original)
+++ 
james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java
 Wed Feb 23 20:05:21 2011
@@ -29,8 +29,8 @@ import javax.persistence.Query;
 
 import org.apache.james.mailbox.MailboxException;
 import org.apache.james.mailbox.MessageRange;
-import org.apache.james.mailbox.MessageRange.Type;
 import org.apache.james.mailbox.SearchQuery;
+import org.apache.james.mailbox.MessageRange.Type;
 import org.apache.james.mailbox.SearchQuery.Criterion;
 import org.apache.james.mailbox.SearchQuery.NumericRange;
 import org.apache.james.mailbox.jpa.JPATransactionalMapper;
@@ -57,38 +57,56 @@ public class JPAMessageMapper extends JP
     /**
      * @see 
org.apache.james.mailbox.store.mail.MessageMapper#findInMailbox(org.apache.james.mailbox.MessageRange)
      */
-    public List<MailboxMembership<Long>> findInMailbox(Mailbox<Long> mailbox, 
MessageRange set) throws MailboxException {
+    public void findInMailbox(Mailbox<Long> mailbox, MessageRange set, 
MailboxMembershipCallback<Long> callback) throws MailboxException {
         try {
-            final List<MailboxMembership<Long>> results;
-            final long from = set.getUidFrom();
+            List<MailboxMembership<Long>> results;
+            long from = set.getUidFrom();
             final long to = set.getUidTo();
+            final int batchSize = set.getBatchSize();
             final Type type = set.getType();
-            switch (type) {
-                default:
-                case ALL:
-                    results = findMessagesInMailbox(mailbox);
-                    break;
-                case FROM:
-                    results = findMessagesInMailboxAfterUID(mailbox, from);
-                    break;
-                case ONE:
-                    results = findMessagesInMailboxWithUID(mailbox, from);
-                    break;
-                case RANGE:
-                    results = findMessagesInMailboxBetweenUIDs(mailbox, from, 
to);
-                    break;       
-            }
-            return results;
+            
+               // when batch is specified fetch data in chunks and send back 
in batches
+               do {
+                   switch (type) {
+                       default:
+                       case ALL:
+                           results = findMessagesInMailbox(mailbox, batchSize);
+                           break;
+                       case FROM:
+                           results = findMessagesInMailboxAfterUID(mailbox, 
from, batchSize);
+                           break;
+                       case ONE:
+                           results = findMessagesInMailboxWithUID(mailbox, 
from);
+                           break;
+                       case RANGE:
+                           results = findMessagesInMailboxBetweenUIDs(mailbox, 
from, to, batchSize);
+                           break;       
+                   }
+                   
+                   if(results.size() > 0) {
+                                       callback.onMailboxMembers(results);
+                                       
+                                       // move the start UID behind the last 
fetched message UID
+                                       from = 
results.get(results.size()-1).getUid()+1;
+                               }
+                                       
+                       } while(results.size() > 0 && batchSize > 0);
+                   
         } catch (PersistenceException e) {
             throw new MailboxException("Search of MessageRange " + set + " 
failed in mailbox " + mailbox, e);
         }
     }
-
+    
     @SuppressWarnings("unchecked")
-    private List<MailboxMembership<Long>> 
findMessagesInMailboxAfterUID(Mailbox<Long> mailbox, long uid) {
-        return 
getEntityManager().createNamedQuery("findMessagesInMailboxAfterUID")
+    private List<MailboxMembership<Long>> 
findMessagesInMailboxAfterUID(Mailbox<Long> mailbox, long uid, int batchSize) {
+        Query query = 
getEntityManager().createNamedQuery("findMessagesInMailboxAfterUID")
         .setParameter("idParam", mailbox.getMailboxId())
-        .setParameter("uidParam", uid).getResultList();
+        .setParameter("uidParam", uid);
+        
+        if(batchSize > 0)
+               query.setMaxResults(batchSize);
+        
+        return query.getResultList();
     }
 
     @SuppressWarnings("unchecked")
@@ -99,16 +117,24 @@ public class JPAMessageMapper extends JP
     }
 
     @SuppressWarnings("unchecked")
-    private List<MailboxMembership<Long>> 
findMessagesInMailboxBetweenUIDs(Mailbox<Long> mailbox, long from, long to) {
-        return 
getEntityManager().createNamedQuery("findMessagesInMailboxBetweenUIDs")
+    private List<MailboxMembership<Long>> 
findMessagesInMailboxBetweenUIDs(Mailbox<Long> mailbox, long from, long to, int 
batchSize) {
+        Query query = 
getEntityManager().createNamedQuery("findMessagesInMailboxBetweenUIDs")
         .setParameter("idParam", mailbox.getMailboxId())
         .setParameter("fromParam", from)
-        .setParameter("toParam", to).getResultList();
+        .setParameter("toParam", to);
+        
+        if(batchSize > 0)
+               query.setMaxResults(batchSize);
+        
+        return query.getResultList();
     }
 
     @SuppressWarnings("unchecked")
-    private List<MailboxMembership<Long>> findMessagesInMailbox(Mailbox<Long> 
mailbox) {
-        return 
getEntityManager().createNamedQuery("findMessagesInMailbox").setParameter("idParam",
 mailbox.getMailboxId()).getResultList();
+    private List<MailboxMembership<Long>> findMessagesInMailbox(Mailbox<Long> 
mailbox, int batchSize) {
+         Query query = 
getEntityManager().createNamedQuery("findMessagesInMailbox").setParameter("idParam",
 mailbox.getMailboxId());
+         if(batchSize > 0)
+                query.setMaxResults(batchSize);
+         return query.getResultList();
     }
 
     /**
@@ -330,31 +356,35 @@ public class JPAMessageMapper extends JP
      * (non-Javadoc)
      * @see 
org.apache.james.mailbox.store.mail.MessageMapper#updateFlags(org.apache.james.mailbox.store.mail.model.Mailbox,
 javax.mail.Flags, boolean, boolean, org.apache.james.mailbox.MessageRange)
      */
-    public Iterator<UpdatedFlags> updateFlags(Mailbox<Long> mailbox, Flags 
flags, boolean value, boolean replace, MessageRange set) throws 
MailboxException {
+    public Iterator<UpdatedFlags> updateFlags(Mailbox<Long> mailbox, final 
Flags flags, final boolean value, final boolean replace, MessageRange set) 
throws MailboxException {
         
         final List<UpdatedFlags> updatedFlags = new ArrayList<UpdatedFlags>();
-        final List<MailboxMembership<Long>> members = findInMailbox(mailbox, 
set);
+        findInMailbox(mailbox, set, new MailboxMembershipCallback<Long>() {
+                       
+                       public void 
onMailboxMembers(List<MailboxMembership<Long>> members)
+                                       throws MailboxException {
+                       for (final MailboxMembership<Long> member:members) {
+                           Flags originalFlags = member.createFlags();
+                           if (replace) {
+                               member.setFlags(flags);
+                           } else {
+                               Flags current = member.createFlags();
+                               if (value) {
+                                   current.add(flags);
+                               } else {
+                                   current.remove(flags);
+                               }
+                               member.setFlags(current);
+                           }
+                           Flags newFlags = member.createFlags();
+                           getEntityManager().persist(member);
+                           updatedFlags.add(new 
UpdatedFlags(member.getUid(),originalFlags, newFlags));
+                       }
+                               
+                       }
+               });
 
-        for (final MailboxMembership<Long> member:members) {
-            Flags originalFlags = member.createFlags();
-            if (replace) {
-                member.setFlags(flags);
-            } else {
-                Flags current = member.createFlags();
-                if (value) {
-                    current.add(flags);
-                } else {
-                    current.remove(flags);
-                }
-                member.setFlags(current);
-            }
-            Flags newFlags = member.createFlags();
-            getEntityManager().persist(member);
-            updatedFlags.add(new UpdatedFlags(member.getUid(),originalFlags, 
newFlags));
-        }
-        
         return updatedFlags.iterator();
 
     }
-    
 }

Modified: 
james/mailbox/trunk/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java?rev=1073920&r1=1073919&r2=1073920&view=diff
==============================================================================
--- 
james/mailbox/trunk/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java
 (original)
+++ 
james/mailbox/trunk/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java
 Wed Feb 23 20:05:21 2011
@@ -27,16 +27,16 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map.Entry;
 import java.util.SortedMap;
+import java.util.Map.Entry;
 
 import javax.mail.Flags;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.james.mailbox.MailboxException;
 import org.apache.james.mailbox.MessageRange;
-import org.apache.james.mailbox.MessageRange.Type;
 import org.apache.james.mailbox.SearchQuery;
+import org.apache.james.mailbox.MessageRange.Type;
 import org.apache.james.mailbox.SearchQuery.Criterion;
 import org.apache.james.mailbox.SearchQuery.NumericRange;
 import org.apache.james.mailbox.maildir.MaildirFolder;
@@ -125,11 +125,12 @@ public class MaildirMessageMapper extend
      * (non-Javadoc)
      * @see 
org.apache.james.mailbox.store.mail.MessageMapper#findInMailbox(org.apache.james.mailbox.store.mail.model.Mailbox,
 org.apache.james.mailbox.MessageRange)
      */
-    public List<MailboxMembership<Integer>> findInMailbox(Mailbox<Integer> 
mailbox, MessageRange set)
+    public void findInMailbox(Mailbox<Integer> mailbox, MessageRange set, 
MailboxMembershipCallback<Integer> callback)
     throws MailboxException {
         final List<MailboxMembership<Integer>> results;
         final long from = set.getUidFrom();
         final long to = set.getUidTo();
+        final int batchSize = set.getBatchSize(); 
         final Type type = set.getType();
         switch (type) {
         default:
@@ -146,7 +147,16 @@ public class MaildirMessageMapper extend
             results = findMessagesInMailboxBetweenUIDs(mailbox, null, from, 
to);
             break;       
         }
-        return results;
+        
+        if(batchSize > 0) {
+               int i = 0;
+               while(i*batchSize < results.size()) {
+                       callback.onMailboxMembers(results.subList(i*batchSize, 
(i+1)*batchSize < results.size() ? (i+1)*batchSize : results.size()));
+                       i++;
+               }
+        } else {
+               callback.onMailboxMembers(results);
+        }
     }
 
     private List<MailboxMembership<Integer>> 
findMessageInMailboxWithUID(Mailbox<Integer> mailbox, long uid)
@@ -417,47 +427,52 @@ public class MaildirMessageMapper extend
     }
 
 
-    public Iterator<UpdatedFlags> updateFlags(Mailbox<Integer> mailbox, Flags 
flags, boolean value, boolean replace, MessageRange set) throws 
MailboxException {
+    public Iterator<UpdatedFlags> updateFlags(final Mailbox<Integer> mailbox, 
final Flags flags, final boolean value, final boolean replace, MessageRange 
set) throws MailboxException {
         final List<UpdatedFlags> updatedFlags = new ArrayList<UpdatedFlags>();
-        MaildirFolder folder = maildirStore.createMaildirFolder(mailbox);
+        final MaildirFolder folder = maildirStore.createMaildirFolder(mailbox);
 
-        final List<MailboxMembership<Integer>> members = 
findInMailbox(mailbox, set);
-        for (final MailboxMembership<Integer> member:members) {
-            Flags originalFlags = member.createFlags();
-            if (replace) {
-                member.setFlags(flags);
-            } else {
-                Flags current = member.createFlags();
-                if (value) {
-                    current.add(flags);
-                } else {
-                    current.remove(flags);
-                }
-                member.setFlags(current);
-            }
-            Flags newFlags = member.createFlags();
-            
-            try {
-                AbstractMaildirMessage maildirMessage = 
(AbstractMaildirMessage) member;
-                MaildirMessageName messageName = 
folder.getMessageNameByUid(maildirMessage.getUid());
-                File messageFile = messageName.getFile();
-                //System.out.println("save existing " + message + " as " + 
messageFile.getName());
-                messageName.setFlags(maildirMessage.createFlags());
-                // this automatically moves messages from new to cur if needed
-                String newMessageName = messageName.getFullName();
-                messageFile.renameTo(new File(folder.getCurFolder(), 
newMessageName));
-                long uid = maildirMessage.getUid();
-                folder.update(uid, newMessageName);
-            } catch (IOException e) {
-                throw new MailboxException("Failure while save Message " + 
member + " in Mailbox " + mailbox, e );
-            }
-            
-            updatedFlags.add(new UpdatedFlags(member.getUid(),originalFlags, 
newFlags));
-        }
+        findInMailbox(mailbox, set, new MailboxMembershipCallback<Integer>() {
+                       
+                       public void 
onMailboxMembers(List<MailboxMembership<Integer>> members)
+                                       throws MailboxException {
+                               for (final MailboxMembership<Integer> 
member:members) {
+                           Flags originalFlags = member.createFlags();
+                           if (replace) {
+                               member.setFlags(flags);
+                           } else {
+                               Flags current = member.createFlags();
+                               if (value) {
+                                   current.add(flags);
+                               } else {
+                                   current.remove(flags);
+                               }
+                               member.setFlags(current);
+                           }
+                           Flags newFlags = member.createFlags();
+                           
+                           try {
+                               AbstractMaildirMessage maildirMessage = 
(AbstractMaildirMessage) member;
+                               MaildirMessageName messageName = 
folder.getMessageNameByUid(maildirMessage.getUid());
+                               File messageFile = messageName.getFile();
+                               //System.out.println("save existing " + message 
+ " as " + messageFile.getName());
+                               
messageName.setFlags(maildirMessage.createFlags());
+                               // this automatically moves messages from new 
to cur if needed
+                               String newMessageName = 
messageName.getFullName();
+                               messageFile.renameTo(new 
File(folder.getCurFolder(), newMessageName));
+                               long uid = maildirMessage.getUid();
+                               folder.update(uid, newMessageName);
+                           } catch (IOException e) {
+                               throw new MailboxException("Failure while save 
Message " + member + " in Mailbox " + mailbox, e );
+                           }
+                           
+                           updatedFlags.add(new 
UpdatedFlags(member.getUid(),originalFlags, newFlags));
+                       }
+                       }
+               });
+        
         
         return updatedFlags.iterator();       
         
     }
-    
   
 }

Modified: 
james/mailbox/trunk/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMessageMapper.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMessageMapper.java?rev=1073920&r1=1073919&r2=1073920&view=diff
==============================================================================
--- 
james/mailbox/trunk/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMessageMapper.java
 (original)
+++ 
james/mailbox/trunk/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMessageMapper.java
 Wed Feb 23 20:05:21 2011
@@ -93,8 +93,9 @@ public class InMemoryMessageMapper exten
      * @see 
org.apache.james.mailbox.store.mail.MessageMapper#findInMailbox(java.lang.Object,
 org.apache.james.mailbox.MessageRange)
      */
     @SuppressWarnings("unchecked")
-    public List<MailboxMembership<Long>> findInMailbox(Mailbox<Long> mailbox, 
MessageRange set) throws MailboxException {
+    public void findInMailbox(Mailbox<Long> mailbox, MessageRange set, 
MailboxMembershipCallback<Long> callback) throws MailboxException {
         final List<MailboxMembership<Long>> results;
+        final int batchSize = set.getBatchSize();
         final MessageRange.Type type = set.getType();
         switch (type) {
             case ALL:
@@ -129,21 +130,39 @@ public class InMemoryMessageMapper exten
                 break;
         }
         Collections.sort(results, MailboxMembershipComparator.INSTANCE);
-        return results;
+        
+        if(batchSize > 0) {
+               int i = 0;
+               while(i*batchSize < results.size()) {
+                       callback.onMailboxMembers(results.subList(i*batchSize, 
(i+1)*batchSize < results.size() ? (i+1)*batchSize : results.size()));
+                       i++;
+               }
+        } else {
+               callback.onMailboxMembers(results);
+        }
     }
-
+    
     /*
      * (non-Javadoc)
      * @see 
org.apache.james.mailbox.store.mail.MessageMapper#findMarkedForDeletionInMailbox(org.apache.james.mailbox.MessageRange)
      */
     public List<MailboxMembership<Long>> 
findMarkedForDeletionInMailbox(Mailbox<Long> mailbox, MessageRange set) throws 
MailboxException {
-        final List<MailboxMembership<Long>> results = findInMailbox(mailbox, 
set);
-        for(final Iterator<MailboxMembership<Long>> 
it=results.iterator();it.hasNext();) {
-            if (!it.next().isDeleted()) {
-                it.remove();
-            }
-        }
-        return results;
+       final List<MailboxMembership<Long>> filteredResult = new 
ArrayList<MailboxMembership<Long>>();
+       
+        findInMailbox(mailbox, set, new MailboxMembershipCallback<Long>() {
+               
+                       public void 
onMailboxMembers(List<MailboxMembership<Long>> results)
+                                       throws MailboxException {
+                               for(final Iterator<MailboxMembership<Long>> 
it=results.iterator();it.hasNext();) {
+                                       MailboxMembership<Long> member = 
it.next();
+                           if (member.isDeleted()) {
+                               filteredResult.add(member);
+                           }
+                       }
+                       }
+               });
+        
+               return filteredResult;
     }
 
     /*
@@ -220,31 +239,36 @@ public class InMemoryMessageMapper exten
         return add(mailbox, membership);
     }
 
-    public Iterator<UpdatedFlags> updateFlags(Mailbox<Long> mailbox, Flags 
flags, boolean value, boolean replace, MessageRange set) throws 
MailboxException {
+    public Iterator<UpdatedFlags> updateFlags(final Mailbox<Long> mailbox, 
final Flags flags, final boolean value, final boolean replace, MessageRange 
set) throws MailboxException {
         final List<UpdatedFlags> updatedFlags = new ArrayList<UpdatedFlags>();
 
-        final List<MailboxMembership<Long>> members = findInMailbox(mailbox, 
set);
-        for (final MailboxMembership<Long> member:members) {
-            Flags originalFlags = member.createFlags();
-            if (replace) {
-                member.setFlags(flags);
-            } else {
-                Flags current = member.createFlags();
-                if (value) {
-                    current.add(flags);
-                } else {
-                    current.remove(flags);
-                }
-                member.setFlags(current);
-            }
-            Flags newFlags = member.createFlags();
-            
-            add(mailbox, member);
-            
-            updatedFlags.add(new UpdatedFlags(member.getUid(),originalFlags, 
newFlags));
-        }
+        findInMailbox(mailbox, set, new MailboxMembershipCallback<Long>() {
+                       
+                       public void 
onMailboxMembers(List<MailboxMembership<Long>> members)
+                                       throws MailboxException {
+                               for (final MailboxMembership<Long> 
member:members) {
+                           Flags originalFlags = member.createFlags();
+                           if (replace) {
+                               member.setFlags(flags);
+                           } else {
+                               Flags current = member.createFlags();
+                               if (value) {
+                                   current.add(flags);
+                               } else {
+                                   current.remove(flags);
+                               }
+                               member.setFlags(current);
+                           }
+                           Flags newFlags = member.createFlags();
+                           
+                           add(mailbox, member);
+                           
+                           updatedFlags.add(new 
UpdatedFlags(member.getUid(),originalFlags, newFlags));
+                       }
+                               
+                       }
+               });
         
         return updatedFlags.iterator();       
     }
-    
 }

Modified: 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java?rev=1073920&r1=1073919&r2=1073920&view=diff
==============================================================================
--- 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
 (original)
+++ 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
 Wed Feb 23 20:05:21 2011
@@ -42,9 +42,10 @@ import org.apache.james.mailbox.MailboxE
 import org.apache.james.mailbox.MailboxListener;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageRange;
+import org.apache.james.mailbox.MessageRangeException;
 import org.apache.james.mailbox.MessageResult;
-import org.apache.james.mailbox.MessageResult.FetchGroup;
 import org.apache.james.mailbox.SearchQuery;
+import org.apache.james.mailbox.MessageResult.FetchGroup;
 import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.MessageMapperFactory;
 import org.apache.james.mailbox.store.mail.UidProvider;
@@ -56,6 +57,7 @@ import org.apache.james.mailbox.store.ma
 import org.apache.james.mailbox.store.streaming.ConfigurableMimeTokenStream;
 import org.apache.james.mailbox.store.streaming.CountingInputStream;
 import org.apache.james.mailbox.store.transaction.Mapper;
+import 
org.apache.james.mailbox.store.transaction.Mapper.MailboxMembershipCallback;
 import org.apache.james.mailbox.util.MailboxEventDispatcher;
 import org.apache.james.mime4j.MimeException;
 import org.apache.james.mime4j.descriptor.MaximalBodyDescriptor;
@@ -477,10 +479,33 @@ public abstract class StoreMessageManage
      */
     public Iterator<MessageResult> getMessages(final MessageRange set, 
FetchGroup fetchGroup,
             MailboxSession mailboxSession) throws MailboxException {
-        final List<MailboxMembership<Id>> rows = 
mapperFactory.getMessageMapper(mailboxSession).findInMailbox(getMailboxEntity(),
 set);
+        
+       final List<MailboxMembership<Id>> rows = new 
ArrayList<MailboxMembership<Id>>();
+       
+       
mapperFactory.getMessageMapper(mailboxSession).findInMailbox(getMailboxEntity(),
 set, new MailboxMembershipCallback<Id>() {
+                       public void 
onMailboxMembers(List<MailboxMembership<Id>> batchRows) throws MailboxException 
{
+                               rows.addAll(batchRows);
+                       }
+               });
+       
         return new ResultIterator<Id>(rows.iterator(), fetchGroup);
     }
 
+    /*
+     * (non-Javadoc)
+     * @see 
org.apache.james.mailbox.MessageManager#getMessages(org.apache.james.mailbox.MessageRange,
 org.apache.james.mailbox.MessageResult.FetchGroup, 
org.apache.james.mailbox.MailboxSession, int, 
org.apache.james.mailbox.MessageManager.MessageCallback)
+     */
+       public void getMessages(MessageRange set,
+                       final FetchGroup fetchGroup, MailboxSession 
mailboxSession,
+                       final MessageCallback messageCallback) throws 
MailboxException {
+       
+               
mapperFactory.getMessageMapper(mailboxSession).findInMailbox(getMailboxEntity(),
 set, new MailboxMembershipCallback<Id>() {
+                       public void 
onMailboxMembers(List<MailboxMembership<Id>> rows) throws MailboxException {
+                               messageCallback.onMessages(new 
ResultIterator<Id>(rows.iterator(), fetchGroup));
+                       }
+               });
+       }
+       
     /**
      * Return a List which holds all uids of recent messages and optional 
reset the recent flag on the messages for the uids
      * 
@@ -572,11 +597,21 @@ public abstract class StoreMessageManage
      * (non-Javadoc)
      * @see 
org.apache.james.mailbox.store.AbstractStoreMessageManager#copy(org.apache.james.mailbox.MessageRange,
 org.apache.james.mailbox.store.AbstractStoreMessageManager, 
org.apache.james.mailbox.MailboxSession)
      */
-    protected Iterator<Long> copy(MessageRange set, StoreMessageManager<Id> 
to, MailboxSession session) throws MailboxException {
+    protected Iterator<Long> copy(MessageRange set, final 
StoreMessageManager<Id> to, final MailboxSession session) throws 
MailboxException {
         try {
             MessageMapper<Id> messageMapper = 
mapperFactory.getMessageMapper(session);
-            final List<MailboxMembership<Id>> originalRows = 
messageMapper.findInMailbox(getMailboxEntity(), set);
-            return to.copy(originalRows, session);
+            
+            final List<Long> copiedMessages = new ArrayList<Long>();
+            messageMapper.findInMailbox(getMailboxEntity(), set, new 
MailboxMembershipCallback<Id>() {
+
+                               public void 
onMailboxMembers(List<MailboxMembership<Id>> originalRows)
+                                               throws MailboxException {
+                                       Iterator<Long> ids = 
to.copy(originalRows, session);
+                                       while(ids.hasNext())
+                                               copiedMessages.add(ids.next());
+                               }
+                       });
+            return copiedMessages.iterator(); 
 
         } catch (MailboxException e) {
             throw new MailboxException("Unable to parse message", e);

Modified: 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/MessageMapper.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/MessageMapper.java?rev=1073920&r1=1073919&r2=1073920&view=diff
==============================================================================
--- 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/MessageMapper.java
 (original)
+++ 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/MessageMapper.java
 Wed Feb 23 20:05:21 2011
@@ -39,17 +39,17 @@ import org.apache.james.mailbox.store.tr
 public interface MessageMapper<Id> extends Mapper {
 
     /**
-     * Return a List of {@link MailboxMembership} which represent the given 
{@link MessageRange}
+     * Return a List of {@link MailboxMembership} using {@link 
MailboxMembershipCallback<Id>} which represent the given {@link MessageRange}
      * The list must be ordered by the {@link Message} uid
      * 
      * @param mailbox The mailbox to search
-     * @param set
-     * @return list
+     * @param set message range for batch processing
+     * @param callback callback object 
      * @throws MailboxException
      */
-    public abstract List<MailboxMembership<Id>> findInMailbox(Mailbox<Id> 
mailbox, MessageRange set)
+    public abstract void findInMailbox(Mailbox<Id> mailbox, MessageRange set, 
MailboxMembershipCallback<Id> callback)
             throws MailboxException;
-
+    
     /**
      * Return a List of {@link MailboxMembership} for the given {@link 
MessageRange} which are marked for deletion
      * The list must be ordered by the {@link Message} uid

Modified: 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/transaction/Mapper.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/transaction/Mapper.java?rev=1073920&r1=1073919&r2=1073920&view=diff
==============================================================================
--- 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/transaction/Mapper.java
 (original)
+++ 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/transaction/Mapper.java
 Wed Feb 23 20:05:21 2011
@@ -19,7 +19,11 @@
 
 package org.apache.james.mailbox.store.transaction;
 
+import java.util.List;
+
 import org.apache.james.mailbox.MailboxException;
+import org.apache.james.mailbox.MessageRangeException;
+import org.apache.james.mailbox.store.mail.model.MailboxMembership;
 
 /**
  * Mapper which execute units of work in a {@link Transaction}
@@ -54,6 +58,10 @@ public interface Mapper {
         public T run() throws MailboxException;
     }
     
+    public interface MailboxMembershipCallback<Id> {
+       void onMailboxMembers(List<MailboxMembership<Id>> list) throws 
MailboxException;
+    }
+    
     public abstract class VoidTransaction implements Transaction<Void> {
         
         public final Void run() throws MailboxException {

Modified: 
james/mailbox/trunk/torque/src/main/java/org/apache/james/mailbox/torque/TorqueMailbox.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/torque/src/main/java/org/apache/james/mailbox/torque/TorqueMailbox.java?rev=1073920&r1=1073919&r2=1073920&view=diff
==============================================================================
--- 
james/mailbox/trunk/torque/src/main/java/org/apache/james/mailbox/torque/TorqueMailbox.java
 (original)
+++ 
james/mailbox/trunk/torque/src/main/java/org/apache/james/mailbox/torque/TorqueMailbox.java
 Wed Feb 23 20:05:21 2011
@@ -53,12 +53,15 @@ import org.apache.james.mailbox.MailboxS
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageRange;
 import org.apache.james.mailbox.MessageResult;
-import org.apache.james.mailbox.MessageResult.FetchGroup;
 import org.apache.james.mailbox.SearchQuery;
+import org.apache.james.mailbox.MessageResult.FetchGroup;
 import org.apache.james.mailbox.SearchQuery.Criterion;
 import org.apache.james.mailbox.SearchQuery.NumericRange;
 import org.apache.james.mailbox.store.MailboxMetaData;
+import org.apache.james.mailbox.store.ResultIterator;
+import org.apache.james.mailbox.store.mail.model.MailboxMembership;
 import org.apache.james.mailbox.store.streaming.CRLFOutputStream;
+import 
org.apache.james.mailbox.store.transaction.Mapper.MailboxMembershipCallback;
 import org.apache.james.mailbox.torque.om.MailboxRow;
 import org.apache.james.mailbox.torque.om.MailboxRowPeer;
 import org.apache.james.mailbox.torque.om.MessageBody;
@@ -328,16 +331,39 @@ public class TorqueMailbox implements Me
         return criteria;
     }
 
-    public Iterator getMessages(final MessageRange set, FetchGroup fetchGroup,
+    public Iterator<MessageResult> getMessages(final MessageRange set, 
FetchGroup fetchGroup,
             MailboxSession mailboxSession) throws MailboxException {
-        lockForReading();
+        
+       final List<MessageResult> rows = new ArrayList<MessageResult>();
+       
+       getMessages(set, fetchGroup, mailboxSession, new MessageCallback() {
+                       
+                       public void onMessages(Iterator<MessageResult> it) 
throws MailboxException {
+                               while(it.hasNext()) {
+                                       rows.add(it.next());
+                               }
+                       }
+               }); 
+       
+        return rows.iterator();
+    }
+
+       public void getMessages(MessageRange batchedSet,
+                       FetchGroup fetchGroup, MailboxSession mailboxSession,
+                       MessageCallback messageCallback) throws 
MailboxException {
+               lockForReading();
         try {
             checkAccess();
+
+            List<MessageRange> ranges = createRanges(batchedSet.getUidFrom(), 
batchedSet.getUidTo(), batchedSet.getBatchSize());
+            
             try {
-                Criteria c = criteriaForMessageSet(set);
-                c.add(MessageFlagsPeer.MAILBOX_ID, getMailboxRow()
-                        .getMailboxId());
-                return getMessages(fetchGroup, set, c, mailboxSession);
+               for(MessageRange set : ranges) {
+                       Criteria c = criteriaForMessageSet(set);
+                       c.add(MessageFlagsPeer.MAILBOX_ID, getMailboxRow()
+                               .getMailboxId());
+                       messageCallback.onMessages(getMessages(fetchGroup, set, 
c, mailboxSession));
+               }
             } catch (TorqueException e) {
                 throw new MailboxException("Search failed", e);
             } catch (MessagingException e) {
@@ -346,8 +372,26 @@ public class TorqueMailbox implements Me
         } finally {
             unlockAfterReading();
         }
-    }
-
+       }
+       
+       private List<MessageRange> createRanges(long start, long end, int 
batchSize) {
+         List<MessageRange> ranges = new ArrayList<MessageRange>();
+         if (start == end) {
+             ranges.add(MessageRange.one(start));
+         } else {
+             while (start < end) {
+                 long to = start + batchSize;
+                 if (to > end) {
+                     to = end;
+                 }
+                 MessageRange r = MessageRange.range(start, to);
+                 ranges.add(r);
+                 start = to;
+             }
+         }
+         return ranges;
+       }
+    
     @SuppressWarnings("unchecked")
     private TorqueResultIterator getMessages(FetchGroup result, MessageRange 
range,
             Criteria c, MailboxSession session) throws TorqueException, 
MessagingException,
@@ -857,4 +901,5 @@ public class TorqueMailbox implements Me
 
         return new MailboxMetaData(recent, permanentFlags, uidValidity, 
uidNext, messageCount, unseenCount, firstUnseen, isWriteable(mailboxSession));
     }
+
 }



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

Reply via email to