You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by no...@apache.org on 2011/08/18 20:20:59 UTC

svn commit: r1159343 - in /james/imap/trunk: ./ message/ message/src/main/java/org/apache/james/imap/decode/ message/src/main/java/org/apache/james/imap/encode/base/ message/src/main/java/org/apache/james/imap/utils/ message/src/main/java/org/apache/ja...

Author: norman
Date: Thu Aug 18 18:20:59 2011
New Revision: 1159343

URL: http://svn.apache.org/viewvc?rev=1159343&view=rev
Log:
Replace ByteArrayOutputStream with FastByteArrayOutputStream to remove unnecessary synchronization. See IMAP-331

Added:
    james/imap/trunk/message/src/main/java/org/apache/james/imap/utils/
    james/imap/trunk/message/src/main/java/org/apache/james/imap/utils/io/
    james/imap/trunk/message/src/main/java/org/apache/james/imap/utils/io/FastByteArrayOutputStream.java
Modified:
    james/imap/trunk/message/pom.xml
    james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/ImapRequestLineReader.java
    james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/base/ImapResponseComposerImpl.java
    james/imap/trunk/pom.xml

Modified: james/imap/trunk/message/pom.xml
URL: http://svn.apache.org/viewvc/james/imap/trunk/message/pom.xml?rev=1159343&r1=1159342&r2=1159343&view=diff
==============================================================================
--- james/imap/trunk/message/pom.xml (original)
+++ james/imap/trunk/message/pom.xml Thu Aug 18 18:20:59 2011
@@ -48,10 +48,6 @@
       <artifactId>commons-lang</artifactId>
     </dependency>
     <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-    </dependency>
-    <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <scope>test</scope>

Modified: james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/ImapRequestLineReader.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/ImapRequestLineReader.java?rev=1159343&r1=1159342&r2=1159343&view=diff
==============================================================================
--- james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/ImapRequestLineReader.java (original)
+++ james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/ImapRequestLineReader.java Thu Aug 18 18:20:59 2011
@@ -19,7 +19,6 @@
 
 package org.apache.james.imap.decode;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.ByteBuffer;
@@ -37,13 +36,13 @@ import java.util.List;
 
 import javax.mail.Flags;
 
-import org.apache.commons.io.IOUtils;
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.display.HumanReadableText;
 import org.apache.james.imap.api.message.IdRange;
 import org.apache.james.imap.api.message.request.DayMonthYear;
 import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.api.process.SearchResUtil;
