Author: kkolinko
Date: Thu Mar 15 18:14:44 2012
New Revision: 1301123
URL: http://svn.apache.org/viewvc?rev=1301123&view=rev
Log:
Slightly improve performance of UDecoder
Backports r1203054 from 7.0.x.
- Reduce overhead from exception handling, using
ProxyDirContext.NOT_FOUND_EXCEPTION as an example.
- Limit second string scan using results from the first one.
The s/findByte()/indexOf()/ change part of r1203054 has not been backported.
Modified:
tomcat/tc6.0.x/trunk/STATUS.txt
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/buf/UDecoder.java
tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml
Modified: tomcat/tc6.0.x/trunk/STATUS.txt
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS.txt?rev=1301123&r1=1301122&r2=1301123&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/STATUS.txt (original)
+++ tomcat/tc6.0.x/trunk/STATUS.txt Thu Mar 15 18:14:44 2012
@@ -69,12 +69,6 @@ PATCHES PROPOSED TO BACKPORT:
+1: kkolinko, rjung, fhanik
-1:
-* Reduce overhead from exception handling in UDecoder
- http://people.apache.org/~kkolinko/patches/2011-11-17_tc6_UDecoder.patch
- (r1203054 in TC7)
- +1: kkolinko,funkman, fhanik
- -1:
-
* Align %2f handling between implementations of UDecoder.convert()
http://svn.apache.org/viewvc?rev=1203091&view=rev
+1: kkolinko,funkman, fhanik
Modified: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/buf/UDecoder.java
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/buf/UDecoder.java?rev=1301123&r1=1301122&r2=1301123&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/buf/UDecoder.java
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/buf/UDecoder.java Thu Mar
15 18:14:44 2012
@@ -33,6 +33,30 @@ public final class UDecoder {
protected static final boolean ALLOW_ENCODED_SLASH =
Boolean.valueOf(System.getProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH",
"false")).booleanValue();
+ private static class DecodeException extends CharConversionException {
+ private static final long serialVersionUID = 1L;
+ public DecodeException(String s) {
+ super(s);
+ }
+
+ @Override
+ public synchronized Throwable fillInStackTrace() {
+ // This class does not provide a stack trace
+ return this;
+ }
+ }
+
+ /** Unexpected end of data. */
+ private static final IOException EXCEPTION_EOF = new
DecodeException("EOF");
+
+ /** %xx with not-hex digit */
+ private static final IOException EXCEPTION_NOT_HEX_DIGIT = new
DecodeException(
+ "isHexDigit");
+
+ /** %-encoded slash is forbidden in resource path */
+ private static final IOException EXCEPTION_SLASH = new DecodeException(
+ "noSlash");
+
public UDecoder()
{
}
@@ -57,18 +81,20 @@ public final class UDecoder {
int idx= ByteChunk.indexOf( buff, start, end, '%' );
int idx2=-1;
- if( query )
- idx2= ByteChunk.indexOf( buff, start, end, '+' );
+ if( query ) {
+ idx2= ByteChunk.indexOf( buff, start, (idx >= 0 ? idx : end), '+'
);
+ }
if( idx<0 && idx2<0 ) {
return;
}
- // idx will be the smallest positive inxes ( first % or + )
- if( idx2 >= 0 && idx2 < idx ) idx=idx2;
- if( idx < 0 ) idx=idx2;
+ // idx will be the smallest positive index ( first % or + )
+ if( (idx2 >= 0 && idx2 < idx) || idx < 0 ) {
+ idx=idx2;
+ }
+
+ boolean noSlash = !(ALLOW_ENCODED_SLASH || query);
- boolean noSlash = !(ALLOW_ENCODED_SLASH || query);
-
for( int j=idx; j<end; j++, idx++ ) {
if( buff[ j ] == '+' && query) {
buff[idx]= (byte)' ' ;
@@ -77,18 +103,18 @@ public final class UDecoder {
} else {
// read next 2 digits
if( j+2 >= end ) {
- throw new CharConversionException("EOF");
+ throw EXCEPTION_EOF;
}
byte b1= buff[j+1];
byte b2=buff[j+2];
if( !isHexDigit( b1 ) || ! isHexDigit(b2 ))
- throw new CharConversionException( "isHexDigit");
+ throw EXCEPTION_NOT_HEX_DIGIT;
j+=2;
int res=x2c( b1, b2 );
- if (noSlash && (res == '/')) {
- throw new CharConversionException( "noSlash");
- }
+ if (noSlash && (res == '/')) {
+ throw EXCEPTION_SLASH;
+ }
buff[idx]=(byte)res;
}
}
@@ -122,14 +148,17 @@ public final class UDecoder {
int idx= CharChunk.indexOf( buff, start, cend, '%' );
int idx2=-1;
- if( query )
- idx2= CharChunk.indexOf( buff, start, cend, '+' );
+ if( query ) {
+ idx2= CharChunk.indexOf( buff, start, (idx >= 0 ? idx : cend), '+'
);
+ }
if( idx<0 && idx2<0 ) {
return;
}
-
- if( idx2 >= 0 && idx2 < idx ) idx=idx2;
- if( idx < 0 ) idx=idx2;
+
+ // idx will be the smallest positive index ( first % or + )
+ if( (idx2 >= 0 && idx2 < idx) || idx < 0 ) {
+ idx=idx2;
+ }
for( int j=idx; j<cend; j++, idx++ ) {
if( buff[ j ] == '+' && query ) {
@@ -140,12 +169,12 @@ public final class UDecoder {
// read next 2 digits
if( j+2 >= cend ) {
// invalid
- throw new CharConversionException("EOF");
+ throw EXCEPTION_EOF;
}
char b1= buff[j+1];
char b2=buff[j+2];
if( !isHexDigit( b1 ) || ! isHexDigit(b2 ))
- throw new CharConversionException("isHexDigit");
+ throw EXCEPTION_NOT_HEX_DIGIT;
j+=2;
int res=x2c( b1, b2 );
Modified: tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml?rev=1301123&r1=1301122&r2=1301123&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Thu Mar 15 18:14:44 2012
@@ -103,6 +103,9 @@
parameters, as documentation says, instead of
<code>(maxParameterCount-1)</code>. (kkolinko)
</fix>
+ <fix>
+ Slightly improve performance of UDecoder.convert(). (kkolinko)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]