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.