Author: norman
Date: Tue Apr 26 18:57:52 2011
New Revision: 1096852

URL: http://svn.apache.org/viewvc?rev=1096852&view=rev
Log:
Buffer writes until end() or literal( ) is called to gain better performance. 
See IMAP-277

Modified:
    
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseComposer.java
    
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/base/ImapResponseComposerImpl.java
    
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/base/ImapResponseComposerImplTest.java

Modified: 
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseComposer.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseComposer.java?rev=1096852&r1=1096851&r2=1096852&view=diff
==============================================================================
--- 
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseComposer.java
 (original)
+++ 
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseComposer.java
 Tue Apr 26 18:57:52 2011
@@ -42,7 +42,7 @@ public interface ImapResponseComposer {
     public ImapResponseComposer untaggedNoResponse(String displayMessage, 
String responseCode) throws IOException;
 
     /**
-     * Writes flags to output using standard format.
+     * Compose flags to output using standard format.
      * 
      * @param flags
      *            <code>Flags</code>, not null
@@ -50,19 +50,47 @@ public interface ImapResponseComposer {
     public ImapResponseComposer flags(Flags flags) throws IOException;
 
     /**
-     * Writes a complete FLAGS response.
+     * Compose a complete FLAGS response.
      * 
      * @param flags
      *            <code>Flags</code>, not null
      */
     public ImapResponseComposer flagsResponse(Flags flags) throws IOException;
 
+    /**
+     * Compose a complete EXISTS response
+     * 
+     * @param count the message count that exists
+     * @return self
+     * @throws IOException
+     */
     public ImapResponseComposer existsResponse(long count) throws IOException;
 
+    /**
+     * Compose a RECENT response
+     * 
+     * @param count the message count which is marked as recent
+     * @return self
+     * @throws IOException
+     */
     public ImapResponseComposer recentResponse(long count) throws IOException;
 
+    /**
+     * Compose a EXPUNGE response
+     * 
+     * @param msn the MSN which where expunged
+     * @return self
+     * @throws IOException
+     */
     public ImapResponseComposer expungeResponse(long msn) throws IOException;
 
+    /**
+     * Compose a SEARCH response
+     * 
+     * @param ids the MSN or UID which were found
+     * @return  self
+     * @throws IOException
+     */
     public ImapResponseComposer searchResponse(long[] ids) throws IOException;
 
     /**
@@ -141,6 +169,14 @@ public interface ImapResponseComposer {
      */
     public ImapResponseComposer nil() throws IOException;
 
+    /**
+     * Compose a response which contains the {@link ImapCommand} to which the 
response belongs
+     * 
+     * @param command
+     * @param message
+     * @return self
+     * @throws IOException
+     */
     public ImapResponseComposer commandResponse(ImapCommand command, String 
message) throws IOException;
 
     /**
@@ -175,8 +211,22 @@ public interface ImapResponseComposer {
      */
     public ImapResponseComposer untaggedResponse(String message) throws 
IOException;
 
+    /**
+     * Compose a BYE response
+     * 
+     * @param message
+     * @return self
+     * @throws IOException
+     */
     public ImapResponseComposer byeResponse(String message) throws IOException;
 
+    /**
+     * Compose a HELLO response
+     * 
+     * @param message
+     * @return self
+     * @throws IOException
+     */
     public ImapResponseComposer hello(String message) throws IOException;
 
     public ImapResponseComposer untagged() throws IOException;
@@ -187,6 +237,12 @@ public interface ImapResponseComposer {
 
     public ImapResponseComposer message(final long number) throws IOException;
 
+    /**
+     * Write a CRLF and flush the composer which will write the content of it 
to the socket
+     * 
+     * @return composer
+     * @throws IOException
+     */
     public ImapResponseComposer end() throws IOException;
 
     public ImapResponseComposer tag(String tag) throws IOException;
@@ -195,9 +251,17 @@ public interface ImapResponseComposer {
 
     public ImapResponseComposer statusResponse(Long messages, Long recent, 
Long uidNext, Long uidValidity, Long unseen, String mailboxName) throws 
IOException;
 
-    public void quote(String message) throws IOException;
+    public ImapResponseComposer quote(String message) throws IOException;
 
-    public void literal(Literal literal) throws IOException;
+    /**
+     * Compose a {@link Literal} and write it to the socket. Everything which 
was buffered before will
+     * get written too
+     * 
+     * @param literal
+     * @return self
+     * @throws IOException
+     */
+    public ImapResponseComposer literal(Literal literal) throws IOException;
 
     public ImapResponseComposer openParen() throws IOException;
 
@@ -266,7 +330,13 @@ public interface ImapResponseComposer {
      */
     public ImapResponseComposer nillableComposition(String masterQuote, 
List<String> quotes) throws IOException;
 
-    public void skipNextSpace() throws IOException;
+    /**
+     * Tell the {@link ImapResponseComposer} to skip the next written space
+     * 
+     * @return composer
+     * @throws IOException
+     */
+    public ImapResponseComposer skipNextSpace() throws IOException;
 
     /**
      * Composes a <code>CAPABILITY</code> response. See <code>7.2.1</code> of 
<a

Modified: 
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/base/ImapResponseComposerImpl.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/base/ImapResponseComposerImpl.java?rev=1096852&r1=1096851&r2=1096852&view=diff
==============================================================================
--- 
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/base/ImapResponseComposerImpl.java
 (original)
+++ 
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/base/ImapResponseComposerImpl.java
 Tue Apr 26 18:57:52 2011
@@ -28,6 +28,7 @@ import java.util.List;
 
 import javax.mail.Flags;
 
+import org.apache.commons.io.output.ByteArrayOutputStream;
 import org.apache.james.imap.api.ImapCommand;
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.encode.ImapResponseComposer;
@@ -56,23 +57,16 @@ public class ImapResponseComposerImpl im
 
     private final ImapResponseWriter writer;
 
-    public ImapResponseComposerImpl(final ImapResponseWriter writer) {
-        this(writer, DEFAULT_BUFFER_SIZE);
-    }
+    private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
 
     private static final int LOWER_CASE_OFFSET = 'a' - 'A';
 
-    private static final int DEFAULT_BUFFER_SIZE = 128;
-
     private final Charset usAscii;
 
-    private final ByteBuffer buffer;
-
     private boolean skipNextSpace;
 
-    public ImapResponseComposerImpl(final ImapResponseWriter writer, final int 
bufferSize) {
+    public ImapResponseComposerImpl(final ImapResponseWriter writer) {
         skipNextSpace = false;
-        buffer = ByteBuffer.allocate(bufferSize);
         usAscii = Charset.forName("US-ASCII");
         this.writer = writer;
     }
@@ -261,7 +255,7 @@ public class ImapResponseComposerImpl im
         if (responseCode != null && !"".equals(responseCode)) {
             writeASCII(" [");
             writeASCII(responseCode);
-            write(BYTE_CLOSE_SQUARE_BRACKET);
+            buffer.write(BYTE_CLOSE_SQUARE_BRACKET);
         }
     }
 
@@ -271,7 +265,9 @@ public class ImapResponseComposerImpl im
      * @see org.apache.james.imap.encode.ImapResponseComposer#end()
      */
     public ImapResponseComposer end() throws IOException {
-        write(LINE_END.getBytes());
+        buffer.write(LINE_END.getBytes());
+        writer.write(ByteBuffer.wrap(buffer.toByteArray()));
+        buffer.reset();
         return this;
     }
 
@@ -693,18 +689,7 @@ public class ImapResponseComposerImpl im
     }
 
     private void writeASCII(final String string) throws IOException {
-        final ByteBuffer buffer = usAscii.encode(string);
-        writer.write(buffer);
-    }
-
-    private void write(byte[] bytes) throws IOException {
-        final ByteBuffer wrap = ByteBuffer.wrap(bytes);
-        writer.write(wrap);
-    }
-
-    private void write(byte b) throws IOException {
-        final ByteBuffer wrap = ByteBuffer.wrap(new byte[] { b });
-        writer.write(wrap);
+        buffer.write(string.getBytes(usAscii));
     }
 
     /*
@@ -737,47 +722,36 @@ public class ImapResponseComposerImpl im
      * @see
      * 
org.apache.james.imap.encode.ImapResponseComposer#quote(java.lang.String)
      */
-    public void quote(String message) throws IOException {
+    public ImapResponseComposer quote(String message) throws IOException {
         space();
         final int length = message.length();
-        buffer.clear();
-        buffer.put(BYTE_DQUOTE);
+       
+        buffer.write(BYTE_DQUOTE);
         for (int i = 0; i < length; i++) {
-            writeIfFull();
             char character = message.charAt(i);
             if (character == ImapConstants.BACK_SLASH || character == DQUOTE) {
-                buffer.put(BYTE_BACK_SLASH);
+                buffer.write(BYTE_BACK_SLASH);
             }
-            writeIfFull();
             // 7-bit ASCII only
             if (character > 128) {
-                buffer.put(BYTE_QUESTION);
+                buffer.write(BYTE_QUESTION);
             } else {
-                buffer.put((byte) character);
+                buffer.write((byte) character);
             }
         }
-        writeIfFull();
-        buffer.put(BYTE_DQUOTE);
-        buffer.flip();
-        writer.write(buffer);
+        buffer.write(BYTE_DQUOTE);
+        return this;
     }
 
-    private void writeIfFull() throws IOException {
-        if (!buffer.hasRemaining()) {
-            buffer.flip();
-            writer.write(buffer);
-            buffer.clear();
-        }
-    }
 
     private void closeBracket(final byte bracket) throws IOException {
-        write(bracket);
+        buffer.write(bracket);
         clearSkipNextSpace();
     }
 
     private void openBracket(final byte bracket) throws IOException {
         space();
-        write(bracket);
+        buffer.write(bracket);
         skipNextSpace();
     }
 
@@ -790,15 +764,16 @@ public class ImapResponseComposerImpl im
      * 
      * @see org.apache.james.imap.encode.ImapResponseComposer#skipNextSpace()
      */
-    public void skipNextSpace() {
+    public ImapResponseComposer skipNextSpace() {
         skipNextSpace = true;
+        return this;
     }
 
     private void space() throws IOException {
         if (skipNextSpace) {
             skipNextSpace = false;
         } else {
-            write(SP.getBytes());
+            buffer.write(SP.getBytes());
         }
     }
 
@@ -809,16 +784,17 @@ public class ImapResponseComposerImpl im
      * org.apache.james.imap.encode.ImapResponseComposer#literal(org.apache.
      * james.imap.message.response.Literal)
      */
-    public void literal(Literal literal) throws IOException {
+    public ImapResponseComposer literal(Literal literal) throws IOException {
         space();
-        write(BYTE_OPEN_BRACE);
+        buffer.write(BYTE_OPEN_BRACE);
         final long size = literal.size();
         writeASCII(Long.toString(size));
-        write(BYTE_CLOSE_BRACE);
-        write(LINE_END.getBytes());
+        buffer.write(BYTE_CLOSE_BRACE);
+        end();
         if (size > 0) {
             writer.write(literal);
         }
+        return this;
     }
 
     private void closeSquareBracket() throws IOException {
@@ -832,25 +808,20 @@ public class ImapResponseComposerImpl im
     private void upperCaseAscii(String message, boolean quote) throws 
IOException {
         space();
         final int length = message.length();
-        buffer.clear();
         if (quote) {
-            buffer.put(BYTE_DQUOTE);
+            buffer.write(BYTE_DQUOTE);
         }
         for (int i = 0; i < length; i++) {
-            writeIfFull();
             final char next = message.charAt(i);
             if (next >= 'a' && next <= 'z') {
-                buffer.put((byte) (next - LOWER_CASE_OFFSET));
+                buffer.write((byte) (next - LOWER_CASE_OFFSET));
             } else {
-                buffer.put((byte) (next));
+                buffer.write((byte) (next));
             }
         }
-        writeIfFull();
         if (quote) {
-            buffer.put(BYTE_DQUOTE);
+            buffer.write(BYTE_DQUOTE);
         }
-        buffer.flip();
-        writer.write(buffer);
     }
 
 }

Modified: 
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/base/ImapResponseComposerImplTest.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/base/ImapResponseComposerImplTest.java?rev=1096852&r1=1096851&r2=1096852&view=diff
==============================================================================
--- 
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/base/ImapResponseComposerImplTest.java
 (original)
+++ 
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/base/ImapResponseComposerImplTest.java
 Tue Apr 26 18:57:52 2011
@@ -45,7 +45,8 @@ public class ImapResponseComposerImplTes
     protected byte[] encodeListResponse(String typeName, List<String> 
attributes,
             char hierarchyDelimiter, String name) throws Exception {
         composer.listResponse(typeName, attributes, hierarchyDelimiter, name);
-        return writer.getBytes();
+        composer.end();
+        return removeCRLF(writer.getBytes());
     }
 
     protected void clear() throws Exception {
@@ -54,12 +55,14 @@ public class ImapResponseComposerImplTes
 
     protected byte[] encodeSearchResponse(long[] ids) throws Exception {
         composer.searchResponse(ids);
-        return writer.getBytes();
+        composer.end();
+        return removeCRLF(writer.getBytes());
     }
 
     protected byte[] encodeFlagsResponse(Flags flags) throws Exception {
         composer.flags(flags);
-        return writer.getBytes();
+        composer.end();
+        return removeCRLF(writer.getBytes());
     }
 
     protected byte[] encodeStatusResponse(Long messages, Long recent,
@@ -67,7 +70,8 @@ public class ImapResponseComposerImplTes
             throws Exception {
         composer.statusResponse(messages, recent, uidNext, uidValidity, unseen,
                 mailbox);
-        return writer.getBytes();
+        composer.end();
+        return removeCRLF(writer.getBytes());
     }
 
     protected byte[] encodeStatusResponse(String tag, ImapCommand command,
@@ -75,7 +79,19 @@ public class ImapResponseComposerImplTes
             boolean useParens, int number, String text) throws Exception {
         composer.statusResponse(tag, command, type, responseCode, parameters,
                 useParens, number, text);
-        return writer.getBytes();
+        composer.end();
+        return removeCRLF(writer.getBytes());
+    }
+    
+    private byte[] removeCRLF(byte[] b) {
+        if (b.length > 2) {
+            byte[] newB = new byte[b.length -2];
+            System.arraycopy(b, 0, newB, 0, newB.length);
+            return newB;
+        } else {
+            return b;
+        }
+        
     }
 
 }



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

Reply via email to