- With Comet support, it is necessary to optimize the amount of memory used by individual
authorremm <remm@13f79535-47bb-0310-9956-ffa450edef68>
Sun, 4 Jun 2006 15:01:39 +0000 (15:01 +0000)
committerremm <remm@13f79535-47bb-0310-9956-ffa450edef68>
Sun, 4 Jun 2006 15:01:39 +0000 (15:01 +0000)
  processors. This removes most of the buffers that are being used, without reducing performance
  in many cases.
- Note: I'm not sure the algorithm in InternalAprInputBuffer.nextRequest, which is used when
  pipelining, is correct. It also could use free space in the buffer more efficiently when trimming
  it.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk@411576 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/coyote/http11/InternalAprInputBuffer.java
java/org/apache/coyote/http11/InternalAprOutputBuffer.java

index f40429c..699e2f8 100644 (file)
@@ -55,14 +55,12 @@ public class InternalAprInputBuffer implements InputBuffer {
         this.request = request;\r
         headers = request.getMimeHeaders();\r
 \r
-        headerBuffer1 = new byte[headerBufferSize];\r
-        headerBuffer2 = new byte[headerBufferSize];\r
-        bodyBuffer = new byte[headerBufferSize];\r
-        buf = headerBuffer1;\r
-        bbuf = ByteBuffer.allocateDirect(headerBufferSize);\r
-\r
-        headerBuffer = new char[headerBufferSize];\r
-        ascbuf = headerBuffer;\r
+        buf = new byte[headerBufferSize];\r
+        if (headerBufferSize < (8 * 1024)) {\r
+            bbuf = ByteBuffer.allocateDirect(6 * 1500);\r
+        } else {\r
+            bbuf = ByteBuffer.allocateDirect((headerBufferSize / 1500 + 1) * 1500);\r
+        }\r
 \r
         inputStreamInputBuffer = new SocketInputBuffer();\r
 \r
@@ -126,12 +124,6 @@ public class InternalAprInputBuffer implements InputBuffer {
 \r
 \r
     /**\r
-     * Pointer to the US-ASCII header buffer.\r
-     */\r
-    protected char[] ascbuf;\r
-\r
-\r
-    /**\r
      * Last valid byte.\r
      */\r
     protected int lastValid;\r
@@ -144,27 +136,10 @@ public class InternalAprInputBuffer implements InputBuffer {
 \r
 \r
     /**\r
-     * HTTP header buffer no 1.\r
-     */\r
-    protected byte[] headerBuffer1;\r
-\r
-\r
-    /**\r
-     * HTTP header buffer no 2.\r
-     */\r
-    protected byte[] headerBuffer2;\r
-\r
-\r
-    /**\r
-     * HTTP body buffer.\r
+     * Pos of the end of the header in the buffer, which is also the\r
+     * start of the body.\r
      */\r
-    protected byte[] bodyBuffer;\r
-\r
-\r
-    /**\r
-     * US-ASCII header buffer.\r
-     */\r
-    protected char[] headerBuffer;\r
+    protected int end;\r
 \r
 \r
     /**\r
@@ -313,7 +288,6 @@ public class InternalAprInputBuffer implements InputBuffer {
         request.recycle();\r
 \r
         socket = 0;\r
-        buf = headerBuffer1;\r
         lastValid = 0;\r
         pos = 0;\r
         lastActiveFilter = -1;\r
@@ -334,20 +308,19 @@ public class InternalAprInputBuffer implements InputBuffer {
         // Recycle Request object\r
         request.recycle();\r
 \r
-        // Determine the header buffer used for next request\r
-        byte[] newHeaderBuf = null;\r
-        if (buf == headerBuffer1) {\r
-            newHeaderBuf = headerBuffer2;\r
-        } else {\r
-            newHeaderBuf = headerBuffer1;\r
+        //System.out.println("LV-pos: " + (lastValid - pos));\r
+        // Copy leftover bytes to the beginning of the buffer\r
+        if (lastValid - pos > 0) {\r
+            int npos = 0;\r
+            int opos = pos;\r
+            while (lastValid - opos > opos - npos) {\r
+                System.arraycopy(buf, opos, buf, npos, opos - npos);\r
+                npos += pos;\r
+                opos += pos;\r
+            }\r
+            System.arraycopy(buf, opos, buf, npos, lastValid - opos);\r
         }\r
-\r
-        // Copy leftover bytes from buf to newHeaderBuf\r
-        System.arraycopy(buf, pos, newHeaderBuf, 0, lastValid - pos);\r
-\r
-        // Swap buffers\r
-        buf = newHeaderBuf;\r
-\r
+        \r
         // Recycle filters\r
         for (int i = 0; i <= lastActiveFilter; i++) {\r
             activeFilters[i].recycle();\r
@@ -479,11 +452,9 @@ public class InternalAprInputBuffer implements InputBuffer {
                     throw new EOFException(sm.getString("iib.eof.error"));\r
             }\r
 \r
-            ascbuf[pos] = (char) buf[pos];\r
-\r
             if (buf[pos] == Constants.SP) {\r
                 space = true;\r
-                request.method().setChars(ascbuf, start, pos - start);\r
+                request.method().setBytes(buf, start, pos - start);\r
             }\r
 \r
             pos++;\r
@@ -554,8 +525,6 @@ public class InternalAprInputBuffer implements InputBuffer {
                     throw new EOFException(sm.getString("iib.eof.error"));\r
             }\r
 \r
-            ascbuf[pos] = (char) buf[pos];\r
-\r
             if (buf[pos] == Constants.CR) {\r
                 end = pos;\r
             } else if (buf[pos] == Constants.LF) {\r
@@ -569,7 +538,7 @@ public class InternalAprInputBuffer implements InputBuffer {
         }\r
 \r
         if ((end - start) > 0) {\r
-            request.protocol().setChars(ascbuf, start, end - start);\r
+            request.protocol().setBytes(buf, start, end - start);\r
         } else {\r
             request.protocol().setString("");\r
         }\r
@@ -589,6 +558,7 @@ public class InternalAprInputBuffer implements InputBuffer {
         }\r
 \r
         parsingHeader = false;\r
+        end = pos;\r
 \r
     }\r
 \r
@@ -651,15 +621,13 @@ public class InternalAprInputBuffer implements InputBuffer {
 \r
             if (buf[pos] == Constants.COLON) {\r
                 colon = true;\r
-                headerValue = headers.addValue(ascbuf, start, pos - start);\r
+                headerValue = headers.addValue(buf, start, pos - start);\r
             }\r
             chr = buf[pos];\r
             if ((chr >= Constants.A) && (chr <= Constants.Z)) {\r
                 buf[pos] = (byte) (chr - Constants.LC_OFFSET);\r
             }\r
 \r
-            ascbuf[pos] = (char) buf[pos];\r
-\r
             pos++;\r
 \r
         }\r
@@ -793,8 +761,7 @@ public class InternalAprInputBuffer implements InputBuffer {
             }\r
 \r
             bbuf.clear();\r
-            nRead = Socket.recvbb\r
-                (socket, 0, buf.length - lastValid);\r
+            nRead = Socket.recvbb(socket, 0, buf.length - lastValid);\r
             if (nRead > 0) {\r
                 bbuf.limit(nRead);\r
                 bbuf.get(buf, pos, nRead);\r
@@ -809,16 +776,21 @@ public class InternalAprInputBuffer implements InputBuffer {
 \r
         } else {\r
 \r
-            buf = bodyBuffer;\r
-            pos = 0;\r
-            lastValid = 0;\r
+            if (buf.length - end < 4500) {\r
+                // In this case, the request header was really large, so we allocate a \r
+                // brand new one; the old one will get GCed when subsequent requests\r
+                // clear all references\r
+                buf = new byte[buf.length];\r
+                end = 0;\r
+            }\r
+            pos = end;\r
+            lastValid = pos;\r
             bbuf.clear();\r
-            nRead = Socket.recvbb\r
-                (socket, 0, buf.length);\r
+            nRead = Socket.recvbb(socket, 0, buf.length - lastValid);\r
             if (nRead > 0) {\r
                 bbuf.limit(nRead);\r
-                bbuf.get(buf, 0, nRead);\r
-                lastValid = nRead;\r
+                bbuf.get(buf, pos, nRead);\r
+                lastValid = pos + nRead;\r
             } else {\r
                 throw new IOException(sm.getString("iib.failedread"));\r
             }\r
index 5f73738..e153dd9 100644 (file)
@@ -62,10 +62,12 @@ public class InternalAprOutputBuffer
         this.response = response;\r
         headers = response.getMimeHeaders();\r
 \r
-        headerBuffer = new byte[headerBufferSize];\r
-        buf = headerBuffer;\r
-\r
-        bbuf = ByteBuffer.allocateDirect((headerBufferSize / 1500 + 1) * 1500);\r
+        buf = new byte[headerBufferSize];\r
+        if (headerBufferSize < (8 * 1024)) {\r
+            bbuf = ByteBuffer.allocateDirect(6 * 1500);\r
+        } else {\r
+            bbuf = ByteBuffer.allocateDirect((headerBufferSize / 1500 + 1) * 1500);\r
+        }\r
 \r
         outputStreamOutputBuffer = new SocketOutputBuffer();\r
 \r
@@ -120,7 +122,7 @@ public class InternalAprOutputBuffer
 \r
 \r
     /**\r
-     * Pointer to the current read buffer.\r
+     * Pointer to the current write buffer.\r
      */\r
     protected byte[] buf;\r
 \r
@@ -132,12 +134,6 @@ public class InternalAprOutputBuffer
 \r
 \r
     /**\r
-     * HTTP header buffer.\r
-     */\r
-    protected byte[] headerBuffer;\r
-\r
-\r
-    /**\r
      * Underlying socket.\r
      */\r
     protected long socket;\r
@@ -316,7 +312,6 @@ public class InternalAprOutputBuffer
         bbuf.clear();\r
 \r
         socket = 0;\r
-        buf = headerBuffer;\r
         pos = 0;\r
         lastActiveFilter = -1;\r
         committed = false;\r
@@ -336,9 +331,6 @@ public class InternalAprOutputBuffer
         // Recycle Request object\r
         response.recycle();\r
 \r
-        // Determine the header buffer used for next request\r
-        buf = headerBuffer;\r
-\r
         // Recycle filters\r
         for (int i = 0; i <= lastActiveFilter; i++) {\r
             activeFilters[i].recycle();\r