You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2005/10/23 20:21:11 UTC
svn commit: r327828 - in /jakarta/httpclient/trunk/http-core/src:
java/org/apache/http/impl/io/ java/org/apache/http/io/
java/org/apache/http/params/ java/org/apache/http/util/
test/org/apache/http/impl/ test/org/apache/http/util/
Author: olegk
Date: Sun Oct 23 11:20:46 2005
New Revision: 327828
URL: http://svn.apache.org/viewcvs?rev=327828&view=rev
Log:
Another round of performance optimization
* Abstract HTTP data receiver extended with a method to read HTTP line into a char buffer. This method is intended to reduce the amount of garbage generated when parsing HTTP lines
* Abstract HTTP data receiver uses byte to char cast when converting raw bytes to US-ASCII chars
Modified:
jakarta/httpclient/trunk/http-core/src/java/org/apache/http/impl/io/AbstractHttpDataReceiver.java
jakarta/httpclient/trunk/http-core/src/java/org/apache/http/io/HttpDataReceiver.java
jakarta/httpclient/trunk/http-core/src/java/org/apache/http/params/HttpProtocolParams.java
jakarta/httpclient/trunk/http-core/src/java/org/apache/http/util/CharArrayBuffer.java
jakarta/httpclient/trunk/http-core/src/java/org/apache/http/util/EncodingUtils.java
jakarta/httpclient/trunk/http-core/src/java/org/apache/http/util/EntityUtils.java
jakarta/httpclient/trunk/http-core/src/test/org/apache/http/impl/TestHttpDataReceiverAndTransmitter.java
jakarta/httpclient/trunk/http-core/src/test/org/apache/http/util/TestCharArrayBuffer.java
Modified: jakarta/httpclient/trunk/http-core/src/java/org/apache/http/impl/io/AbstractHttpDataReceiver.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-core/src/java/org/apache/http/impl/io/AbstractHttpDataReceiver.java?rev=327828&r1=327827&r2=327828&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-core/src/java/org/apache/http/impl/io/AbstractHttpDataReceiver.java (original)
+++ jakarta/httpclient/trunk/http-core/src/java/org/apache/http/impl/io/AbstractHttpDataReceiver.java Sun Oct 23 11:20:46 2005
@@ -36,6 +36,7 @@
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.util.ByteArrayBuffer;
+import org.apache.http.util.CharArrayBuffer;
import org.apache.http.util.EncodingUtils;
/**
@@ -57,6 +58,7 @@
private ByteArrayBuffer linebuffer = null;
private String charset = "US-ASCII";
+ private boolean ascii = true;
protected void init(final InputStream instream, int buffersize) {
if (instream == null) {
@@ -149,7 +151,10 @@
return -1;
}
- public String readLine() throws IOException {
+ public int readLine(final CharArrayBuffer charbuffer) throws IOException {
+ if (charbuffer == null) {
+ throw new IllegalArgumentException("Char array buffer may not be null");
+ }
this.linebuffer.clear();
int noRead = 0;
boolean retry = true;
@@ -160,7 +165,7 @@
// end of line found.
if (this.linebuffer.isEmpty()) {
// the entire line is preset in the read buffer
- return lineFromReadBuffer(i);
+ return lineFromReadBuffer(charbuffer, i);
}
retry = false;
int len = i + 1 - this.bufferpos;
@@ -181,12 +186,12 @@
}
if (noRead == -1 && this.linebuffer.isEmpty()) {
// indicate the end of stream
- return null;
+ return -1;
}
- return lineFromLineBuffer();
+ return lineFromLineBuffer(charbuffer);
}
- private String lineFromLineBuffer() {
+ private int lineFromLineBuffer(final CharArrayBuffer charbuffer) {
// discard LF if found
int l = this.linebuffer.length();
if (l > 0) {
@@ -202,11 +207,13 @@
}
}
}
- return EncodingUtils.getString(
- this.linebuffer.getBuffer(), 0, this.linebuffer.length(), this.charset);
+ copyToCharBuffer(
+ this.linebuffer.getBuffer(), 0, this.linebuffer.length(),
+ charbuffer);
+ return this.linebuffer.length();
}
- private String lineFromReadBuffer(int pos) {
+ private int lineFromReadBuffer(final CharArrayBuffer charbuffer, int pos) {
int off = this.bufferpos;
int len;
this.bufferpos = pos + 1;
@@ -215,11 +222,48 @@
pos--;
}
len = pos - off;
- return EncodingUtils.getString(this.buffer, off, len, this.charset);
+ copyToCharBuffer(this.buffer, off, len, charbuffer);
+ return len;
+ }
+
+ private void copyToCharBuffer(final byte[] b, int off, int len,
+ final CharArrayBuffer charbuffer) {
+ if (this.ascii) {
+ // this is an uuuuugly performance hack
+ charbuffer.ensureCapacity(len);
+ int oldlen = charbuffer.length();
+ int newlen = oldlen + len;
+ charbuffer.setLength(newlen);
+ char[] tmp = charbuffer.getBuffer();
+ for (int i = oldlen; i < newlen; i++) {
+ int ch = b[off + i];
+ if (ch < 0) {
+ ch = 256 + ch;
+ }
+ tmp[i] = (char) ch;
+ }
+ } else {
+ String s = EncodingUtils.getString(b, off, len, this.charset);
+ charbuffer.ensureCapacity(s.length());
+ charbuffer.append(s);
+ }
+ }
+
+ public String readLine() throws IOException {
+ CharArrayBuffer charbuffer = new CharArrayBuffer(64);
+ int l = readLine(charbuffer);
+ if (l != -1) {
+ return charbuffer.toString();
+ } else {
+ return null;
+ }
}
public void reset(final HttpParams params) {
this.charset = HttpProtocolParams.getHttpElementCharset(params);
+ this.ascii =
+ this.charset.equalsIgnoreCase(EncodingUtils.ASCII_CHARSET) ||
+ this.charset.equalsIgnoreCase("ASCII");
}
}
Modified: jakarta/httpclient/trunk/http-core/src/java/org/apache/http/io/HttpDataReceiver.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-core/src/java/org/apache/http/io/HttpDataReceiver.java?rev=327828&r1=327827&r2=327828&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-core/src/java/org/apache/http/io/HttpDataReceiver.java (original)
+++ jakarta/httpclient/trunk/http-core/src/java/org/apache/http/io/HttpDataReceiver.java Sun Oct 23 11:20:46 2005
@@ -32,6 +32,7 @@
import java.io.IOException;
import org.apache.http.params.HttpParams;
+import org.apache.http.util.CharArrayBuffer;
/**
* <p>
@@ -51,6 +52,8 @@
int read(byte[] b) throws IOException;
int read() throws IOException;
+
+ int readLine(CharArrayBuffer buffer) throws IOException;
String readLine() throws IOException;
Modified: jakarta/httpclient/trunk/http-core/src/java/org/apache/http/params/HttpProtocolParams.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-core/src/java/org/apache/http/params/HttpProtocolParams.java?rev=327828&r1=327827&r2=327828&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-core/src/java/org/apache/http/params/HttpProtocolParams.java (original)
+++ jakarta/httpclient/trunk/http-core/src/java/org/apache/http/params/HttpProtocolParams.java Sun Oct 23 11:20:46 2005
@@ -30,6 +30,7 @@
package org.apache.http.params;
import org.apache.http.HttpVersion;
+import org.apache.http.util.EncodingUtils;
/**
* This class implements an adaptor around the {@link HttpParams} interface
@@ -184,7 +185,7 @@
}
String charset = (String) params.getParameter(HTTP_ELEMENT_CHARSET);
if (charset == null) {
- charset = "US-ASCII";
+ charset = EncodingUtils.ASCII_CHARSET;
}
return charset;
}
@@ -211,7 +212,7 @@
}
String charset = (String) params.getParameter(HTTP_CONTENT_CHARSET);
if (charset == null) {
- charset = "ISO-8859-1";
+ charset = EncodingUtils.ISO_8859_1_CHARSET;
}
return charset;
}
Modified: jakarta/httpclient/trunk/http-core/src/java/org/apache/http/util/CharArrayBuffer.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-core/src/java/org/apache/http/util/CharArrayBuffer.java?rev=327828&r1=327827&r2=327828&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-core/src/java/org/apache/http/util/CharArrayBuffer.java (original)
+++ jakarta/httpclient/trunk/http-core/src/java/org/apache/http/util/CharArrayBuffer.java Sun Oct 23 11:20:46 2005
@@ -128,6 +128,13 @@
return this.len;
}
+ public void ensureCapacity(int required) {
+ int available = this.buffer.length - this.len;
+ if (required > available) {
+ expand(this.len + required);
+ }
+ }
+
public void setLength(int len) {
if (len < 0 || len > this.buffer.length) {
throw new IndexOutOfBoundsException();
Modified: jakarta/httpclient/trunk/http-core/src/java/org/apache/http/util/EncodingUtils.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-core/src/java/org/apache/http/util/EncodingUtils.java?rev=327828&r1=327827&r2=327828&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-core/src/java/org/apache/http/util/EncodingUtils.java (original)
+++ jakarta/httpclient/trunk/http-core/src/java/org/apache/http/util/EncodingUtils.java Sun Oct 23 11:20:46 2005
@@ -41,7 +41,10 @@
public class EncodingUtils {
/** ASCII chatset */
- private static final String ASCII_CHARSET = "US-ASCII";
+ public static final String ASCII_CHARSET = "US-ASCII";
+
+ /** ISO-8859-1 chatset */
+ public static final String ISO_8859_1_CHARSET = "ISO-8859-1";
/**
* Converts the byte array of HTTP content characters to a string. If
Modified: jakarta/httpclient/trunk/http-core/src/java/org/apache/http/util/EntityUtils.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-core/src/java/org/apache/http/util/EntityUtils.java?rev=327828&r1=327827&r2=327828&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-core/src/java/org/apache/http/util/EntityUtils.java (original)
+++ jakarta/httpclient/trunk/http-core/src/java/org/apache/http/util/EntityUtils.java Sun Oct 23 11:20:46 2005
@@ -113,7 +113,7 @@
charset = defaultCharset;
}
if (charset == null) {
- charset = "ISO-8859-1";
+ charset = EncodingUtils.ISO_8859_1_CHARSET;
}
Reader reader = new InputStreamReader(entity.getContent(), charset);
CharArrayBuffer buffer = new CharArrayBuffer(i);
Modified: jakarta/httpclient/trunk/http-core/src/test/org/apache/http/impl/TestHttpDataReceiverAndTransmitter.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-core/src/test/org/apache/http/impl/TestHttpDataReceiverAndTransmitter.java?rev=327828&r1=327827&r2=327828&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-core/src/test/org/apache/http/impl/TestHttpDataReceiverAndTransmitter.java (original)
+++ jakarta/httpclient/trunk/http-core/src/test/org/apache/http/impl/TestHttpDataReceiverAndTransmitter.java Sun Oct 23 11:20:46 2005
@@ -41,6 +41,7 @@
import org.apache.http.mockup.HttpDataTransmitterMockup;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.util.EncodingUtils;
public class TestHttpDataReceiverAndTransmitter extends TestCase {
@@ -346,6 +347,42 @@
}
assertNull(receiver.readLine());
assertNull(receiver.readLine());
+ }
+
+ public void testNonAsciiReadWriteLine() throws Exception {
+ String s1 = constructString(SWISS_GERMAN_HELLO);
+
+ HttpParams params = new DefaultHttpParams(null);
+ HttpProtocolParams.setHttpElementCharset(params, EncodingUtils.ISO_8859_1_CHARSET);
+
+ HttpDataTransmitterMockup transmitter = new HttpDataTransmitterMockup();
+ transmitter.reset(params);
+
+ for (int i = 0; i < 10; i++) {
+ transmitter.writeLine(s1);
+ }
+ transmitter.flush();
+
+ HttpDataReceiverMockup receiver = new HttpDataReceiverMockup(
+ transmitter.getData());
+ HttpProtocolParams.setHttpElementCharset(params, EncodingUtils.ASCII_CHARSET);
+ receiver.reset(params);
+
+ for (int i = 0; i < 10; i++) {
+ assertEquals(s1, receiver.readLine());
+ }
+ assertNull(receiver.readLine());
+ assertNull(receiver.readLine());
+ }
+
+ public void testInvalidCharArrayBuffer() throws Exception {
+ HttpDataReceiverMockup receiver = new HttpDataReceiverMockup(new byte[] {});
+ try {
+ receiver.readLine(null);
+ fail("IllegalArgumentException should have been thrown");
+ } catch (IllegalArgumentException ex) {
+ //expected
+ }
}
}
Modified: jakarta/httpclient/trunk/http-core/src/test/org/apache/http/util/TestCharArrayBuffer.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-core/src/test/org/apache/http/util/TestCharArrayBuffer.java?rev=327828&r1=327827&r2=327828&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-core/src/test/org/apache/http/util/TestCharArrayBuffer.java (original)
+++ jakarta/httpclient/trunk/http-core/src/test/org/apache/http/util/TestCharArrayBuffer.java Sun Oct 23 11:20:46 2005
@@ -198,5 +198,13 @@
// expected
}
}
-
+
+ public void testEnsureCapacity() throws Exception {
+ CharArrayBuffer buffer = new CharArrayBuffer(4);
+ buffer.ensureCapacity(2);
+ assertEquals(4, buffer.capacity());
+ buffer.ensureCapacity(8);
+ assertEquals(8, buffer.capacity());
+ }
+
}