You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2005/05/14 22:41:26 UTC

cvs commit: jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11 InternalAprOutputBuffer.java

remm        2005/05/14 13:41:26

  Modified:    http11/src/java/org/apache/coyote/http11
                        InternalAprOutputBuffer.java
  Log:
  - Optimize a little using a direct byte buffer to replace the socket buffer.
  - I'll experiment with doing the same optimization for reads, but I don't expect it to do anything
    (other than waste memory) as copying bytes will be needed.
  
  Revision  Changes    Path
  1.3       +25 -45    jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/InternalAprOutputBuffer.java
  
  Index: InternalAprOutputBuffer.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/InternalAprOutputBuffer.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- InternalAprOutputBuffer.java	20 Apr 2005 16:13:23 -0000	1.2
  +++ InternalAprOutputBuffer.java	14 May 2005 20:41:26 -0000	1.3
  @@ -17,6 +17,7 @@
   package org.apache.coyote.http11;
   
   import java.io.IOException;
  +import java.nio.ByteBuffer;
   import java.security.AccessController;
   import java.security.PrivilegedAction;
   
  @@ -38,7 +39,7 @@
    * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
    */
   public class InternalAprOutputBuffer 
  -    implements OutputBuffer, ByteChunk.ByteOutputChannel {
  +    implements OutputBuffer {
   
   
       // -------------------------------------------------------------- Constants
  @@ -66,15 +67,14 @@
           headerBuffer = new byte[headerBufferSize];
           buf = headerBuffer;
   
  +        bbuf = ByteBuffer.allocateDirect((headerBufferSize / 1500 + 1) * 1500);
  +
           outputStreamOutputBuffer = new SocketOutputBuffer();
   
           filterLibrary = new OutputFilter[0];
           activeFilters = new OutputFilter[0];
           lastActiveFilter = -1;
   
  -        socketBuffer = new ByteChunk();
  -        socketBuffer.setByteOutputChannel(this);
  -
           committed = false;
           finished = false;
   
  @@ -168,17 +168,11 @@
   
   
       /**
  -     * Socket buffer.
  -     */
  -    protected ByteChunk socketBuffer;
  -
  -
  -    /**
  -     * Socket buffer (extra buffering to reduce number of packets sent).
  +     * Direct byte buffer used for writing.
        */
  -    protected boolean useSocketBuffer = false;
  -
  +    protected ByteBuffer bbuf = null;
   
  +    
       // ------------------------------------------------------------- Properties
   
   
  @@ -202,14 +196,7 @@
        * Set the socket buffer size.
        */
       public void setSocketBuffer(int socketBufferSize) {
  -
  -        if (socketBufferSize > 500) {
  -            useSocketBuffer = true;
  -            socketBuffer.allocate(socketBufferSize, socketBufferSize);
  -        } else {
  -            useSocketBuffer = false;
  -        }
  -
  +        // FIXME: Remove
       }
   
   
  @@ -295,9 +282,7 @@
           }
   
           // Flush the current buffer
  -        if (useSocketBuffer) {
  -            socketBuffer.flushBuffer();
  -        }
  +        flushBuffer();
   
       }
   
  @@ -326,7 +311,7 @@
   
           // Recycle Request object
           response.recycle();
  -        socketBuffer.recycle();
  +        bbuf.clear();
   
           socket = 0;
           buf = headerBuffer;
  @@ -348,7 +333,6 @@
   
           // Recycle Request object
           response.recycle();
  -        socketBuffer.recycle();
   
           // Determine the header buffer used for next request
           buf = headerBuffer;
  @@ -390,9 +374,7 @@
           if (lastActiveFilter != -1)
               activeFilters[lastActiveFilter].end();
   
  -        if (useSocketBuffer) {
  -            socketBuffer.flushBuffer();
  -        }
  +        flushBuffer();
   
           finished = true;
   
  @@ -595,12 +577,7 @@
   
           if (pos > 0) {
               // Sending the response header buffer
  -            if (useSocketBuffer) {
  -                socketBuffer.append(buf, 0, pos);
  -            } else {
  -                if (Socket.send(socket, buf, 0, pos) < 0)
  -                    throw new IOException(sm.getString("iib.failedwrite"));
  -            }
  +            bbuf.put(buf, 0, pos);
           }
   
       }
  @@ -738,11 +715,13 @@
       /**
        * Callback to write data from the buffer.
        */
  -    public void realWriteBytes(byte[] buf, int off, int len)
  +    protected void flushBuffer()
           throws IOException {
  -        if (len > 0) {
  -            if (Socket.send(socket, buf, off, len) < 0)
  +        if (bbuf.position() > 0) {
  +            if (Socket.sendb(socket, bbuf, 0, bbuf.position()) < 0) {
                   throw new IOException(sm.getString("iib.failedwrite"));
  +            }
  +            bbuf.clear();
           }
       }
   
  @@ -764,14 +743,15 @@
           public int doWrite(ByteChunk chunk, Response res) 
               throws IOException {
   
  -            if (useSocketBuffer) {
  -                socketBuffer.append(chunk.getBuffer(), chunk.getStart(), 
  -                                   chunk.getLength());
  -            } else {
  -                if (Socket.send(socket, chunk.getBuffer(), chunk.getStart(), 
  -                                chunk.getLength()) < 0)
  -                    throw new IOException(sm.getString("iib.failedwrite"));
  +            if (bbuf.position() + chunk.getLength() > bbuf.capacity()) {
  +                flushBuffer();
  +                if (chunk.getLength() > bbuf.capacity()) {
  +                    if (Socket.send(socket, chunk.getBuffer(), chunk.getStart(), 
  +                            chunk.getLength()) < 0)
  +                        throw new IOException(sm.getString("iib.failedwrite"));
  +                }
               }
  +            bbuf.put(chunk.getBuffer(), chunk.getStart(), chunk.getLength());
               return chunk.getLength();
   
           }
  
  
  

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


Re: cvs commit: jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11 InternalAprOutputBuffer.java

Posted by Remy Maucherat <re...@apache.org>.
Bill Barker wrote:
>> remm        2005/05/14 13:41:26
>>
>>  Modified:    http11/src/java/org/apache/coyote/http11
>>                        InternalAprOutputBuffer.java
>>  Log:
>>  - Optimize a little using a direct byte buffer to replace the socket 
>> buffer.
>>  - I'll experiment with doing the same optimization for reads, but I 
>> don't expect it to do anything
>>    (other than waste memory) as copying bytes will be needed.
>>
> 
> Cool.  I had been thinking that the savings with NIO were all do to the 
> fact that SocketChannel.write would allocate and copy to another 
> ByteBuffer instance if I didn't use direct ByteBuffers.

Yes, it's a little bit faster (the optimization seems a bit more 
efficient on Java 5, also). Not much difference, though, but it confirms 
virtually all the overhead is likely on JNI. I assume it is saving one 
copy of the bytes.

On input, saving a copy won't be possible, so I don't think it'll make a 
difference (maybe it will on Java 5, who knows), but I'll try it anyway.

Right now, with my localhost ab test on tomcat.gif (/usr/sbin/ab.exe -c 
20 -k -n 20000 http://127.0.0.1:8080/tomcat.gif, Sun Java 5 server, 
Windows XP with no firewall), I'm at (in relative numbers): APR 1.00, 
regular IO 1.13

This is clearly the worst situation, however. Not doing localhost tests 
should hide some of the JNI overhead (as the network stack will actually 
have stuff to do), so I think the results are quite good overall.

Rémy

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


Re: cvs commit: jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11 InternalAprOutputBuffer.java

Posted by Bill Barker <wb...@wilshire.com>.
----- Original Message ----- 
From: <re...@apache.org>
To: <ja...@apache.org>
Sent: Saturday, May 14, 2005 1:41 PM
Subject: cvs commit: 
jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11 
InternalAprOutputBuffer.java


> remm        2005/05/14 13:41:26
>
>  Modified:    http11/src/java/org/apache/coyote/http11
>                        InternalAprOutputBuffer.java
>  Log:
>  - Optimize a little using a direct byte buffer to replace the socket 
> buffer.
>  - I'll experiment with doing the same optimization for reads, but I don't 
> expect it to do anything
>    (other than waste memory) as copying bytes will be needed.
>

Cool.  I had been thinking that the savings with NIO were all do to the fact 
that SocketChannel.write would allocate and copy to another ByteBuffer 
instance if I didn't use direct ByteBuffers.



This message is intended only for the use of the person(s) listed above as the intended recipient(s), and may contain information that is PRIVILEGED and CONFIDENTIAL.  If you are not an intended recipient, you may not read, copy, or distribute this message or any attachment. If you received this communication in error, please notify us immediately by e-mail and then delete all copies of this message and any attachments.

In addition you should be aware that ordinary (unencrypted) e-mail sent through the Internet is not secure. Do not send confidential or sensitive information, such as social security numbers, account numbers, personal identification numbers and passwords, to us via ordinary (unencrypted) e-mail.