Author: peter_firmstone Date: Sat May 11 04:15:06 2013 New Revision: 1481257
URL: http://svn.apache.org/r1481257 Log: Moved logging outside of locks in Target Make sure ThreadPool threads die after timeout String.toUpperCase and toLowerCase were hotspots during Stress testing, replaced with bitshift operations for ascii strings in Uri There is contention on InvocationHandler from Target$2.run() during stress testing on a 2 cpu machine, there could be a scaling issue in JERI when using DGC Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/runtime/Target.java river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/ThreadPool.java river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/URIEncoderDecoder.java river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/Uri.java river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/UriParser.java river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/net/UriTest.java Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/runtime/Target.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/runtime/Target.java?rev=1481257&r1=1481256&r2=1481257&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/runtime/Target.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/runtime/Target.java Sat May 11 04:15:06 2013 @@ -248,11 +248,11 @@ final class Target { void collect() { if (!exported) return; + if (logger.isLoggable(Level.FINE)) { + logger.log(Level.FINE, "garbage collection of object with id {0}", id); + } lock.lock(); try { - if (logger.isLoggable(Level.FINE)) { - logger.log(Level.FINE, "garbage collection of object with id {0}", id); - } unexported = true; exported = false; @@ -293,11 +293,12 @@ final class Target { void referenced(Uuid clientID, long sequenceNum) { if (!allowDGC) return; if (!exported) return; + if (logger.isLoggable(Level.FINEST)) { + logger.log(Level.FINEST, "this={0}, clientID={1}, sequenceNum={2}", new Object[]{this, clientID, Long.valueOf(sequenceNum)}); + } lock.lock(); try { - if (logger.isLoggable(Level.FINEST)) { - logger.log(Level.FINEST, "this={0}, clientID={1}, sequenceNum={2}", new Object[]{this, clientID, Long.valueOf(sequenceNum)}); - } + SequenceEntry entry = (SequenceEntry) sequenceTable.get(clientID); if (entry == null) { entry = new SequenceEntry(sequenceNum); @@ -328,11 +329,11 @@ final class Target { void unreferenced(Uuid clientID, long sequenceNum, boolean strong) { if (!allowDGC) return; if (!exported) return; + if (logger.isLoggable(Level.FINEST)) { + logger.log(Level.FINEST, "this={0}, clientID={1}, sequenceNum={2}, strong={3}", new Object[]{this, clientID, Long.valueOf(sequenceNum), Boolean.valueOf(strong)}); + } lock.lock(); try { - if (logger.isLoggable(Level.FINEST)) { - logger.log(Level.FINEST, "this={0}, clientID={1}, sequenceNum={2}, strong={3}", new Object[]{this, clientID, Long.valueOf(sequenceNum), Boolean.valueOf(strong)}); - } SequenceEntry entry = sequenceTable.get(clientID); if (entry == null) { if (strong) { @@ -358,11 +359,12 @@ final class Target { void leaseExpired(Uuid clientID) { assert allowDGC; if (!exported) return; + if (logger.isLoggable(Level.FINEST)) { + logger.log(Level.FINEST, "this={0}, clientID={1}", new Object[]{this, clientID}); + } lock.lock(); try { - if (logger.isLoggable(Level.FINEST)) { - logger.log(Level.FINEST, "this={0}, clientID={1}", new Object[]{this, clientID}); - } + SequenceEntry entry = sequenceTable.get(clientID); if (entry != null && !entry.keep()) { /* Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/ThreadPool.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/ThreadPool.java?rev=1481257&r1=1481256&r2=1481257&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/ThreadPool.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/ThreadPool.java Sat May 11 04:15:06 2013 @@ -238,7 +238,11 @@ final class ThreadPool implements Execut task = queue.poll(idleTimeout, TimeUnit.MILLISECONDS); waitingThreads.getAndDecrement(); // thread.setName(NewThreadAction.NAME_PREFIX + task); - if (task != null) task.run(); + if (task != null) { + task.run(); + } else { + break; //Timeout or spurious wakeup. + } // thread.setName(NewThreadAction.NAME_PREFIX + "Idle"); } catch (InterruptedException e){ waitingThreads.getAndDecrement(); Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/URIEncoderDecoder.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/URIEncoderDecoder.java?rev=1481257&r1=1481256&r2=1481257&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/URIEncoderDecoder.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/URIEncoderDecoder.java Sat May 11 04:15:06 2013 @@ -50,7 +50,7 @@ class URIEncoderDecoder { static { legalEscaped = new HashMap<String,Character>(); char [] legals = "abcdefghijklmnopqrstuvwyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~".toCharArray(); - StringBuilder buf = new StringBuilder(); + StringBuilder buf = new StringBuilder(12); int l = legals.length; for (int i = 0; i< l; i++){ char ch = legals[i]; @@ -153,7 +153,7 @@ class URIEncoderDecoder { */ static String quoteIllegal(String s, String legal) throws UnsupportedEncodingException { - StringBuilder buf = new StringBuilder(); + StringBuilder buf = new StringBuilder(s.length() + 24); for (int i = 0; i < s.length(); i++) { char ch = s.charAt(i); if ( (ch >= 'a' && ch <= 'z') @@ -190,7 +190,7 @@ class URIEncoderDecoder { * @return java.lang.String the converted string */ static String encodeOthers(String s) throws UnsupportedEncodingException { - StringBuilder buf = new StringBuilder(); + StringBuilder buf = new StringBuilder(s.length()*9); for (int i = 0; i < s.length(); i++) { char ch = s.charAt(i); if (ch <= 127) { @@ -225,7 +225,7 @@ class URIEncoderDecoder { */ static String decode(String s) throws UnsupportedEncodingException { - StringBuilder result = new StringBuilder(); + StringBuilder result = new StringBuilder(s.length()); ByteArrayOutputStream out = new ByteArrayOutputStream(); int l = s.length(); for (int i = 0; i < l;) { @@ -257,7 +257,7 @@ class URIEncoderDecoder { } static String decodeUnreserved(String s) throws URISyntaxException { - StringBuilder result = new StringBuilder(); + StringBuilder result = new StringBuilder(s.length()); StringBuilder pct_encoded = new StringBuilder(12); int l = s.length(); for (int i = 0; i < l;) { Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/Uri.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/Uri.java?rev=1481257&r1=1481256&r2=1481257&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/Uri.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/Uri.java Sat May 11 04:15:06 2013 @@ -217,16 +217,85 @@ public final class Uri implements Compar */ static final String queryFragLegal = pcharLegal + "/?"; + private final static char a = 'a'; + private final static char z = 'z'; + private final static char A = 'A'; + private final static char Z = 'Z'; + private final static char upperCaseBitwiseMask = 0xdf; + private final static char lowerCaseBitwiseMask = 0x20; + + static String toAsciiUpperCase(String s){ + return new String(toAsciiUpperCase(s.toCharArray())); + } + + static char [] toAsciiUpperCase(char [] array){ + int length = array.length; + for (int i = 0; i < length ; i++){ + if (array[i] >= a && array[i] <= z) { + array[i] = toAsciiUpperCase(array[i]); + } + } + return array; + } + + static char toAsciiUpperCase(char c){ + return (char) (c & upperCaseBitwiseMask); + } + + static String toAsciiLowerCase(String s){ + return new String(toAsciiLowerCase(s.toCharArray())); + } + + static char[] toAsciiLowerCase(char [] array){ + int length = array.length; + for (int i = 0; i < length ; i++){ + if (array[i] >= A && array[i] <= Z) { + array[i] = toAsciiLowerCase(array[i]); + } + } + return array; + } + + static char toAsciiLowerCase(char c){ + return (char) (c | lowerCaseBitwiseMask); + } + + static boolean charArraysEqual( char [] a , char [] b){ + int alen = a.length; + int blen = b.length; + if (alen != blen) return false; + for (int i = 0; i < alen; i++){ + if (a[i] != b[i]) return false; + } + return true; + } + + static boolean asciiStringsUpperCaseEqual(String a, String b){ + char [] ac = a.toCharArray(); + toAsciiUpperCase(ac); + char [] bc = b.toCharArray(); + toAsciiUpperCase(bc); + return charArraysEqual(ac, bc); + } + + static boolean asciiStringsLowerCaseEqual(String a, String b){ + char [] ac = a.toCharArray(); + toAsciiLowerCase(ac); + char [] bc = b.toCharArray(); + toAsciiLowerCase(bc); + return charArraysEqual(ac, bc); + } /** Fixes windows file URI string by converting back slashes to forward * slashes and inserting a forward slash before the drive letter if it is * missing. No normalisation or modification of case is performed. */ public static String fixWindowsURI(String uri) { if (uri == null) return null; + if (File.separatorChar != '\\') return uri; if ( uri.startsWith("file:") || uri.startsWith("FILE:")){ char [] u = uri.toCharArray(); int l = u.length; - StringBuilder sb = new StringBuilder(); + StringBuilder sb = new StringBuilder(uri.length()+1); for (int i=0; i<l; i++){ // Ensure we use forward slashes if (u[i] == File.separatorChar) { @@ -781,7 +850,8 @@ public final class Uri implements Compar // compare paths if (fileSchemeCaseInsensitiveOS){ - ret = path.toUpperCase(Locale.ENGLISH).compareTo(uri.path.toUpperCase(Locale.ENGLISH)); + ret = toAsciiUpperCase(path).compareTo(toAsciiUpperCase(uri.path)); +// ret = path.toUpperCase(Locale.ENGLISH).compareTo(uri.path.toUpperCase(Locale.ENGLISH)); } else { ret = path.compareTo(uri.path); } @@ -869,7 +939,7 @@ public final class Uri implements Compar /* * Takes a string that may contain hex sequences like %F1 or %2b and - * converts the hex values following the '%' to lowercase + * converts the hex values following the '%' to uppercase */ private String convertHexToUpperCase(String s) { StringBuilder result = new StringBuilder(""); //$NON-NLS-1$ @@ -880,7 +950,8 @@ public final class Uri implements Compar int index = 0, previndex = 0; while ((index = s.indexOf('%', previndex)) != -1) { result.append(s.substring(previndex, index + 1)); - result.append(s.substring(index + 1, index + 3).toUpperCase(Locale.ENGLISH)); + // Convert to upper case ascii + result.append(toAsciiUpperCase(s.substring(index + 1, index + 3).toCharArray())); index += 3; previndex = index; } @@ -965,9 +1036,10 @@ public final class Uri implements Compar if ( !(path != null && (path.equals(uri.path) || fileSchemeCaseInsensitiveOS // Upper case comparison required for Windows & VMS. - && path.toUpperCase(Locale.ENGLISH).equals( - uri.path.toUpperCase(Locale.ENGLISH) - )))) + && asciiStringsUpperCaseEqual(path, uri.path) +// path.toUpperCase(Locale.ENGLISH).equals( +// uri.path.toUpperCase(Locale.ENGLISH)) + ))) { return false; } @@ -1231,8 +1303,8 @@ public final class Uri implements Compar String thisFile; String thatFile; if (fileSchemeCaseInsensitiveOS){ - thisFile = path == null ? null: path.toUpperCase(Locale.ENGLISH); - thatFile = implied.path == null ? null: implied.path.toUpperCase(Locale.ENGLISH); + thisFile = path == null ? null: toAsciiUpperCase(path); + thatFile = implied.path == null ? null: toAsciiUpperCase(implied.path); } else { thisFile = path; thatFile = implied.path; @@ -1872,7 +1944,7 @@ public final class Uri implements Compar if (path != null) { if (fileSchemeCaseInsensitiveOS){ - result.append(path.toUpperCase(Locale.ENGLISH)); + result.append(toAsciiUpperCase(path.toCharArray())); } else { result.append(path); } Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/UriParser.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/UriParser.java?rev=1481257&r1=1481256&r2=1481257&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/UriParser.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/UriParser.java Sat May 11 04:15:06 2013 @@ -78,7 +78,7 @@ final class UriParser { if (index != -1 && (index2 >= index || index2 == -1) && (index3 >= index || index3 == -1)) { // the characters up to the first ':' comprise the scheme absolute = true; - scheme = temp.substring(0, index).toLowerCase(Locale.ENGLISH); + scheme = Uri.toAsciiLowerCase(temp.substring(0, index)); if (scheme.length() == 0) { throw new URISyntaxException(uri, Messages.getString("luni.83"), index); } Modified: river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/net/UriTest.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/net/UriTest.java?rev=1481257&r1=1481256&r2=1481257&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/net/UriTest.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/net/UriTest.java Sat May 11 04:15:06 2013 @@ -19,6 +19,7 @@ package org.apache.river.api.net; import java.net.MalformedURLException; import java.net.URISyntaxException; +import java.util.Locale; import junit.framework.Assert; import junit.framework.TestCase; @@ -1860,6 +1861,8 @@ public class UriTest extends TestCase { Uri otherGrant = Uri.parseAndCreate("file:/foo/*"); Uri implied = Uri.parseAndCreate("file:/foo/bar"); Uri alsoImplied = Uri.parseAndCreate("file:///foo/bar"); + System.out.println(grant); + System.out.println(implied); Assert.assertTrue(grant.implies(implied)); Assert.assertTrue(grant.implies(alsoImplied)); Assert.assertTrue(otherGrant.implies(implied)); @@ -1873,4 +1876,19 @@ public class UriTest extends TestCase { Assert.assertTrue(result); } + public void testCaseStringEquals() throws Exception { + String a = "zabckel%5f%20klw"; + String b = "ZABCKEL%5F%20KLW"; + boolean result = Uri.asciiStringsUpperCaseEqual(a, b); + Assert.assertTrue(result); + result = Uri.asciiStringsLowerCaseEqual(a, b); + Assert.assertTrue(result); + String A = Uri.toAsciiUpperCase(a); + System.out.println(a); + System.out.println(A); + System.out.println(a.toCharArray()); + System.out.println(new String(a.toCharArray())); + Assert.assertEquals(A, b); + } + }