+import org.apache.james.imap.utils.io.FastByteArrayOutputStream;
 
 /**
  * Wraps the client input reader with a bunch of convenience methods, allowing
@@ -357,15 +356,31 @@ public abstract class ImapRequestLineRea
         if (charset == null) {
             return consumeLiteral(US_ASCII);
         } else {
-            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            FastByteArrayOutputStream out = new FastByteArrayOutputStream();
+            InputStream in = null;
             try {
-                IOUtils.copy(consumeLiteral(false), out);
+            	in = consumeLiteral(false);
+            	byte[] buf = new byte[ 0xFFFF ]; 
+                
+            	for (int len; (len = in.read(buf)) != -1; ) 
+                    out.write( buf, 0, len ); 
+                
+                final byte[] bytes = out.toByteArray();
+                final ByteBuffer buffer = ByteBuffer.wrap(bytes);
+                return decode(charset, buffer);
+                
             } catch (IOException e) {
                 throw new DecodingException(HumanReadableText.BAD_IO_ENCODING, "Bad character encoding", e);
+            } finally {
+            	if (in != null) {
+            		try {
+            			in.close();
+            		} catch (IOException e) {
+            			// ignore on close
+            		}
+            	}
             }
-            final byte[] bytes = out.toByteArray();
-            final ByteBuffer buffer = ByteBuffer.wrap(bytes);
-            return decode(charset, buffer);
+
         }
     }
 

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=1159343&r1=1159342&r2=1159343&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 Thu Aug 18 18:20:59 2011
@@ -25,13 +25,13 @@ import java.nio.charset.Charset;
 
 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.api.message.IdRange;
 import org.apache.james.imap.encode.ImapResponseComposer;
 import org.apache.james.imap.encode.ImapResponseWriter;
 import org.apache.james.imap.message.response.Literal;
+import org.apache.james.imap.utils.io.FastByteArrayOutputStream;
 
 /**
  * Class providing methods to send response messages from the server to the
@@ -42,21 +42,27 @@ public class ImapResponseComposerImpl im
     public static final String FLAGS = "FLAGS";
 
     public static final String FAILED = "failed.";
-
+    private static final int LOWER_CASE_OFFSET = 'a' - 'A';
+    public final static int DEFAULT_BUFFER_SIZE = 2048;
+    
+    
     private final ImapResponseWriter writer;
 
-    private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-
-    private static final int LOWER_CASE_OFFSET = 'a' - 'A';
+    private final FastByteArrayOutputStream buffer;
 
     private final Charset usAscii;
 
     private boolean skipNextSpace;
 
-    public ImapResponseComposerImpl(final ImapResponseWriter writer) {
+    public ImapResponseComposerImpl(final ImapResponseWriter writer, int bufferSize) {
         skipNextSpace = false;
         usAscii = Charset.forName("US-ASCII");
         this.writer = writer;
+        this.buffer = new FastByteArrayOutputStream(bufferSize);
+    }
+    
+    public ImapResponseComposerImpl(final ImapResponseWriter writer) {
+        this(writer, DEFAULT_BUFFER_SIZE);
     }
 
     /*

Added: james/imap/trunk/message/src/main/java/org/apache/james/imap/utils/io/FastByteArrayOutputStream.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/utils/io/FastByteArrayOutputStream.java?rev=1159343&view=auto
==============================================================================
--- james/imap/trunk/message/src/main/java/org/apache/james/imap/utils/io/FastByteArrayOutputStream.java (added)
+++ james/imap/trunk/message/src/main/java/org/apache/james/imap/utils/io/FastByteArrayOutputStream.java Thu Aug 18 18:20:59 2011
@@ -0,0 +1,233 @@
+package org.apache.james.imap.utils.io;
+
+/**
+ *  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.
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * This class was forked from cassandra:
+ * 
+ * http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/io/util/FastByteArrayOutputStream.java?view=co
+ */
+
+/**
+ * A specialized {@link OutputStream} for class for writing content to an
+ * (internal) byte array. As bytes are written to this stream, the byte array
+ * may be expanded to hold more bytes. When the writing is considered to be
+ * finished, a copy of the byte array can be requested from the class.
+ * 
+ * @see ByteArrayOutputStream
+ */
+public class FastByteArrayOutputStream extends OutputStream {
+    /**
+     * The byte array containing the bytes written.
+     */
+    protected byte[] buf;
+
+    /**
+     * The number of bytes written.
+     */
+    protected int count;
+
+    /**
+     * Constructs a new ByteArrayOutputStream with a default size of 32 bytes.
+     * If more than 32 bytes are written to this instance, the underlying byte
+     * array will expand.
+     */
+    public FastByteArrayOutputStream() {
+        buf = new byte[32];
+    }
+
+    /**
+     * Constructs a new {@code ByteArrayOutputStream} with a default size of
+     * {@code size} bytes. If more than {@code size} bytes are written to this
+     * instance, the underlying byte array will expand.
+     * 
+     * @param size
+     *            initial size for the underlying byte array, must be
+     *            non-negative.
+     * @throws IllegalArgumentException
+     *             if {@code size} < 0.
+     */
+    public FastByteArrayOutputStream(int size) {
+        if (size >= 0) {
+            buf = new byte[size];
+        } else {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    private void expand(int i) {
+        /* Can the buffer handle @i more bytes, if not expand it */
+        if (count + i <= buf.length) {
+            return;
+        }
+
+        byte[] newbuf = new byte[(count + i) * 2];
+        System.arraycopy(buf, 0, newbuf, 0, count);
+        buf = newbuf;
+    }
+
+    /**
+     * Resets this stream to the beginning of the underlying byte array. All
+     * subsequent writes will overwrite any bytes previously stored in this
+     * stream.
+     */
+    public void reset() {
+        count = 0;
+    }
+
+    /**
+     * Returns the total number of bytes written to this stream so far.
+     * 
+     * @return the number of bytes written to this stream.
+     */
+    public int size() {
+        return count;
+    }
+
+    /**
+     * Returns the contents of this ByteArrayOutputStream as a byte array. Any
+     * changes made to the receiver after returning will not be reflected in the
+     * byte array returned to the caller.
+     * 
+     * @return this stream's current contents as a byte array.
+     */
+    public byte[] toByteArray() {
+        byte[] newArray = new byte[count];
+        System.arraycopy(buf, 0, newArray, 0, count);
+        return newArray;
+    }
+
+    /**
+     * Returns the contents of this ByteArrayOutputStream as a string. Any
+     * changes made to the receiver after returning will not be reflected in the
+     * string returned to the caller.
+     * 
+     * @return this stream's current contents as a string.
+     */
+
+    @Override
+    public String toString() {
+        return new String(buf, 0, count);
+    }
+
+    /**
+     * Returns the contents of this ByteArrayOutputStream as a string. Each byte
+     * {@code b} in this stream is converted to a character {@code c} using the
+     * following function:
+     * {@code c == (char)(((hibyte & 0xff) << 8) | (b & 0xff))}. This method is
+     * deprecated and either {@link #toString()} or {@link #toString(String)}
+     * should be used.
+     * 
+     * @param hibyte
+     *            the high byte of each resulting Unicode character.
+     * @return this stream's current contents as a string with the high byte set
+     *         to {@code hibyte}.
+     * @deprecated Use {@link #toString()}.
+     */
+    @Deprecated
+    public String toString(int hibyte) {
+        char[] newBuf = new char[size()];
+        for (int i = 0; i < newBuf.length; i++) {
+            newBuf[i] = (char) (((hibyte & 0xff) << 8) | (buf[i] & 0xff));
+        }
+        return new String(newBuf);
+    }
+
+    /**
+     * Returns the contents of this ByteArrayOutputStream as a string converted
+     * according to the encoding declared in {@code enc}.
+     * 
+     * @param enc
+     *            a string representing the encoding to use when translating
+     *            this stream to a string.
+     * @return this stream's current contents as an encoded string.
+     * @throws UnsupportedEncodingException
+     *             if the provided encoding is not supported.
+     */
+    public String toString(String enc) throws UnsupportedEncodingException {
+        return new String(buf, 0, count, enc);
+    }
+
+    /**
+     * Writes {@code count} bytes from the byte array {@code buffer} starting at
+     * offset {@code index} to this stream.
+     * 
+     * @param buffer
+     *            the buffer to be written.
+     * @param offset
+     *            the initial position in {@code buffer} to retrieve bytes.
+     * @param len
+     *            the number of bytes of {@code buffer} to write.
+     * @throws NullPointerException
+     *             if {@code buffer} is {@code null}.
+     * @throws IndexOutOfBoundsException
+     *             if {@code offset < 0} or {@code len < 0}, or if
+     *             {@code offset + len} is greater than the length of
+     *             {@code buffer}.
+     */
+    @Override
+    public void write(byte[] buffer, int offset, int len) {
+        // avoid int overflow
+        if (offset < 0 || offset > buffer.length || len < 0
+                || len > buffer.length - offset) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (len == 0) {
+            return;
+        }
+
+        /* Expand if necessary */
+        expand(len);
+        System.arraycopy(buffer, offset, buf, this.count, len);
+        this.count += len;
+    }
+
+    /**
+     * Writes the specified byte {@code oneByte} to the OutputStream. Only the
+     * low order byte of {@code oneByte} is written.
+     * 
+     * @param oneByte
+     *            the byte to be written.
+     */
+    @Override
+    public void write(int oneByte) {
+        if (count == buf.length) {
+            expand(1);
+        }
+        buf[count++] = (byte) oneByte;
+    }
+
+    /**
+     * Takes the contents of this stream and writes it to the output stream
+     * {@code out}.
+     * 
+     * @param out
+     *            an OutputStream on which to write the contents of this stream.
+     * @throws IOException
+     *             if an error occurs while writing to {@code out}.
+     */
+    public void writeTo(OutputStream out) throws IOException {
+        out.write(buf, 0, count);
+    }
+}
+

Modified: james/imap/trunk/pom.xml
URL: http://svn.apache.org/viewvc/james/imap/trunk/pom.xml?rev=1159343&r1=1159342&r2=1159343&view=diff
==============================================================================
--- james/imap/trunk/pom.xml (original)
+++ james/imap/trunk/pom.xml Thu Aug 18 18:20:59 2011
@@ -551,11 +551,6 @@
         <version>${version.jmock}</version>
         <scope>test</scope>
       </dependency>
-      <dependency>
-        <groupId>commons-io</groupId>
-        <artifactId>commons-io</artifactId>
-        <version>2.0.1</version>
-      </dependency>
       
 
       <!--



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org