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: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to