From lana.steuck at sun.com Mon May 3 00:37:01 2010 From: lana.steuck at sun.com (lana.steuck at sun.com) Date: Mon, 03 May 2010 00:37:01 +0000 Subject: hg: jdk7/tl: 2 new changesets Message-ID: <20100503003701.4450744A73@hg.openjdk.java.net> Changeset: 97d8b6c659c2 Author: mikejwre Date: 2010-04-22 16:54 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/rev/97d8b6c659c2 Added tag jdk7-b90 for changeset 425ba3efabbf ! .hgtags Changeset: 5f5c33d417f3 Author: mikejwre Date: 2010-04-29 14:32 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/rev/5f5c33d417f3 Added tag jdk7-b91 for changeset 97d8b6c659c2 ! .hgtags From lana.steuck at sun.com Mon May 3 00:37:05 2010 From: lana.steuck at sun.com (lana.steuck at sun.com) Date: Mon, 03 May 2010 00:37:05 +0000 Subject: hg: jdk7/tl/corba: 3 new changesets Message-ID: <20100503003707.ADA0944A74@hg.openjdk.java.net> Changeset: bcd2fc089227 Author: mikejwre Date: 2010-04-22 16:54 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/corba/rev/bcd2fc089227 Added tag jdk7-b90 for changeset 56ce07b0eb47 ! .hgtags Changeset: 930582f667a1 Author: mikejwre Date: 2010-04-29 14:32 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/corba/rev/930582f667a1 Added tag jdk7-b91 for changeset bcd2fc089227 ! .hgtags Changeset: 458c1408450c Author: lana Date: 2010-05-02 15:49 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/corba/rev/458c1408450c Merge From lana.steuck at sun.com Mon May 3 00:38:53 2010 From: lana.steuck at sun.com (lana.steuck at sun.com) Date: Mon, 03 May 2010 00:38:53 +0000 Subject: hg: jdk7/tl/hotspot: 34 new changesets Message-ID: <20100503004003.5E86344A76@hg.openjdk.java.net> Changeset: 4c78b7c16824 Author: trims Date: 2010-04-15 19:08 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/4c78b7c16824 6944398: Bump the HS18 build number to 03 Summary: Update the HS18 build number to 03 Reviewed-by: jcoomes ! make/hotspot_version Changeset: fdd57634910e Author: never Date: 2010-03-18 14:31 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/fdd57634910e 6926979: should simplify catch_inline_exception Reviewed-by: twisti ! src/share/vm/opto/doCall.cpp ! src/share/vm/opto/parse.hpp ! src/share/vm/opto/parse1.cpp ! src/share/vm/runtime/globals.hpp Changeset: 747d26efc5fa Author: twisti Date: 2010-03-30 00:57 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/747d26efc5fa 6939180: Zero locking fix Summary: When Zero is running with Shark enabled threads can be left with their _do_not_unlock_if_synchronized flag incorrectly set. Reviewed-by: twisti Contributed-by: Gary Benson ! src/cpu/zero/vm/cppInterpreter_zero.cpp Changeset: 47742b654fcb Author: twisti Date: 2010-03-31 08:03 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/47742b654fcb 6939731: JSR 292 Zero build fix after 6934494 Summary: The changes of 6934494 have broken the Zero build. Reviewed-by: twisti Contributed-by: Gary Benson ! src/cpu/zero/vm/methodHandles_zero.cpp ! src/cpu/zero/vm/stubRoutines_zero.hpp Changeset: f61d795ce6de Author: never Date: 2010-03-31 11:54 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/f61d795ce6de 6939845: zero needs fallback path in C++ interpreter for platform dependent fast bytecodes Reviewed-by: never Contributed-by: ed at camswl.com ! src/share/vm/interpreter/bytecodeInterpreter.cpp Changeset: 7f4deda46b04 Author: never Date: 2010-03-31 16:29 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/7f4deda46b04 Merge Changeset: 547cbe6dacc5 Author: never Date: 2010-04-01 16:06 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/547cbe6dacc5 6936709: AsyncGetCallTrace doesn't handle inexact stack walking properly Reviewed-by: kvn ! src/share/vm/prims/forte.cpp Changeset: 1c9c45172908 Author: kvn Date: 2010-04-02 11:55 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/1c9c45172908 6939804: ciConstant::print() prints incorrect bool value Summary: Fix typo. Reviewed-by: never ! src/share/vm/ci/ciConstant.cpp Changeset: 9bb91718aaf2 Author: kvn Date: 2010-04-02 15:55 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/9bb91718aaf2 Merge ! src/share/vm/runtime/globals.hpp Changeset: 895d9ade6111 Author: asaha Date: 2010-04-06 22:06 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/895d9ade6111 Merge ! src/share/vm/opto/type.cpp Changeset: a2ea687fdc7c Author: coleenp Date: 2010-03-31 16:51 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/a2ea687fdc7c 6938627: Make temporary directory use property java.io.tmpdir when specified Summary: Get java.io.tmpdir property in os::get_temp_directory() and call this instead of harcoding "/tmp". Don't assume trailing file_separator either. Reviewed-by: dholmes, kamg ! src/os/linux/vm/attachListener_linux.cpp ! src/os/linux/vm/os_linux.cpp ! src/os/linux/vm/perfMemory_linux.cpp ! src/os/solaris/vm/attachListener_solaris.cpp ! src/os/solaris/vm/os_solaris.cpp ! src/os/solaris/vm/perfMemory_solaris.cpp ! src/os/windows/vm/os_windows.cpp ! src/os/windows/vm/perfMemory_windows.cpp ! src/share/vm/compiler/compileBroker.cpp ! src/share/vm/utilities/ostream.cpp ! src/share/vm/utilities/vmError.cpp Changeset: 0fd6320854d3 Author: jcoomes Date: 2010-04-02 17:04 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/0fd6320854d3 Merge Changeset: 6ccd32c284ac Author: kamg Date: 2010-04-07 12:28 -0400 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/6ccd32c284ac Merge Changeset: 56507bcd639e Author: tonyp Date: 2010-03-30 15:36 -0400 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/56507bcd639e 6937160: G1: should observe GCTimeRatio Summary: Remove the G1GCPercent parameter, that specifies the desired GC overhead percentage in G1, and observe the GCTimeRatio parameter instead. Reviewed-by: jmasa, johnc ! src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp ! src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp ! src/share/vm/gc_implementation/g1/g1_globals.hpp ! src/share/vm/runtime/arguments.cpp Changeset: 781e29eb8e08 Author: tonyp Date: 2010-04-02 12:10 -0400 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/781e29eb8e08 6677708: G1: re-enable parallel RSet updating and scanning Summary: Enable parallel RSet updating and scanning. Reviewed-by: iveresov, jmasa ! src/share/vm/gc_implementation/g1/g1_globals.hpp Changeset: 72f725c5a7be Author: tonyp Date: 2010-04-05 12:19 -0400 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/72f725c5a7be 6940310: G1: MT-unsafe calls to CM::region_stack_push() / CM::region_stack_pop() Summary: Calling the methods region_stack_push() and region_stack_pop() concurrent is not MT-safe. The assumption is that we will only call region_stack_push() during a GC pause and region_stack_pop() during marking. Unfortunately, we also call region_stack_push() during marking which seems to be introducing subtle marking failures. This change introduces lock-based methods for pushing / popping to be called during marking. Reviewed-by: iveresov, johnc ! src/share/vm/gc_implementation/g1/concurrentMark.cpp ! src/share/vm/gc_implementation/g1/concurrentMark.hpp ! src/share/vm/runtime/mutexLocker.cpp ! src/share/vm/runtime/mutexLocker.hpp Changeset: 23b1b27ac76c Author: tonyp Date: 2010-04-06 10:59 -0400 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/23b1b27ac76c 6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.") Summary: Make sure that two marking cycles do not overlap, i.e., a new one can only start after the concurrent marking thread finishes all its work. In the fix I piggy-back a couple of minor extra fixes: some general code reformatting for consistency (only around the code I modified), the removal of a field (G1CollectorPolicy::_should_initiate_conc_mark) which doesn't seem to be used at all (it's only set but never read), as well as moving the "is GC locker active" test earlier into the G1 pause / Full GC and using a more appropriate method for it. Reviewed-by: johnc, jmasa, jcoomes, ysr ! src/share/vm/gc_implementation/g1/concurrentMark.cpp ! src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp ! src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp ! src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp ! src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Changeset: bda703475ded Author: johnc Date: 2010-04-07 11:43 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/bda703475ded 6940894: G1: assert(new_obj != 0 || ... "should be forwarded") for compaction tests Summary: Humongous regions may contain multiple objects as a result of being retained as to-space from a previous GC and then re-used as to-space after being tagged as humongous. These changes include a check that causes retained to-space regions that are now tagged as humongous to be disregarded and a new to-space region allocated. Reviewed-by: tonyp, iveresov ! src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Changeset: 6b73e879f1c2 Author: tonyp Date: 2010-04-09 13:08 -0400 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/6b73e879f1c2 Merge Changeset: e4c77b879561 Author: tonyp Date: 2010-04-09 15:01 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/e4c77b879561 Merge Changeset: ed4f78aa9282 Author: twisti Date: 2010-04-06 13:39 +0200 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/ed4f78aa9282 6940520: CodeCache::scavenge_root_nmethods_do must fix oop relocations Summary: ScavengeRootsInCode can lead to unfixed code-embedded oops. Reviewed-by: kvn, never ! src/share/vm/code/codeCache.cpp Changeset: 0dc88ad3244e Author: kvn Date: 2010-04-06 15:18 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/0dc88ad3244e 6940677: Use 64 bytes chunk copy for arraycopy on Sparc Summary: For large arrays we should use 64 bytes chunks copy. Reviewed-by: twisti ! src/cpu/sparc/vm/stubGenerator_sparc.cpp Changeset: 6476042f815c Author: kvn Date: 2010-04-07 09:37 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/6476042f815c 6940701: Don't align loops in stubs for Niagara sparc Summary: Don't align loops in stubs for Niagara sparc since NOPs are expensive. Reviewed-by: twisti, never ! src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp ! src/cpu/sparc/vm/c2_globals_sparc.hpp ! src/cpu/sparc/vm/globals_sparc.hpp ! src/cpu/sparc/vm/stubGenerator_sparc.cpp ! src/cpu/sparc/vm/vm_version_sparc.cpp ! src/cpu/x86/vm/c2_globals_x86.hpp ! src/cpu/x86/vm/globals_x86.hpp ! src/cpu/x86/vm/stubGenerator_x86_32.cpp ! src/cpu/x86/vm/stubGenerator_x86_64.cpp ! src/share/vm/opto/c2_globals.hpp ! src/share/vm/runtime/globals.hpp Changeset: b9d85fcdf743 Author: kvn Date: 2010-04-07 10:35 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/b9d85fcdf743 6940733: allocate non static oop fields in super and sub classes together Summary: Use FieldsAllocationStyle=2 to allocate non static oop fields in super and sub classes together Reviewed-by: twisti ! src/share/vm/classfile/classFileParser.cpp ! src/share/vm/runtime/globals.hpp Changeset: 9e321dcfa5b7 Author: kvn Date: 2010-04-07 12:39 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/9e321dcfa5b7 6940726: Use BIS instruction for allocation prefetch on Sparc Summary: Use BIS instruction for allocation prefetch on Sparc Reviewed-by: twisti ! src/cpu/sparc/vm/sparc.ad ! src/cpu/sparc/vm/vm_version_sparc.cpp ! src/share/vm/memory/threadLocalAllocBuffer.hpp ! src/share/vm/opto/macro.cpp ! src/share/vm/opto/memnode.hpp ! src/share/vm/runtime/globals.hpp Changeset: 93767e6a2dfd Author: twisti Date: 2010-04-08 10:55 +0200 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/93767e6a2dfd 6941529: SharedRuntime::raw_exception_handler_for_return_address must reset thread MethodHandle flag Summary: During testing a bug was hit when an exception returned to the interpreter and the SP was wrong. Reviewed-by: kvn, never ! src/cpu/x86/vm/c1_Runtime1_x86.cpp ! src/cpu/x86/vm/runtime_x86_32.cpp ! src/cpu/x86/vm/sharedRuntime_x86_64.cpp ! src/cpu/x86/vm/stubGenerator_x86_32.cpp ! src/share/vm/opto/runtime.cpp ! src/share/vm/runtime/sharedRuntime.cpp ! src/share/vm/runtime/thread.hpp Changeset: 0a43776437b6 Author: iveresov Date: 2010-04-08 12:13 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/0a43776437b6 6942223: c1 64 bit fixes Summary: This fixes lir_cmp_l2i on x64 and sparc 64bit, and the debug info generation. Reviewed-by: never ! src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp ! src/cpu/x86/vm/assembler_x86.cpp ! src/cpu/x86/vm/c1_LIRAssembler_x86.cpp ! src/share/vm/c1/c1_LinearScan.cpp Changeset: 213fbcf54799 Author: jrose Date: 2010-04-08 17:45 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/213fbcf54799 Merge Changeset: fc3cd2277dc7 Author: jrose Date: 2010-04-13 13:01 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/fc3cd2277dc7 Merge Changeset: e16cca0aa5e1 Author: trims Date: 2010-04-15 19:08 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/e16cca0aa5e1 Merge Changeset: 25f53b53aaa3 Author: trims Date: 2010-04-15 19:09 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/25f53b53aaa3 Added tag hs18-b02 for changeset 4b60f23c4223 ! .hgtags Changeset: 605c9707a766 Author: trims Date: 2010-04-20 21:38 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/605c9707a766 Merge ! .hgtags Changeset: e0a1a502e402 Author: mikejwre Date: 2010-04-22 16:54 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/e0a1a502e402 Added tag jdk7-b90 for changeset 605c9707a766 ! .hgtags Changeset: 03a8443caa4b Author: mikejwre Date: 2010-04-29 14:32 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/03a8443caa4b Added tag jdk7-b91 for changeset e0a1a502e402 ! .hgtags From lana.steuck at sun.com Mon May 3 00:42:59 2010 From: lana.steuck at sun.com (lana.steuck at sun.com) Date: Mon, 03 May 2010 00:42:59 +0000 Subject: hg: jdk7/tl/jaxp: 2 new changesets Message-ID: <20100503004259.E1D8B44A77@hg.openjdk.java.net> Changeset: b89b2c3044a2 Author: mikejwre Date: 2010-04-22 16:54 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jaxp/rev/b89b2c3044a2 Added tag jdk7-b90 for changeset c5d932ee326d ! .hgtags Changeset: e6a40e4bb104 Author: mikejwre Date: 2010-04-29 14:32 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jaxp/rev/e6a40e4bb104 Added tag jdk7-b91 for changeset b89b2c3044a2 ! .hgtags From lana.steuck at sun.com Mon May 3 00:43:03 2010 From: lana.steuck at sun.com (lana.steuck at sun.com) Date: Mon, 03 May 2010 00:43:03 +0000 Subject: hg: jdk7/tl/jaxws: 2 new changesets Message-ID: <20100503004303.8BBCD44A78@hg.openjdk.java.net> Changeset: cf4686bf35ab Author: mikejwre Date: 2010-04-22 16:54 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jaxws/rev/cf4686bf35ab Added tag jdk7-b90 for changeset ead7c4566a00 ! .hgtags Changeset: df7c033f6a11 Author: mikejwre Date: 2010-04-29 14:32 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jaxws/rev/df7c033f6a11 Added tag jdk7-b91 for changeset cf4686bf35ab ! .hgtags From lana.steuck at sun.com Mon May 3 00:45:10 2010 From: lana.steuck at sun.com (lana.steuck at sun.com) Date: Mon, 03 May 2010 00:45:10 +0000 Subject: hg: jdk7/tl/jdk: 25 new changesets Message-ID: <20100503005022.C7F0B44A79@hg.openjdk.java.net> Changeset: 471c3c1f18d1 Author: bae Date: 2010-04-20 11:06 +0400 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/471c3c1f18d1 6936389: FontManager.fileCloser may cause memory leak in applets Reviewed-by: igor, prr, ant ! src/share/classes/sun/font/SunFontManager.java ! src/share/classes/sun/java2d/Disposer.java ! src/share/classes/sun/java2d/loops/GraphicsPrimitive.java ! src/solaris/classes/sun/awt/X11/XToolkit.java ! src/solaris/classes/sun/awt/X11GraphicsDevice.java ! src/solaris/classes/sun/awt/motif/MToolkit.java ! src/windows/classes/sun/awt/windows/WToolkit.java ! src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java + test/sun/awt/font/ClassLoaderLeakTest.java Changeset: bd5d1afc00ab Author: lana Date: 2010-04-20 16:47 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/bd5d1afc00ab Merge Changeset: 43b8a8bc8208 Author: uta Date: 2010-04-14 15:28 +0400 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/43b8a8bc8208 6920842: Wheel events do not bubbling to the browser if they was not treated in applet. Reviewed-by: art, anthony, peterz ! src/share/classes/java/awt/Component.java ! src/share/classes/java/awt/Container.java ! src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java Changeset: ba8ecdbf0b88 Author: lana Date: 2010-04-15 15:19 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/ba8ecdbf0b88 Merge - make/tools/src/build/tools/charsetmapping/CharsetMapping.java - make/tools/src/build/tools/charsetmapping/GenerateDBCS.java - make/tools/src/build/tools/charsetmapping/GenerateEUC_TW.java - make/tools/src/build/tools/charsetmapping/GenerateMapping.java - make/tools/src/build/tools/charsetmapping/GenerateSBCS.java - src/share/classes/sun/io/ByteToCharHKSCS.java - src/share/classes/sun/io/ByteToCharHKSCS_2001.java - src/share/classes/sun/io/CharToByteHKSCS.java - src/share/classes/sun/io/CharToByteHKSCS_2001.java - src/share/classes/sun/nio/cs/ext/Big5.java - src/share/classes/sun/nio/cs/ext/HKSCS_2001.java - test/java/net/Socket/FDClose.java - test/lib/security/cacerts/VerifyCACerts.java Changeset: f51dc9fc72d3 Author: lana Date: 2010-04-20 16:48 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/f51dc9fc72d3 Merge Changeset: b48c141258e1 Author: peytoia Date: 2010-04-13 13:47 +0900 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/b48c141258e1 6709938: RFE: Support more scripts in JDK logical fonts using new fonts in Windows XP and later. Reviewed-by: okutsu ! src/windows/classes/sun/awt/windows/fontconfig.properties Changeset: 98359a01cbe0 Author: okutsu Date: 2010-04-14 13:53 +0900 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/98359a01cbe0 6941948: NumaricShaper.shape() doesn't work with NumericShaper.Range.EASTERN_ARABIC Reviewed-by: peytoia ! src/share/classes/java/awt/font/NumericShaper.java + test/java/awt/font/NumericShaper/EasternArabicTest.java Changeset: 4d8b1b04544c Author: lana Date: 2010-04-15 11:51 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/4d8b1b04544c Merge - make/tools/src/build/tools/charsetmapping/CharsetMapping.java - make/tools/src/build/tools/charsetmapping/GenerateDBCS.java - make/tools/src/build/tools/charsetmapping/GenerateEUC_TW.java - make/tools/src/build/tools/charsetmapping/GenerateMapping.java - make/tools/src/build/tools/charsetmapping/GenerateSBCS.java - src/share/classes/sun/io/ByteToCharHKSCS.java - src/share/classes/sun/io/ByteToCharHKSCS_2001.java - src/share/classes/sun/io/CharToByteHKSCS.java - src/share/classes/sun/io/CharToByteHKSCS_2001.java - src/share/classes/sun/nio/cs/ext/Big5.java - src/share/classes/sun/nio/cs/ext/HKSCS_2001.java ! src/windows/classes/sun/awt/windows/fontconfig.properties - test/java/net/Socket/FDClose.java - test/lib/security/cacerts/VerifyCACerts.java Changeset: 17d17234a1d9 Author: okutsu Date: 2010-04-16 15:53 +0900 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/17d17234a1d9 6609675: [Fmt-Da] DateFormat.parse() on a timezone changes its calendar's timezone Reviewed-by: peytoia ! src/share/classes/java/text/DateFormat.java ! src/share/classes/java/text/SimpleDateFormat.java Changeset: f75f5e2274d5 Author: rupashka Date: 2010-04-16 13:05 +0400 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/f75f5e2274d5 6922179: SynthTextPaneUI.installUI() doesn't set component to opaque as specified Reviewed-by: alexp ! src/share/classes/javax/swing/plaf/basic/BasicTextUI.java Changeset: 584dcb7ecaf9 Author: naoto Date: 2010-04-19 14:48 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/584dcb7ecaf9 6943941: Rebranding issues with some tests in jdk/test/java/util Reviewed-by: ohair ! test/java/util/Locale/Bug4175998Test.java ! test/java/util/ResourceBundle/Bug4083270Test.java ! test/java/util/ResourceBundle/Bug4165815Test.java ! test/java/util/ResourceBundle/Bug4168625Class.java ! test/java/util/ResourceBundle/Bug4168625Getter.java ! test/java/util/ResourceBundle/Bug4168625Resource.java ! test/java/util/ResourceBundle/Bug4168625Resource2.java ! test/java/util/ResourceBundle/Bug4168625Resource2_en_US.java ! test/java/util/ResourceBundle/Bug4168625Resource3.java ! test/java/util/ResourceBundle/Bug4168625Resource3_en.java ! test/java/util/ResourceBundle/Bug4168625Resource3_en_CA.java ! test/java/util/ResourceBundle/Bug4168625Resource3_en_IE.java ! test/java/util/ResourceBundle/Bug4168625Resource3_en_US.java ! test/java/util/ResourceBundle/Bug4177489Test.java ! test/java/util/ResourceBundle/Bug4177489_Resource.java ! test/java/util/ResourceBundle/Bug4177489_Resource_jf.java Changeset: 2571720800a6 Author: peytoia Date: 2010-04-20 15:01 +0900 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/2571720800a6 6945238: (tz) Support tzdata2010i Reviewed-by: okutsu ! make/sun/javazic/tzdata/VERSION ! make/sun/javazic/tzdata/africa ! make/sun/javazic/tzdata/asia ! make/sun/javazic/tzdata/southamerica Changeset: 0d9662f62d0d Author: lana Date: 2010-04-20 16:50 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/0d9662f62d0d Merge Changeset: 884df20e9cce Author: lana Date: 2010-04-20 16:51 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/884df20e9cce Merge - make/tools/CharsetMapping/Big5.c2b Changeset: 9bf334e32d35 Author: yhuang Date: 2010-01-21 22:05 -0800 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/9bf334e32d35 6916787: Ukrainian currency name needs to be fixed Reviewed-by: yhuang, peytoia ! src/share/classes/sun/util/resources/CurrencyNames_uk_UA.properties ! test/sun/text/resources/LocaleData ! test/sun/text/resources/LocaleDataTest.java Changeset: 00890dd53f45 Author: yhuang Date: 2010-01-27 23:19 -0800 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/00890dd53f45 6919624: minimalDaysInFirstWeek ressource for hungarian is wrong Reviewed-by: yhuang, peytoia ! src/share/classes/sun/util/resources/CalendarData_hu.properties ! test/sun/text/resources/LocaleData ! test/sun/text/resources/LocaleDataTest.java Changeset: 0173ef08dcc8 Author: yhuang Date: 2010-02-11 20:59 -0800 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/0173ef08dcc8 6776102: sun/util/resources/TimeZone/Bug6317929.java test failed against 6u12b01 and passed against 6u11b03 Reviewed-by: yhuang, peytoia ! test/sun/util/resources/TimeZone/Bug6317929.java Changeset: b2485d8eba40 Author: yhuang Date: 2010-04-11 21:04 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/b2485d8eba40 Merge - make/java/redist/FILES.gmk - make/java/text/FILES_java.gmk - make/sun/nio/FILES_java.gmk - src/share/classes/sun/dyn/util/BytecodeSignature.java - src/solaris/classes/sun/nio/ch/SctpSocketDispatcher.java Changeset: babd3f260d32 Author: yhuang Date: 2010-04-11 23:21 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/babd3f260d32 6875904: Java 7 message synchronization 1 Reviewed-by: ogino, faryad ! make/sun/launcher/Makefile ! src/share/classes/com/sun/rowset/RowSetResourceBundle_de.properties ! src/share/classes/com/sun/rowset/RowSetResourceBundle_es.properties ! src/share/classes/com/sun/rowset/RowSetResourceBundle_fr.properties ! src/share/classes/com/sun/rowset/RowSetResourceBundle_it.properties ! src/share/classes/com/sun/rowset/RowSetResourceBundle_ja.properties ! src/share/classes/com/sun/rowset/RowSetResourceBundle_ko.properties ! src/share/classes/com/sun/rowset/RowSetResourceBundle_sv.properties ! src/share/classes/com/sun/rowset/RowSetResourceBundle_zh_CN.properties ! src/share/classes/com/sun/rowset/RowSetResourceBundle_zh_TW.properties ! src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_de.properties ! src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_es.properties ! src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_fr.properties ! src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_it.properties ! src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties ! src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties ! src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_sv.properties ! src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties ! src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties + src/share/classes/sun/launcher/resources/launcher_de.properties + src/share/classes/sun/launcher/resources/launcher_es.properties + src/share/classes/sun/launcher/resources/launcher_fr.properties + src/share/classes/sun/launcher/resources/launcher_it.properties + src/share/classes/sun/launcher/resources/launcher_ja.properties + src/share/classes/sun/launcher/resources/launcher_ko.properties + src/share/classes/sun/launcher/resources/launcher_sv.properties + src/share/classes/sun/launcher/resources/launcher_zh_CN.properties + src/share/classes/sun/launcher/resources/launcher_zh_TW.properties ! src/share/classes/sun/management/resources/agent_de.properties ! src/share/classes/sun/management/resources/agent_es.properties ! src/share/classes/sun/management/resources/agent_fr.properties ! src/share/classes/sun/management/resources/agent_it.properties ! src/share/classes/sun/management/resources/agent_ja.properties ! src/share/classes/sun/management/resources/agent_ko.properties ! src/share/classes/sun/management/resources/agent_sv.properties ! src/share/classes/sun/management/resources/agent_zh_CN.properties ! src/share/classes/sun/management/resources/agent_zh_TW.properties ! src/share/classes/sun/security/tools/JarSignerResources_ja.java ! src/share/classes/sun/security/tools/JarSignerResources_zh_CN.java ! src/share/classes/sun/security/util/AuthResources_de.java ! src/share/classes/sun/security/util/AuthResources_es.java ! src/share/classes/sun/security/util/AuthResources_fr.java ! src/share/classes/sun/security/util/AuthResources_it.java ! src/share/classes/sun/security/util/AuthResources_ja.java ! src/share/classes/sun/security/util/AuthResources_ko.java ! src/share/classes/sun/security/util/AuthResources_sv.java ! src/share/classes/sun/security/util/AuthResources_zh_CN.java ! src/share/classes/sun/security/util/AuthResources_zh_TW.java ! src/share/classes/sun/tools/jconsole/resources/JConsoleResources_ja.java ! src/share/classes/sun/tools/jconsole/resources/JConsoleResources_zh_CN.java Changeset: 7794a4a38e99 Author: yhuang Date: 2010-04-20 01:24 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/7794a4a38e99 Merge - make/tools/src/build/tools/charsetmapping/CharsetMapping.java - make/tools/src/build/tools/charsetmapping/GenerateDBCS.java - make/tools/src/build/tools/charsetmapping/GenerateEUC_TW.java - make/tools/src/build/tools/charsetmapping/GenerateMapping.java - make/tools/src/build/tools/charsetmapping/GenerateSBCS.java - src/share/classes/sun/io/ByteToCharHKSCS.java - src/share/classes/sun/io/ByteToCharHKSCS_2001.java - src/share/classes/sun/io/CharToByteHKSCS.java - src/share/classes/sun/io/CharToByteHKSCS_2001.java - src/share/classes/sun/nio/cs/ext/Big5.java - src/share/classes/sun/nio/cs/ext/HKSCS_2001.java - test/java/net/Socket/FDClose.java - test/lib/security/cacerts/VerifyCACerts.java Changeset: b5ae88dd3dbd Author: mikejwre Date: 2010-04-28 20:04 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/b5ae88dd3dbd Merge Changeset: ab117ded3e3f Author: mikejwre Date: 2010-04-22 16:54 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/ab117ded3e3f Added tag jdk7-b90 for changeset 7f90d0b9dbb7 ! .hgtags Changeset: 08a31cab971f Author: mikejwre Date: 2010-04-29 13:53 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/08a31cab971f Merge - make/tools/CharsetMapping/Big5.c2b Changeset: f2dce7210cc0 Author: mikejwre Date: 2010-04-29 14:32 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/f2dce7210cc0 Added tag jdk7-b91 for changeset 08a31cab971f ! .hgtags Changeset: 937ec1a4ea35 Author: lana Date: 2010-05-02 15:54 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/937ec1a4ea35 Merge From lana.steuck at sun.com Mon May 3 00:57:57 2010 From: lana.steuck at sun.com (lana.steuck at sun.com) Date: Mon, 03 May 2010 00:57:57 +0000 Subject: hg: jdk7/tl/langtools: 7 new changesets Message-ID: <20100503005810.2C69144A7A@hg.openjdk.java.net> Changeset: 06e06ec0d6f2 Author: yhuang Date: 2010-04-11 23:24 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/06e06ec0d6f2 6875904: Java 7 message synchronization 1 Reviewed-by: ogino, faryad ! src/share/classes/com/sun/tools/apt/resources/apt_ja.properties ! src/share/classes/com/sun/tools/apt/resources/apt_zh_CN.properties ! src/share/classes/com/sun/tools/doclets/formats/html/resources/standard_ja.properties ! src/share/classes/com/sun/tools/doclets/formats/html/resources/standard_zh_CN.properties ! src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_ja.properties ! src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_zh_CN.properties ! src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties ! src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties ! src/share/classes/com/sun/tools/javac/resources/javac_ja.properties ! src/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties Changeset: 053bf290d575 Author: yhuang Date: 2010-04-20 01:30 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/053bf290d575 Merge - test/tools/javap/T6305779.java Changeset: b68de5eee27b Author: mikejwre Date: 2010-04-28 20:04 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/b68de5eee27b Merge Changeset: ebf79cbf5711 Author: mikejwre Date: 2010-04-22 16:54 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/ebf79cbf5711 Added tag jdk7-b90 for changeset 71c2c23a7c35 ! .hgtags Changeset: 97b6fa97b8dd Author: mikejwre Date: 2010-04-29 14:10 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/97b6fa97b8dd Merge ! test/tools/javac/generics/diamond/neg/Neg01.java ! test/tools/javac/generics/diamond/neg/Neg01.out ! test/tools/javac/generics/diamond/neg/Neg02.java ! test/tools/javac/generics/diamond/neg/Neg02.out ! test/tools/javac/generics/diamond/neg/Neg03.java ! test/tools/javac/generics/diamond/neg/Neg03.out ! test/tools/javac/generics/diamond/neg/Neg04.java ! test/tools/javac/generics/diamond/neg/Neg04.out ! test/tools/javac/generics/diamond/neg/Neg05.java ! test/tools/javac/generics/diamond/neg/Neg05.out ! test/tools/javac/generics/diamond/pos/Pos01.java ! test/tools/javac/generics/diamond/pos/Pos02.java ! test/tools/javac/generics/diamond/pos/Pos03.java ! test/tools/javac/generics/diamond/pos/Pos04.java Changeset: 98cba5876cb5 Author: mikejwre Date: 2010-04-29 14:33 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/98cba5876cb5 Added tag jdk7-b91 for changeset 97b6fa97b8dd ! .hgtags Changeset: c399da99fa16 Author: lana Date: 2010-05-02 15:55 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/c399da99fa16 Merge From Ulf.Zibis at gmx.de Mon May 3 11:40:44 2010 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Mon, 03 May 2010 13:40:44 +0200 Subject: Performance of locally copied members ? Message-ID: <4BDEB63C.7060004@gmx.de> Hi, in class String I often see member variables copied to local variables. In java.nio.Buffer I don't see that (e.g. for "position" in nextPutIndex(int nb)). Now I'm wondering. From JMM (Java-Memory-Model) I learned, that jvm can hold non-volatile variables in a cache for each thread, so e.g. even in CPU register for few ones. From this knowing, I don't understand, why doing the local caching manually in String (and many other classes), instead trusting on the JVM. Can anybody help me in understanding this ? -Ulf From martinrb at google.com Mon May 3 17:29:47 2010 From: martinrb at google.com (Martin Buchholz) Date: Mon, 3 May 2010 10:29:47 -0700 Subject: Performance of locally copied members ? In-Reply-To: <4BDEB63C.7060004@gmx.de> References: <4BDEB63C.7060004@gmx.de> Message-ID: It's a coding style made popular by Doug Lea. It's an extreme optimization that probably isn't necessary; you can expect the JIT to make the same optimizations. (you can try to check the machine code yourself!) Nevertheless, copying to locals produces the smallest bytecode, and for low-level code it's nice to write code that's a little closer to the machine. Also, optimizations of finals (can cache even across volatile reads) could be better. John Rose is working on that. For some algorithms in j.u.c, copying to a local is necessary for correctness. Martin On Mon, May 3, 2010 at 04:40, Ulf Zibis wrote: > Hi, > > in class String I often see member variables copied to local variables. > In java.nio.Buffer I don't see that (e.g. for "position" in nextPutIndex(int > nb)). > Now I'm wondering. > > From JMM (Java-Memory-Model) I learned, that jvm can hold non-volatile > variables in a cache for each thread, so e.g. even in CPU register for few > ones. > From this knowing, I don't understand, why doing the local caching manually > in String (and many other classes), instead trusting on the JVM. > > Can anybody help me in understanding this ? > > -Ulf > > > From Ulf.Zibis at gmx.de Mon May 3 18:24:57 2010 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Mon, 03 May 2010 20:24:57 +0200 Subject: Performance of locally copied members ? In-Reply-To: References: <4BDEB63C.7060004@gmx.de> Message-ID: <4BDF14F9.9030904@gmx.de> Am 03.05.2010 19:29, schrieb Martin Buchholz: > It's a coding style made popular by Doug Lea. > It's an extreme optimization that probably isn't necessary; > you can expect the JIT to make the same optimizations. > (you can try to check the machine code yourself!) > Nevertheless, copying to locals produces the smallest > bytecode, and for low-level code it's nice to write code > that's a little closer to the machine. > Much thanks! Can I guess, that you agree, that j.n.X-Buffer classes are enough low-level, to "correct" the code in that manner? > Also, optimizations of finals (can cache even across volatile > reads) could be better. John Rose is working on that. > > For some algorithms in j.u.c, > copying to a local is necessary for correctness. > What is j.u.c ? -Ulf > Martin > > On Mon, May 3, 2010 at 04:40, Ulf Zibis wrote: > >> Hi, >> >> in class String I often see member variables copied to local variables. >> In java.nio.Buffer I don't see that (e.g. for "position" in nextPutIndex(int >> nb)). >> Now I'm wondering. >> >> From JMM (Java-Memory-Model) I learned, that jvm can hold non-volatile >> variables in a cache for each thread, so e.g. even in CPU register for few >> ones. >> From this knowing, I don't understand, why doing the local caching manually >> in String (and many other classes), instead trusting on the JVM. >> >> Can anybody help me in understanding this ? >> >> -Ulf >> >> >> >> > > From martinrb at google.com Mon May 3 18:42:55 2010 From: martinrb at google.com (Martin Buchholz) Date: Mon, 3 May 2010 11:42:55 -0700 Subject: Performance of locally copied members ? In-Reply-To: <4BDF14F9.9030904@gmx.de> References: <4BDEB63C.7060004@gmx.de> <4BDF14F9.9030904@gmx.de> Message-ID: On Mon, May 3, 2010 at 11:24, Ulf Zibis wrote: > Am 03.05.2010 19:29, schrieb Martin Buchholz: >> >> It's a coding style made popular by Doug Lea. >> It's an extreme optimization that probably isn't necessary; >> you can expect the JIT to make the same optimizations. >> (you can try to check the machine code yourself!) >> Nevertheless, copying to locals produces the smallest >> bytecode, and for low-level code it's nice to write code >> that's a little closer to the machine. >> > > Much thanks! > Can I guess, that you agree, that j.n.X-Buffer classes are enough low-level, > to "correct" the code in that manner? I think that yes, in those classes copying fields to locals would be preferred, but maybe not worth it unless already making changes there (which we are). >> Also, optimizations of finals (can cache even across volatile >> reads) could be better. ?John Rose is working on that. >> >> For some algorithms in j.u.c, >> copying to a local is necessary for correctness. >> > > What is j.u.c ? java.util.concurrent. > -Ulf > > >> Martin >> >> On Mon, May 3, 2010 at 04:40, Ulf Zibis ?wrote: >> >>> >>> Hi, >>> >>> in class String I often see member variables copied to local variables. >>> In java.nio.Buffer I don't see that (e.g. for "position" in >>> nextPutIndex(int >>> nb)). >>> Now I'm wondering. >>> >>> ?From JMM (Java-Memory-Model) I learned, that jvm can hold non-volatile >>> variables in a cache for each thread, so e.g. even in CPU register for >>> few >>> ones. >>> ?From this knowing, I don't understand, why doing the local caching >>> manually >>> in String (and many other classes), instead trusting on the JVM. >>> >>> Can anybody help me in understanding this ? >>> >>> -Ulf >>> >>> >>> >>> >> >> > > From opinali at gmail.com Mon May 3 20:13:44 2010 From: opinali at gmail.com (Osvaldo Doederlein) Date: Mon, 3 May 2010 17:13:44 -0300 Subject: Performance of locally copied members ? In-Reply-To: References: <4BDEB63C.7060004@gmx.de> Message-ID: 2010/5/3 Martin Buchholz > It's a coding style made popular by Doug Lea. > It's an extreme optimization that probably isn't necessary; > you can expect the JIT to make the same optimizations. > It certainly is necessary - unfortunately. Testing my particle/octree-based 3D renderer without this manual optimization (dumping FPS performance each 100 frames, begin at 10th score after startup): JDK 6u21-b03, Hotspot Client: 159.4896331738437fps 161.29032258064515fps 158.73015873015873fps 160.0fps 159.23566878980893fps JDK 6u21-b03, Hotspot Server: 197.23865877712032fps 204.91803278688525fps 196.07843137254903fps 200.40080160320642fps 198.01980198019803fps Now let's cache 8 instance variables into local variables (most final, a couple non-final ones too): JDK 6u21-b03, Hotspot Client: 169.4915254237288fps 172.1170395869191fps 168.63406408094434fps 168.0672268907563fps 170.64846416382252fps JDK 6u21-b03, Hotspot Server: 197.62845849802372fps 200.40080160320642fps 196.8503937007874fps 199.6007984031936fps 203.2520325203252fps So, the manual optimization makes no difference for Hotspot Server; but hell it does for Client - 6% better performance in this test; and the test is not only the complex, deeply nested rendering loops that use those cacheable variables to read the input data and update the output pixel and Z buffers - there's also other code that burns significant CPU and doesn't use these variables, remarkably buffer filling and copying steps. This means the speedup in the optimized code should be much higher than 6%, I only reported / cared to measure the application's global performance. We'll need to deal with HotSpot Client for years to come, not to mention smaller platforms (JavaME, JavaFX Mobile&TV) which JIT compilers are even lesser than JavaSE's C1. Tuned bytecode is also faster to interpret, which benefits warm-up time too. Please keep your dirty purist hands off the API code that Doug and others micro-optimized; it is necessary. :) And my +1 to add the same opts to other perf-critical APIs. Even most important for java.nio as under C1, it doesn't currently benefit from intrinsic compilation of critical DirectBuffer methods. A+ Osvaldo > (you can try to check the machine code yourself!) > Nevertheless, copying to locals produces the smallest > bytecode, and for low-level code it's nice to write code > that's a little closer to the machine. > > Also, optimizations of finals (can cache even across volatile > reads) could be better. John Rose is working on that. > > For some algorithms in j.u.c, > copying to a local is necessary for correctness. > > Martin > > On Mon, May 3, 2010 at 04:40, Ulf Zibis wrote: > > Hi, > > > > in class String I often see member variables copied to local variables. > > In java.nio.Buffer I don't see that (e.g. for "position" in > nextPutIndex(int > > nb)). > > Now I'm wondering. > > > > From JMM (Java-Memory-Model) I learned, that jvm can hold non-volatile > > variables in a cache for each thread, so e.g. even in CPU register for > few > > ones. > > From this knowing, I don't understand, why doing the local caching > manually > > in String (and many other classes), instead trusting on the JVM. > > > > Can anybody help me in understanding this ? > > > > -Ulf > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From martinrb at google.com Mon May 3 20:49:18 2010 From: martinrb at google.com (Martin Buchholz) Date: Mon, 3 May 2010 13:49:18 -0700 Subject: Performance of locally copied members ? In-Reply-To: References: <4BDEB63C.7060004@gmx.de> Message-ID: Osvaldo, Thanks for the interesting measurements. I have already assimilated this optimization into my own coding style, but have hesitated to publicize it or to require it of others, partly because one hopes that future JIT improvements will obsolete it. It seems likely that we "system programmers" will need to help the compiler make the best code forever, but the nature of that help changes (slowly). Martin On Mon, May 3, 2010 at 13:13, Osvaldo Doederlein wrote: > 2010/5/3 Martin Buchholz >> >> It's a coding style made popular by Doug Lea. >> It's an extreme optimization that probably isn't necessary; >> you can expect the JIT to make the same optimizations. > > It certainly is necessary - unfortunately. Testing my particle/octree-based > 3D renderer without this manual optimization (dumping FPS performance each > 100 frames, begin at 10th score after startup): > > JDK 6u21-b03, Hotspot Client: > 159.4896331738437fps > 161.29032258064515fps > 158.73015873015873fps > 160.0fps > 159.23566878980893fps > > JDK 6u21-b03, Hotspot Server: > 197.23865877712032fps > 204.91803278688525fps > 196.07843137254903fps > 200.40080160320642fps > 198.01980198019803fps > > Now let's cache 8 instance variables into local variables (most final, a > couple non-final ones too): > > JDK 6u21-b03, Hotspot Client: > 169.4915254237288fps > 172.1170395869191fps > 168.63406408094434fps > 168.0672268907563fps > 170.64846416382252fps > > JDK 6u21-b03, Hotspot Server: > 197.62845849802372fps > 200.40080160320642fps > 196.8503937007874fps > 199.6007984031936fps > 203.2520325203252fps > > So, the manual optimization makes no difference for Hotspot Server; but hell > it does for Client - 6% better performance in this test; and the test is not > only the complex, deeply nested rendering loops that use those cacheable > variables to read the input data and update the output pixel and Z buffers - > there's also other code that burns significant CPU and doesn't use these > variables, remarkably buffer filling and copying steps. This means the > speedup in the optimized code should be much higher than 6%, I only reported > / cared to measure the application's global performance. > > We'll need to deal with HotSpot Client for years to come, not to mention > smaller platforms (JavaME, JavaFX Mobile&TV) which JIT compilers are even > lesser than JavaSE's C1. Tuned bytecode is also faster to interpret, which > benefits warm-up time too. Please keep your dirty purist hands off the API > code that Doug and others micro-optimized; it is necessary. :) > > And my +1 to add the same opts to other perf-critical APIs. Even most > important for java.nio as under C1, it doesn't currently benefit from > intrinsic compilation of critical DirectBuffer methods. > > A+ > Osvaldo > > >> >> (you can try to check the machine code yourself!) >> Nevertheless, copying to locals produces the smallest >> bytecode, and for low-level code it's nice to write code >> that's a little closer to the machine. >> >> Also, optimizations of finals (can cache even across volatile >> reads) could be better. ?John Rose is working on that. >> >> For some algorithms in j.u.c, >> copying to a local is necessary for correctness. >> >> Martin >> >> On Mon, May 3, 2010 at 04:40, Ulf Zibis wrote: >> > Hi, >> > >> > in class String I often see member variables copied to local variables. >> > In java.nio.Buffer I don't see that (e.g. for "position" in >> > nextPutIndex(int >> > nb)). >> > Now I'm wondering. >> > >> > From JMM (Java-Memory-Model) I learned, that jvm can hold non-volatile >> > variables in a cache for each thread, so e.g. even in CPU register for >> > few >> > ones. >> > From this knowing, I don't understand, why doing the local caching >> > manually >> > in String (and many other classes), instead trusting on the JVM. >> > >> > Can anybody help me in understanding this ? >> > >> > -Ulf >> > >> > >> > > > From David.Holmes at Oracle.Com Mon May 3 22:27:03 2010 From: David.Holmes at Oracle.Com (David Holmes) Date: Tue, 04 May 2010 08:27:03 +1000 Subject: Performance of locally copied members ? In-Reply-To: References: <4BDEB63C.7060004@gmx.de> Message-ID: <4BDF4DB7.7070705@oracle.com> I've forwarded this to hotspot-compiler-dev. I know Doug introduced this for final fields because at the time the compiler was not optimizing their use, but I had thought that issue was long since resolved at least in C2. If C1 is lagging then we need to see that it catches up. There should not be a need to code this way at the Java-level. (Note, as Martin says sometimes you must copy a field to a local for correctness - the field might change value but the current code must not see that - but that's not the case we're concerned with.) Cheers, David Holmes Osvaldo Doederlein said the following on 05/04/10 06:13: > 2010/5/3 Martin Buchholz > > > It's a coding style made popular by Doug Lea. > It's an extreme optimization that probably isn't necessary; > you can expect the JIT to make the same optimizations. > > > It certainly is necessary - unfortunately. Testing my > particle/octree-based 3D renderer without this manual optimization > (dumping FPS performance each 100 frames, begin at 10th score after > startup): > > JDK 6u21-b03, Hotspot Client: > 159.4896331738437fps > 161.29032258064515fps > 158.73015873015873fps > 160.0fps > 159.23566878980893fps > > JDK 6u21-b03, Hotspot Server: > 197.23865877712032fps > 204.91803278688525fps > 196.07843137254903fps > 200.40080160320642fps > 198.01980198019803fps > > Now let's cache 8 instance variables into local variables (most final, a > couple non-final ones too): > > JDK 6u21-b03, Hotspot Client: > 169.4915254237288fps > 172.1170395869191fps > 168.63406408094434fps > 168.0672268907563fps > 170.64846416382252fps > > JDK 6u21-b03, Hotspot Server: > 197.62845849802372fps > 200.40080160320642fps > 196.8503937007874fps > 199.6007984031936fps > 203.2520325203252fps > > So, the manual optimization makes no difference for Hotspot Server; but > hell it does for Client - 6% better performance in this test; and the > test is not only the complex, deeply nested rendering loops that use > those cacheable variables to read the input data and update the output > pixel and Z buffers - there's also other code that burns significant CPU > and doesn't use these variables, remarkably buffer filling and copying > steps. This means the speedup in the optimized code should be much > higher than 6%, I only reported / cared to measure the application's > global performance. > > We'll need to deal with HotSpot Client for years to come, not to mention > smaller platforms (JavaME, JavaFX Mobile&TV) which JIT compilers are > even lesser than JavaSE's C1. Tuned bytecode is also faster to > interpret, which benefits warm-up time too. Please keep your dirty > purist hands off the API code that Doug and others micro-optimized; it > is necessary. :) > > And my +1 to add the same opts to other perf-critical APIs. Even most > important for java.nio as under C1, it doesn't currently benefit from > intrinsic compilation of critical DirectBuffer methods. > > A+ > Osvaldo > > > > (you can try to check the machine code yourself!) > Nevertheless, copying to locals produces the smallest > bytecode, and for low-level code it's nice to write code > that's a little closer to the machine. > > Also, optimizations of finals (can cache even across volatile > reads) could be better. John Rose is working on that. > > For some algorithms in j.u.c, > copying to a local is necessary for correctness. > > Martin > > On Mon, May 3, 2010 at 04:40, Ulf Zibis > wrote: > > Hi, > > > > in class String I often see member variables copied to local > variables. > > In java.nio.Buffer I don't see that (e.g. for "position" in > nextPutIndex(int > > nb)). > > Now I'm wondering. > > > > From JMM (Java-Memory-Model) I learned, that jvm can hold > non-volatile > > variables in a cache for each thread, so e.g. even in CPU > register for few > > ones. > > From this knowing, I don't understand, why doing the local > caching manually > > in String (and many other classes), instead trusting on the JVM. > > > > Can anybody help me in understanding this ? > > > > -Ulf > > > > > > > > From jonathan.gibbons at sun.com Tue May 4 00:14:44 2010 From: jonathan.gibbons at sun.com (jonathan.gibbons at sun.com) Date: Tue, 04 May 2010 00:14:44 +0000 Subject: hg: jdk7/tl/langtools: 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch') Message-ID: <20100504001446.C42B544D11@hg.openjdk.java.net> Changeset: a6f2911a7c55 Author: mcimadamore Date: 2010-05-03 17:12 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/a6f2911a7c55 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch') Reviewed-by: jjg, darcy + src/share/classes/com/sun/source/tree/DisjointTypeTree.java ! src/share/classes/com/sun/source/tree/Tree.java ! src/share/classes/com/sun/source/tree/TreeVisitor.java ! src/share/classes/com/sun/source/util/SimpleTreeVisitor.java ! src/share/classes/com/sun/source/util/TreeScanner.java ! src/share/classes/com/sun/tools/javac/code/Flags.java ! src/share/classes/com/sun/tools/javac/code/Source.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/Flow.java ! src/share/classes/com/sun/tools/javac/jvm/Gen.java ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java ! src/share/classes/com/sun/tools/javac/resources/compiler.properties ! src/share/classes/com/sun/tools/javac/tree/JCTree.java ! src/share/classes/com/sun/tools/javac/tree/Pretty.java ! src/share/classes/com/sun/tools/javac/tree/TreeCopier.java ! src/share/classes/com/sun/tools/javac/tree/TreeInfo.java ! src/share/classes/com/sun/tools/javac/tree/TreeMaker.java ! src/share/classes/com/sun/tools/javac/tree/TreeScanner.java ! src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java + test/tools/javac/multicatch/Neg01.java + test/tools/javac/multicatch/Neg01.out + test/tools/javac/multicatch/Neg02.java + test/tools/javac/multicatch/Neg02.out + test/tools/javac/multicatch/Neg03.java + test/tools/javac/multicatch/Neg03.out + test/tools/javac/multicatch/Neg04.java + test/tools/javac/multicatch/Neg04.out + test/tools/javac/multicatch/Pos01.java + test/tools/javac/multicatch/Pos02.java + test/tools/javac/multicatch/Pos03.java + test/tools/javac/multicatch/Pos04.java + test/tools/javac/multicatch/Pos05.java From jjb at google.com Wed May 5 04:57:42 2010 From: jjb at google.com (Joshua Bloch) Date: Tue, 4 May 2010 21:57:42 -0700 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: Message-ID: Vladimir, Hi. I'm thrilled that you were able to eke so much more perforance out of this already optimized code. I read your changes on my flight to Pittsburgh. Here's the code review: I think the comment on lines 102-105 was too useful to delete: 102 ... This 103 * method differs from the public {@code sort} method in that the 104 * {@code right} index is inclusive, and it does no range checking 105 * on {@code left} or {@code right}. The sentinel technique that you use in lines 118 - 136 is questionable: you are modifying a portion of the array outside the specified range of the call, which arguably violates the contract of the call, and could be observed in a multithreaded program. It's not beyond the realm of reason that it could break existing clients. I will discuss it with Doug Lea and let you know what he says. If we leave this optimization in, we should change the comments slightly. Appearing to comment-out code (other than entire assertions in inner loops) is never a good thing, hence the change to line 130 and the addition of the line that follows. Also I reworded the commennt in lines 122-125 for clarity. Changed lines are starred, added line has a "+": 118 // Use insertion sort on tiny arrays 119 if (length < INSERTION_SORT_THRESHOLD) { 120 if (left > 0) { 121 /* *122 * Temporarily set the value immediately preceding the range *123 * to the minimum int value to serve as a sentinel. This *124 * allows us to avoid the j >= left check on each iteration. 125 */ 126 int before = a[left - 1]; a[left - 1] = Integer.MIN_VALUE; 127 128 for (int j, i = left + 1; i <= right; i++) { 129 int ai = a[i]; *130 for (j = i - 1; ai < a[j]; j--) { +NEW // assert j >= left; 131 a[j + 1] = a[j]; 132 } 133 a[j + 1] = ai; 134 } 135 a[left - 1] = before; 136 } else { The comment in line 155 is misleading, and should be replace by this: I'd reword the comment in lines 137-140 for clarity: 137 /* 138 * For case, when left == 0, traditional (without a sentinel) 139 * insertion sort, optimized for server VM, is used. 140 */ 155 // Inexpensive approximation of length / 7 The comment strategy for choosing sample points is subtle enough that it deserves bit more commentary. I propose replacing line 158 with this: /* * Sort five evenly spaced elements around (and including) the center * element in the range. These elements will be used for pivot selection * as described below. The choice for spacing these elements was empirically * determined to work well on a wide variety of inputs. */ Lines 183 and 184 are unnecessary array accesses. Probably better is: 183 int pivot1 = ae2; 184 int pivot2 = ae4; This is essentially just a renaming of these two local variables, and presumably the compiler will act accordingly. I prefer the original wording: 197 * Pointer k is the first index of ?-part to the revised wording: 217 * Pointer k is the first index of not inspected ?-part. I'd revert this change. I'd change 190 from: 190 if (pivot1 < pivot2) { to 190 if (pivot1 != pivot2) { It's clearer (this is the "pivots differ" case), and at least as fast. The spacing lines 249 and 250 is a bit quirky: 249 dualPivotQuicksort(a, left, less - 2); 250 dualPivotQuicksort(a, great + 2, right); I'd replace it with the more standard: 249 dualPivotQuicksort(a, left, less - 2); 250 dualPivotQuicksort(a, great + 2, right); Alternatively, you could make corresponding arguments line up: 249 dualPivotQuicksort(a, left, less - 2); 250 dualPivotQuicksort(a, great + 2, right ); The policy change in line 256 is non-trivial: Old: 298 if (less < e1 && great > e5) { New: 256 if (great - less > 5 * seventh) { I previously experimented with the "new-style" policy (length-based, rather than endpoint-based), but didn't get good results. Perhaps the symmetric style combines well with the change in interval size (5/7 vs. 2/3). At any rate, it's simpler than the old-style and conforms to the comment, so if you're satisfied with the performance, I'm happy with it. In lines 362 and 363, you have the same "quirky spacing" as in linkes 249 and 250: 361 // Sort left and right parts recursively 362 dualPivotQuicksort(a, left, less - 1); 363 dualPivotQuicksort(a, great + 1, right); Regards, Josh On Thu, Apr 29, 2010 at 4:05 AM, Vladimir Iaroslavski < vladimir.iaroslavski at googlemail.com> wrote: > Hello, > > Thank you for pointing to this check, I have run test again and it > works little it faster > (this check was necessary for old version of insertion sort): > > 60.90% / 48.35% instead of 61.00% / 51.00% (client / server). > > I attached new version of the class (+ minor javdoc changes). > > Best regards, > Vladimir > > On Thu, Apr 29, 2010 at 12:18 PM, Goktug Gokdogan > wrote: > > One quick comment: you can consider moving trivial array check so it will > be > > executed only if insertion sort threshold check passes: > > > > if (length < INSERTION_SORT_THRESHOLD) { > > if (length < 2) { > > return; > > } > > .... > > > > On Mon, Apr 26, 2010 at 2:50 PM, Vladimir Iaroslavski > > wrote: > >> > >> Hello, everyone! > >> > >> I've investigated the implementation of the Dual-Pivot Quicksort > >> which is used for sorting primitives and here is my result: > >> > >> http://cr.openjdk.java.net/~alanb/6947216/webrev.00 > >> > >> New implementation of Dual-Pivot Quicksort is faster > >> than previous one of 12% for client VM and few percents for > >> server VM. Tests on Bentley's test suite (Win XP, JDK 7, > >> build 1.7.0-ea-b84, n = 1000000) show geometry mean 0.88 > >> for client VM and 0.98-1.00 for server VM. > >> > >> In compare with sorting from JDK 6 by Jon L. Bentley and > >> M. Douglas McIlroy's (with one pivot) the ratio is 0.61 / 0.50 > >> (client / server). > >> > >> See the execution time for sorting array of 2`000`000 int elements > >> 50 times, client / server VM, in milliseconds: > >> > >> random > >> new: 16723 18776 > >> jdk7: 17571 18975 > >> jdk6: 22241 26524 > >> > >> ascendant > >> new: 3541 4702 > >> jdk7: 4486 4669 > >> jdk6: 8667 7978 > >> > >> descendant > >> new: 3854 4907 > >> jdk7: 4942 5034 > >> jdk6: 8787 8243 > >> > >> equal > >> new: 234 281 > >> jdk7: 291 230 > >> jdk6: 602 1018 > >> > >> organ pipes > >> new: 7673 8613 > >> jdk7: 8167 8993 > >> jdk6: 11902 14044 > >> > >> stagger 1 > >> new: 7648 8591 > >> jdk7: 8161 8979 > >> jdk6: 11908 13810 > >> > >> stagger 2 > >> new: 8349 9299 > >> jdk7: 10968 11916 > >> jdk6: 12194 14734 > >> > >> stagger 4 > >> new: 8475 9622 > >> jdk7: 9221 9682 > >> jdk6: 10523 12006 > >> > >> stagger 8 > >> new: 9321 10689 > >> jdk7: 11125 12387 > >> jdk6: 13829 16214 > >> > >> period 1..2 > >> new: 758 751 > >> jdk7: 870 754 > >> jdk6: 1038 1227 > >> > >> period 1..4 > >> new: 1004 963 > >> jdk7: 1365 1209 > >> jdk6: 1511 1847 > >> > >> period 1..8 > >> new: 1588 1573 > >> jdk7: 1599 1790 > >> jdk6: 2602 3045 > >> > >> random 1..2 > >> new: 1327 1125 > >> jdk7: 1362 1496 > >> jdk6: 1531 2182 > >> > >> random 1..4 > >> new: 1830 2118 > >> jdk7: 1851 2236 > >> jdk6: 2292 3025 > >> > >> where stagger(m) is array like a[i] = i * (m + 1) % length. > >> > >> The summary of changes is: > >> > >> 1. For sorting small arrays is used insertion sort with sentinel > >> instead of traditional, which has the structure: > >> > >> for (int i = left + 1; i <= right; i++) { > >> for (j = i; j > left && a[j-1] > a[j]; j--) { > >> swap(a[i], a[j-1]); > >> } > >> } > >> > >> Note that range check j > left is performed on each iteration, > >> but really helps very rare. To avoid this expensive range check, > >> it was suggested to set minimum value (negative infinity) on the > >> first position. This type of suggestion is used in new version: > >> > >> if left bound > 0, we can put sentinel on a[left - 1], do insertion > >> sort without expensive check range, and then restore a[left - 1] > >> value. If left == 0, traditional insertion sort is used. Please, > >> look at the webrev for details. > >> > >> 2. In previous implementation 5 evenly spaced elements > >> > >> sixth = length / 6; > >> a[sixth], a[2 * sixth], a[3 * sixth], a[4 * sixth], a[5 * sixth] > >> > >> were used as candidates of pivots elements. This case is very > >> sensitive for period inputs, especially by 6. The new suggestion > >> is to take 5 center evenly spaced elements like this: > >> > >> int seventh = length / 7; > >> int midpoint = (left + right) >>> 1; > >> > >> a[midpoint - 2 * seventh], a[midpoint - seventh], a[midpoint], > >> a[midpoint + seventh], a[midpoint + 2 * seventh] > >> > >> and moreover, the seventh is calculated inexpensively: > >> seventh = (length >>> 3) + (length >>> 6) + 1; > >> > >> This schema works the same on random, ascendant, descendant, equal > >> inputs, but much better for period / stagger. > >> > >> 3. The whole structure > >> > >> > >> > >> if (pivotsDiffer) { > >> > >> } > >> else { > >> > >> } > >> > >> > >> > >> if (!pivotsDiffer) { > >> return; > >> } > >> > >> > >> > >> > >> was modified to: > >> ---------------- > >> > >> > >> > >> if (pivot1 < pivot2) { > >> > >> > >> > >> > >> > >> } > >> else { > >> > >> > >> } > >> > >> 4. Partitioning for both cases have not been changed at all. > >> > >> 5. Minor javadoc and format changes. > >> > >> Please, review new implementation, > >> any comments / suggestions are welcome! > >> > >> Thank you, > >> Vladimir > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dmytro_sheyko at hotmail.com Wed May 5 12:01:55 2010 From: dmytro_sheyko at hotmail.com (Dmytro Sheyko) Date: Wed, 5 May 2010 19:01:55 +0700 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: Message-ID: Hi Vladimir, The trick with sentinel is quite cute. Going farther, I think it is not always necessary to replace left outer element with the least possible value (and restore it later after sorting) because after partitioning every element in adjoining array part can play the role of sentinel. The only exception is when the user requested to sort array partially (not from the beginning). Thereby we should care about setting sentinel explicitly in this exceptional case only and only once before sorting whole array. Also it seems to me that it is not necessary to put pivot candidates (5 elements that are used to choose pivots) back to array because anyway they are to be sorted later and likely change their positions. I am also interesting in theoretical rationale why dual pivot quicksort is better than single pivot one. The last document that I have seen (Last updated: September 22, 2009) compared classic quicksort (where pivot is chosen arbitrarily) with "classic" dual pivot quicksort (where pivots are also chosen arbitrarily). As conclusion they both perform about 2*n*ln(n) key comparisons. However jdk had improved quicksort: median-of-three and pseudomedian-of-nine approaches were used. And median-of-three approach lead to 12/7*n*ln(n) key comparisons. On the other hand, dual pivot quicksort is also improved: pivots are chosen from 5 candidates, and hence it must perform less than 2*n*ln(n) key comparisons. Regards, Dmytro Sheyko > Date: Tue, 27 Apr 2010 01:50:08 +0400 > Subject: New portion of improvements for Dual-Pivot Quicksort > From: vladimir.iaroslavski at googlemail.com > To: core-libs-dev at openjdk.java.net > > Hello, everyone! > > I've investigated the implementation of the Dual-Pivot Quicksort > which is used for sorting primitives and here is my result: > > http://cr.openjdk.java.net/~alanb/6947216/webrev.00 > > New implementation of Dual-Pivot Quicksort is faster > than previous one of 12% for client VM and few percents for > server VM. Tests on Bentley's test suite (Win XP, JDK 7, > build 1.7.0-ea-b84, n = 1000000) show geometry mean 0.88 > for client VM and 0.98-1.00 for server VM. > > In compare with sorting from JDK 6 by Jon L. Bentley and > M. Douglas McIlroy's (with one pivot) the ratio is 0.61 / 0.50 > (client / server). > > See the execution time for sorting array of 2`000`000 int elements > 50 times, client / server VM, in milliseconds: > > random > new: 16723 18776 > jdk7: 17571 18975 > jdk6: 22241 26524 > > ascendant > new: 3541 4702 > jdk7: 4486 4669 > jdk6: 8667 7978 > > descendant > new: 3854 4907 > jdk7: 4942 5034 > jdk6: 8787 8243 > > equal > new: 234 281 > jdk7: 291 230 > jdk6: 602 1018 > > organ pipes > new: 7673 8613 > jdk7: 8167 8993 > jdk6: 11902 14044 > > stagger 1 > new: 7648 8591 > jdk7: 8161 8979 > jdk6: 11908 13810 > > stagger 2 > new: 8349 9299 > jdk7: 10968 11916 > jdk6: 12194 14734 > > stagger 4 > new: 8475 9622 > jdk7: 9221 9682 > jdk6: 10523 12006 > > stagger 8 > new: 9321 10689 > jdk7: 11125 12387 > jdk6: 13829 16214 > > period 1..2 > new: 758 751 > jdk7: 870 754 > jdk6: 1038 1227 > > period 1..4 > new: 1004 963 > jdk7: 1365 1209 > jdk6: 1511 1847 > > period 1..8 > new: 1588 1573 > jdk7: 1599 1790 > jdk6: 2602 3045 > > random 1..2 > new: 1327 1125 > jdk7: 1362 1496 > jdk6: 1531 2182 > > random 1..4 > new: 1830 2118 > jdk7: 1851 2236 > jdk6: 2292 3025 > > where stagger(m) is array like a[i] = i * (m + 1) % length. > > The summary of changes is: > > 1. For sorting small arrays is used insertion sort with sentinel > instead of traditional, which has the structure: > > for (int i = left + 1; i <= right; i++) { > for (j = i; j > left && a[j-1] > a[j]; j--) { > swap(a[i], a[j-1]); > } > } > > Note that range check j > left is performed on each iteration, > but really helps very rare. To avoid this expensive range check, > it was suggested to set minimum value (negative infinity) on the > first position. This type of suggestion is used in new version: > > if left bound > 0, we can put sentinel on a[left - 1], do insertion > sort without expensive check range, and then restore a[left - 1] > value. If left == 0, traditional insertion sort is used. Please, > look at the webrev for details. > > 2. In previous implementation 5 evenly spaced elements > > sixth = length / 6; > a[sixth], a[2 * sixth], a[3 * sixth], a[4 * sixth], a[5 * sixth] > > were used as candidates of pivots elements. This case is very > sensitive for period inputs, especially by 6. The new suggestion > is to take 5 center evenly spaced elements like this: > > int seventh = length / 7; > int midpoint = (left + right) >>> 1; > > a[midpoint - 2 * seventh], a[midpoint - seventh], a[midpoint], > a[midpoint + seventh], a[midpoint + 2 * seventh] > > and moreover, the seventh is calculated inexpensively: > seventh = (length >>> 3) + (length >>> 6) + 1; > > This schema works the same on random, ascendant, descendant, equal > inputs, but much better for period / stagger. > > 3. The whole structure > > > > if (pivotsDiffer) { > > } > else { > > } > > > > if (!pivotsDiffer) { > return; > } > > > > > was modified to: > ---------------- > > > > if (pivot1 < pivot2) { > > > > > > } > else { > > > } > > 4. Partitioning for both cases have not been changed at all. > > 5. Minor javadoc and format changes. > > Please, review new implementation, > any comments / suggestions are welcome! > > Thank you, > Vladimir _________________________________________________________________ Hotmail: Trusted email with Microsoft?s powerful SPAM protection. https://signup.live.com/signup.aspx?id=60969 -------------- next part -------------- An HTML attachment was scrubbed... URL: From chris.hegarty at oracle.com Wed May 5 12:19:38 2010 From: chris.hegarty at oracle.com (chris.hegarty at oracle.com) Date: Wed, 05 May 2010 12:19:38 +0000 Subject: hg: jdk7/tl/jdk: 6886723: light weight http server doesn't return correct status code for HEAD requests Message-ID: <20100505121952.D78F94420F@hg.openjdk.java.net> Changeset: 5dfa4f0429d8 Author: chegar Date: 2010-05-05 13:18 +0100 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/5dfa4f0429d8 6886723: light weight http server doesn't return correct status code for HEAD requests Reviewed-by: michaelm ! src/share/classes/sun/net/httpserver/ExchangeImpl.java + test/com/sun/net/httpserver/bugs/HeadTest.java From iaroslavski at mail.ru Wed May 5 17:06:00 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Wed, 05 May 2010 21:06:00 +0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: Message-ID: <4BE1A578.6010708@mail.ru> Josh, Thank you very much for review. I'll prepare updated version and send it with my comments soon. Vladimir Joshua Bloch wrote: > Vladimir, > > Hi. I'm thrilled that you were able to eke so much more perforance out > of this already optimized code. I read your changes on my flight to > Pittsburgh. Here's the code review: > > I think the comment on lines 102-105 was too useful to delete: > > 102 ... This > 103 * method differs from the public {@code sort} method in that the > 104 * {@code right} index is inclusive, and it does no range checking > 105 * on {@code left} or {@code right}. > > The sentinel technique that you use in lines 118 - 136 is questionable: > you are modifying a portion of the array outside the specified range of > the call, which arguably violates the contract of the call, and could be > observed in a multithreaded program. It's not beyond the realm of reason > that it could break existing clients. I will discuss it with Doug Lea > and let you know what he says. > > If we leave this optimization in, we should change the comments > slightly. Appearing to comment-out code (other than entire assertions in > inner loops) is never a good thing, hence the change to line 130 and the > addition of the line that follows. Also I reworded the commennt in lines > 122-125 for clarity. Changed lines are starred, added line has a "+": > > 118 // Use insertion sort on tiny arrays > 119 if (length < INSERTION_SORT_THRESHOLD) { > 120 if (left > 0) { > 121 /* > *122 * Temporarily set the value immediately preceding > the range > *123 * to the minimum int value to serve as a sentinel. > This > *124 * allows us to avoid the j >= left check on each > iteration. > 125 */ > 126 int before = a[left - 1]; a[left - 1] = > Integer.MIN_VALUE; > 127 > 128 for (int j, i = left + 1; i <= right; i++) { > 129 int ai = a[i]; > *130 for (j = i - 1; ai < a[j]; j--) { > +NEW // assert j >= left; > 131 a[j + 1] = a[j]; > 132 } > 133 a[j + 1] = ai; > 134 } > 135 a[left - 1] = before; > 136 } else { > > The comment in line 155 is misleading, and should be replace by this: > > I'd reword the comment in lines 137-140 for clarity: > > 137 /* > 138 * For case, when left == 0, traditional (without a > sentinel) > 139 * insertion sort, optimized for server VM, is used. > 140 */ > > > 155 // Inexpensive approximation of length / 7 > > The comment strategy for choosing sample points is subtle enough that it > deserves bit more commentary. I propose replacing line 158 with this: > > /* > * Sort five evenly spaced elements around (and including) the center > * element in the range. These elements will be used for pivot selection > * as described below. The choice for spacing these elements was > empirically > * determined to work well on a wide variety of inputs. > */ > > Lines 183 and 184 are unnecessary array accesses. Probably better is: > > 183 int pivot1 = ae2; > 184 int pivot2 = ae4; > > This is essentially just a renaming of these two local variables, and > presumably the compiler will act accordingly. > > I prefer the original wording: > > 197 * Pointer k is the first index of ?-part > > to the revised wording: > > 217 * Pointer k is the first index of not inspected ?-part. > > I'd revert this change. > > I'd change 190 from: > > 190 if (pivot1 < pivot2) { > > to > > 190 if (pivot1 != pivot2) { > > It's clearer (this is the "pivots differ" case), and at least as fast. > > The spacing lines 249 and 250 is a bit quirky: > > 249 dualPivotQuicksort(a, left, less - 2); > 250 dualPivotQuicksort(a, great + 2, right); > > I'd replace it with the more standard: > > 249 dualPivotQuicksort(a, left, less - 2); > 250 dualPivotQuicksort(a, great + 2, right); > > Alternatively, you could make corresponding arguments line up: > > 249 dualPivotQuicksort(a, left, less - 2); > 250 dualPivotQuicksort(a, great + 2, right ); > > The policy change in line 256 is non-trivial: > > Old: > > 298 if (less < e1 && great > e5) { > > New: > > 256 if (great - less > 5 * seventh) { > > I previously experimented with the "new-style" policy (length-based, > rather than endpoint-based), but didn't get good results. Perhaps the > symmetric style combines well with the change in interval size (5/7 vs. > 2/3). At any rate, it's simpler than the old-style and conforms to the > comment, so if you're satisfied with the performance, I'm happy with it. > > In lines 362 and 363, you have the same "quirky spacing" as in linkes > 249 and 250: > > 361 // Sort left and right parts recursively > 362 dualPivotQuicksort(a, left, less - 1); > 363 dualPivotQuicksort(a, great + 1, right); > > Regards, > > Josh From iaroslavski at mail.ru Wed May 5 17:23:37 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Wed, 05 May 2010 21:23:37 +0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: Message-ID: <4BE1A999.5050700@mail.ru> Hi Dmytro, Thank you very much for suggestions! I checked it and here is my results: If we consider case when the whole array is sorted, we can omit setting sentinel and restoring original value: // int before = a[left - 1]; a[left - 1] = Integer.MIN_VALUE; for (int j, i = left + 1; i <= right; i++) { int ai = a[i]; for (j = i - 1; /* j >= left && */ ai < a[j]; j--) { a[j + 1] = a[j]; } a[j + 1] = ai; } // a[left - 1] = before; I checked this version and found that it works little bit faster (only 0.4-0.3%) with client VM, but loses more than 2.5% under server mode in compare with one-pivot version from JDK 6: client server original: 60.75% 48.20% no setting sentinel: 60.40% 50.88% If we add additional check which case is sorted, I think, we don't win at all. And if pivot candidates are not put back to array, it shows very poor results: client server original: 60.75% 48.20% no back candidates: 66.80% 53.95% I run one pivot version taken from JDK 6: I replace in Dual-Pivot implementation with all optimizations dual-pivot partitioning by one-pivot: but it remain still slower than DPQ. So, the main point of DPQ is not only in optimizations, but in dividing array into 3 parts instead of two. Thank you, Vladimir Dmytro Sheyko wrote: > Hi Vladimir, > > The trick with sentinel is quite cute. Going farther, I think it is not > always necessary to replace left outer element with the least possible value > (and restore it later after sorting) because after partitioning every > element in adjoining array part can play the role of sentinel. > The only exception is when the user requested to sort array partially > (not from the beginning). Thereby we should care about setting sentinel > explicitly in this exceptional case only and only once before sorting whole array. > > Also it seems to me that it is not necessary to put pivot candidates (5 > elements that are used to choose pivots) back to array > because anyway they are to be sorted later and likely change their > positions. > > I am also interesting in theoretical rationale why dual pivot quicksort > is better than single pivot one. The last document that I have seen > (Last updated: September 22, 2009) > compared classic quicksort (where pivot is chosen arbitrarily) with > "classic" dual pivot quicksort (where pivots are also chosen arbitrarily). > As conclusion they both perform about 2*n*ln(n) key comparisons. However > jdk had improved quicksort: median-of-three and pseudomedian-of-nine > approaches were used. And median-of-three approach lead to 12/7*n*ln(n) > key comparisons. On the other hand, dual pivot quicksort is also improved: > pivots are chosen from 5 candidates, and hence it must perform less than > 2*n*ln(n) key comparisons. > > Regards, > Dmytro Sheyko > > > Date: Tue, 27 Apr 2010 01:50:08 +0400 > > Subject: New portion of improvements for Dual-Pivot Quicksort > > From: vladimir.iaroslavski at googlemail.com > > To: core-libs-dev at openjdk.java.net > > > > Hello, everyone! > > > > I've investigated the implementation of the Dual-Pivot Quicksort > > which is used for sorting primitives and here is my result: > > > > http://cr.openjdk.java.net/~alanb/6947216/webrev.00 > > > > New implementation of Dual-Pivot Quicksort is faster > > than previous one of 12% for client VM and few percents for > > server VM. Tests on Bentley's test suite (Win XP, JDK 7, > > build 1.7.0-ea-b84, n = 1000000) show geometry mean 0.88 > > for client VM and 0.98-1.00 for server VM. > > > > In compare with sorting from JDK 6 by Jon L. Bentley and > > M. Douglas McIlroy's (with one pivot) the ratio is 0.61 / 0.50 > > (client / server). > > > > See the execution time for sorting array of 2`000`000 int elements > > 50 times, client / server VM, in milliseconds: > > > > random > > new: 16723 18776 > > jdk7: 17571 18975 > > jdk6: 22241 26524 > > > > ascendant > > new: 3541 4702 > > jdk7: 4486 4669 > > jdk6: 8667 7978 > > > > descendant > > new: 3854 4907 > > jdk7: 4942 5034 > > jdk6: 8787 8243 > > > > equal > > new: 234 281 > > jdk7: 291 230 > > jdk6: 602 1018 > > > > organ pipes > > new: 7673 8613 > > jdk7: 8167 8993 > > jdk6: 11902 14044 > > > > stagger 1 > > new: 7648 8591 > > jdk7: 8161 8979 > > jdk6: 11908 13810 > > > > stagger 2 > > new: 8349 9299 > > jdk7: 10968 11916 > > jdk6: 12194 14734 > > > > stagger 4 > > new: 8475 9622 > > jdk7: 9221 9682 > > jdk6: 10523 12006 > > > > stagger 8 > > new: 9321 10689 > > jdk7: 11125 12387 > > jdk6: 13829 16214 > > > > period 1..2 > > new: 758 751 > > jdk7: 870 754 > > jdk6: 1038 1227 > > > > period 1..4 > > new: 1004 963 > > jdk7: 1365 1209 > > jdk6: 1511 1847 > > > > period 1..8 > > new: 1588 1573 > > jdk7: 1599 1790 > > jdk6: 2602 3045 > > > > random 1..2 > > new: 1327 1125 > > jdk7: 1362 1496 > > jdk6: 1531 2182 > > > > random 1..4 > > new: 1830 2118 > > jdk7: 1851 2236 > > jdk6: 2292 3025 > > > > where stagger(m) is array like a[i] = i * (m + 1) % length. > > > > The summary of changes is: > > > > 1. For sorting small arrays is used insertion sort with sentinel > > instead of traditional, which has the structure: > > > > for (int i = left + 1; i <= right; i++) { > > for (j = i; j > left && a[j-1] > a[j]; j--) { > > swap(a[i], a[j-1]); > > } > > } > > > > Note that range check j > left is performed on each iteration, > > but really helps very rare. To avoid this expensive range check, > > it was suggested to set minimum value (negative infinity) on the > > first position. This type of suggestion is used in new version: > > > > if left bound > 0, we can put sentinel on a[left - 1], do insertion > > sort without expensive check range, and then restore a[left - 1] > > value. If left == 0, traditional insertion sort is used. Please, > > look at the webrev for details. > > > > 2. In previous implementation 5 evenly spaced elements > > > > sixth = length / 6; > > a[sixth], a[2 * sixth], a[3 * sixth], a[4 * sixth], a[5 * sixth] > > > > were used as candidates of pivots elements. This case is very > > sensitive for period inputs, especially by 6. The new suggestion > > is to take 5 center evenly spaced elements like this: > > > > int seventh = length / 7; > > int midpoint = (left + right) >>> 1; > > > > a[midpoint - 2 * seventh], a[midpoint - seventh], a[midpoint], > > a[midpoint + seventh], a[midpoint + 2 * seventh] > > > > and moreover, the seventh is calculated inexpensively: > > seventh = (length >>> 3) + (length >>> 6) + 1; > > > > This schema works the same on random, ascendant, descendant, equal > > inputs, but much better for period / stagger. > > > > 3. The whole structure > > > > > > > > if (pivotsDiffer) { > > > > } > > else { > > > > } > > > > > > > > if (!pivotsDiffer) { > > return; > > } > > > > > > > > > > was modified to: > > ---------------- > > > > > > > > if (pivot1 < pivot2) { > > > > > > > > > > > > } > > else { > > > > > > } > > > > 4. Partitioning for both cases have not been changed at all. > > > > 5. Minor javadoc and format changes. > > > > Please, review new implementation, > > any comments / suggestions are welcome! > > > > Thank you, > > Vladimir From iaroslavski at mail.ru Wed May 5 19:03:22 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Wed, 05 May 2010 23:03:22 +0400 Subject: =?koi8-r?Q?Re[2]=3A_New_portion_of_improvements_for_Dual-Pivot_Quicksort?= In-Reply-To: References: Message-ID: Josh, Quick note on changing int pivot1 = a[e2[; int pivot2 = a[e4]; by int pivot1 = ae2; int pivot2 = ae4; It is extremely surprised, but version with local variables eats 5% (!) of time for client and 2% for server mode (in compare with one-pivot implementation from JDK 6), see: client server with a[e2], a[e4]: 60.75% 48.20% with ae2, ae4: 65.80% 50.42% I don't have idea why this simple change is so expensive. Does anybody can explain it? Vladimir Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua Bloch : > > Vladimir, > > Hi. I'm thrilled that you were able to eke so much more perforance out of this already optimized code. I read your changes on my flight to Pittsburgh. Here's the code review: > > I think the comment on lines 102-105 was too useful to delete: > > 102 ... This > 103 * method differs from the public {@code sort} method in that the > 104 * {@code right} index is inclusive, and it does no range checking > 105 * on {@code left} or {@code right}. > > The sentinel technique that you use in lines 118 - 136 is questionable: you are modifying a portion of the array outside the specified range of the call, which arguably violates the contract of the call, and could be observed in a multithreaded program. It's not beyond the realm of reason that it could break existing clients. I will discuss it with Doug Lea and let you know what he says. > > If we leave this optimization in, we should change the comments slightly. Appearing to comment-out code (other than entire assertions in inner loops) is never a good thing, hence the change to line 130 and the addition of the line that follows. Also I reworded the commennt in lines 122-125 for clarity. Changed lines are starred, added line has a "+": > > 118 // Use insertion sort on tiny arrays > 119 if (length < INSERTION_SORT_THRESHOLD) { > 120 if (left > 0) { > 121 /* > *122 * Temporarily set the value immediately preceding the range > *123 * to the minimum int value to serve as a sentinel. This > *124 * allows us to avoid the j >= left check on each iteration. > 125 */ > 126 int before = a[left - 1]; a[left - 1] = Integer.MIN_VALUE; > 127 > 128 for (int j, i = left + 1; i <= right; i++) { > 129 int ai = a[i]; > *130 for (j = i - 1; ai < a[j]; j--) { > +NEW // assert j >= left; > 131 a[j + 1] = a[j]; > 132 } > 133 a[j + 1] = ai; > 134 } > 135 a[left - 1] = before; > 136 } else { > > The comment in line 155 is misleading, and should be replace by this: > > I'd reword the comment in lines 137-140 for clarity: > > 137 /* > 138 * For case, when left == 0, traditional (without a sentinel) > 139 * insertion sort, optimized for server VM, is used. > 140 */ > > 155 // Inexpensive approximation of length / 7 > > The comment strategy for choosing sample points is subtle enough that it deserves bit more commentary. I propose replacing line 158 with this: > > /* > * Sort five evenly spaced elements around (and including) the center > * element in the range. These elements will be used for pivot selection > * as described below. The choice for spacing these elements was empirically > * determined to work well on a wide variety of inputs. > */ > > Lines 183 and 184 are unnecessary array accesses. Probably better is: > > 183 int pivot1 = ae2; > 184 int pivot2 = ae4; > > This is essentially just a renaming of these two local variables, and presumably the compiler will act accordingly. > > I prefer the original wording: > > 197 * Pointer k is the first index of -part > > to the revised wording: > > 217 * Pointer k is the first index of not inspected -part. > > I'd revert this change. > > I'd change 190 from: > > 190 if (pivot1 < pivot2) { > to > 190 if (pivot1 != pivot2) { > > It's clearer (this is the "pivots differ" case), and at least as fast. > > The spacing lines 249 and 250 is a bit quirky: > > 249 dualPivotQuicksort(a, left, less - 2); > 250 dualPivotQuicksort(a, great + 2, right); > > I'd replace it with the more standard: > > 249 dualPivotQuicksort(a, left, less - 2); > 250 dualPivotQuicksort(a, great + 2, right); > > Alternatively, you could make corresponding arguments line up: > > 249 dualPivotQuicksort(a, left, less - 2); > 250 dualPivotQuicksort(a, great + 2, right ); > > The policy change in line 256 is non-trivial: > > Old: > > 298 if (less < e1 && great > e5) { > > New: > > 256 if (great - less > 5 * seventh) { > > I previously experimented with the "new-style" policy (length-based, rather than endpoint-based), but didn't get good results. Perhaps the symmetric style combines well with the change in interval size (5/7 vs. 2/3). At any rate, it's simpler than the old-style and conforms to the comment, so if you're satisfied with the performance, I'm happy with it. > > In lines 362 and 363, you have the same "quirky spacing" as in linkes 249 and 250: > > 361 // Sort left and right parts recursively > 362 dualPivotQuicksort(a, left, less - 1); > 363 dualPivotQuicksort(a, great + 1, right); > > Regards, > Josh From jjb at google.com Wed May 5 22:05:34 2010 From: jjb at google.com (Joshua Bloch) Date: Wed, 5 May 2010 18:05:34 -0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: Message-ID: Vladimir, Fascinating. I don't know why this should be so. Joch On Wed, May 5, 2010 at 3:03 PM, Vladimir Iaroslavski wrote: > Josh, > > Quick note on changing > > int pivot1 = a[e2[; > int pivot2 = a[e4]; > > by > > int pivot1 = ae2; > int pivot2 = ae4; > > It is extremely surprised, but version with local variables eats > 5% (!) of time for client and 2% for server mode (in compare > with one-pivot implementation from JDK 6), see: > > client server > with a[e2], a[e4]: 60.75% 48.20% > with ae2, ae4: 65.80% 50.42% > > I don't have idea why this simple change is so expensive. > Does anybody can explain it? > > Vladimir > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua Bloch : > > > > Vladimir, > > > > Hi. I'm thrilled that you were able to eke so much more perforance out of > this already optimized code. I read your changes on my flight to Pittsburgh. > Here's the code review: > > > > I think the comment on lines 102-105 was too useful to delete: > > > > 102 ... This > > 103 * method differs from the public {@code sort} method in that the > > 104 * {@code right} index is inclusive, and it does no range checking > > 105 * on {@code left} or {@code right}. > > > > The sentinel technique that you use in lines 118 - 136 is questionable: > you are modifying a portion of the array outside the specified range of the > call, which arguably violates the contract of the call, and could be > observed in a multithreaded program. It's not beyond the realm of reason > that it could break existing clients. I will discuss it with Doug Lea and > let you know what he says. > > > > If we leave this optimization in, we should change the comments slightly. > Appearing to comment-out code (other than entire assertions in inner loops) > is never a good thing, hence the change to line 130 and the addition of the > line that follows. Also I reworded the commennt in lines 122-125 for > clarity. Changed lines are starred, added line has a "+": > > > > 118 // Use insertion sort on tiny arrays > > 119 if (length < INSERTION_SORT_THRESHOLD) { > > 120 if (left > 0) { > > 121 /* > > *122 * Temporarily set the value immediately preceding the range > > *123 * to the minimum int value to serve as a sentinel. This > > *124 * allows us to avoid the j >= left check on each iteration. > > 125 */ > > 126 int before = a[left - 1]; a[left - 1] = Integer.MIN_VALUE; > > 127 > > 128 for (int j, i = left + 1; i <= right; i++) { > > 129 int ai = a[i]; > > *130 for (j = i - 1; ai < a[j]; j--) { > > +NEW // assert j >= left; > > 131 a[j + 1] = a[j]; > > 132 } > > 133 a[j + 1] = ai; > > 134 } > > 135 a[left - 1] = before; > > 136 } else { > > > > The comment in line 155 is misleading, and should be replace by this: > > > > I'd reword the comment in lines 137-140 for clarity: > > > > 137 /* > > 138 * For case, when left == 0, traditional (without a sentinel) > > 139 * insertion sort, optimized for server VM, is used. > > 140 */ > > > > 155 // Inexpensive approximation of length / 7 > > > > The comment strategy for choosing sample points is subtle enough that it > deserves bit more commentary. I propose replacing line 158 with this: > > > > /* > > * Sort five evenly spaced elements around (and including) the center > > * element in the range. These elements will be used for pivot selection > > * as described below. The choice for spacing these elements was > empirically > > * determined to work well on a wide variety of inputs. > > */ > > > > Lines 183 and 184 are unnecessary array accesses. Probably better is: > > > > 183 int pivot1 = ae2; > > 184 int pivot2 = ae4; > > > > This is essentially just a renaming of these two local variables, and > presumably the compiler will act accordingly. > > > > I prefer the original wording: > > > > 197 * Pointer k is the first index of -part > > > > to the revised wording: > > > > 217 * Pointer k is the first index of not inspected -part. > > > > I'd revert this change. > > > > I'd change 190 from: > > > > 190 if (pivot1 < pivot2) { > > to > > 190 if (pivot1 != pivot2) { > > > > It's clearer (this is the "pivots differ" case), and at least as fast. > > > > The spacing lines 249 and 250 is a bit quirky: > > > > 249 dualPivotQuicksort(a, left, less - 2); > > 250 dualPivotQuicksort(a, great + 2, right); > > > > I'd replace it with the more standard: > > > > 249 dualPivotQuicksort(a, left, less - 2); > > 250 dualPivotQuicksort(a, great + 2, right); > > > > Alternatively, you could make corresponding arguments line up: > > > > 249 dualPivotQuicksort(a, left, less - 2); > > 250 dualPivotQuicksort(a, great + 2, right ); > > > > The policy change in line 256 is non-trivial: > > > > Old: > > > > 298 if (less < e1 && great > e5) { > > > > New: > > > > 256 if (great - less > 5 * seventh) { > > > > I previously experimented with the "new-style" policy (length-based, > rather than endpoint-based), but didn't get good results. Perhaps the > symmetric style combines well with the change in interval size (5/7 vs. > 2/3). At any rate, it's simpler than the old-style and conforms to the > comment, so if you're satisfied with the performance, I'm happy with it. > > > > In lines 362 and 363, you have the same "quirky spacing" as in linkes 249 > and 250: > > > > 361 // Sort left and right parts recursively > > 362 dualPivotQuicksort(a, left, less - 1); > > 363 dualPivotQuicksort(a, great + 1, right); > > > > Regards, > > Josh > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jjb at google.com Wed May 5 22:21:18 2010 From: jjb at google.com (Joshua Bloch) Date: Wed, 5 May 2010 18:21:18 -0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: Message-ID: Vladimir, On Wed, May 5, 2010 at 12:57 AM, Joshua Bloch wrote: > > The sentinel technique that you use in lines 118 - 136 is questionable: you > are modifying a portion of the array outside the specified range of the > call, which arguably violates the contract of the call, and could be > observed in a multithreaded program. It's not beyond the realm of reason > that it could break existing clients. I will discuss it with Doug Lea and > let you know what he says. > I talked to Doug, and he agrees that it's not acceptable to modify any location outside the array range that the caller has asked you to sort. This doesn't entirely kill the optimization; it's still OK to use on subranges that don't include the first element of the range that you were asked to sort. In other words, this test > > 120 if (left > 0) { Should be replaced by: 120 if (left > fromIndex + 1) { and you have to pass original fromIndex down to the recursive calls (in fact, you could pass fromIndex +1 to avoid the cost of the addition in each test). It's not clear whether the cost of passing this index down through the recursive calls will eliminate the gains of the optimization, but it's worth performing the experiment. Sorry, Josh -------------- next part -------------- An HTML attachment was scrubbed... URL: From weijun.wang at sun.com Thu May 6 03:27:40 2010 From: weijun.wang at sun.com (weijun.wang at sun.com) Date: Thu, 06 May 2010 03:27:40 +0000 Subject: hg: jdk7/tl/jdk: 6948909: Jarsigner removes MANIFEST.MF info for badly packages jar's Message-ID: <20100506032753.122CF443F3@hg.openjdk.java.net> Changeset: 3d51799b65a9 Author: weijun Date: 2010-05-06 11:26 +0800 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/3d51799b65a9 6948909: Jarsigner removes MANIFEST.MF info for badly packages jar's Reviewed-by: mullan, xuelei ! src/share/classes/sun/security/tools/JarSigner.java + test/sun/security/tools/jarsigner/diffend.sh From weijun.wang at sun.com Thu May 6 05:43:20 2010 From: weijun.wang at sun.com (weijun.wang at sun.com) Date: Thu, 06 May 2010 05:43:20 +0000 Subject: hg: jdk7/tl/jdk: 6890876: jarsigner can add CRL info into signed jar Message-ID: <20100506054333.555EE44444@hg.openjdk.java.net> Changeset: 8834c3633f0b Author: weijun Date: 2010-05-06 13:42 +0800 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/8834c3633f0b 6890876: jarsigner can add CRL info into signed jar Reviewed-by: mullan ! src/share/classes/com/sun/jarsigner/ContentSignerParameters.java ! src/share/classes/java/security/CodeSigner.java ! src/share/classes/java/util/jar/JarVerifier.java + src/share/classes/sun/misc/JavaSecurityCodeSignerAccess.java ! src/share/classes/sun/misc/SharedSecrets.java ! src/share/classes/sun/security/pkcs/PKCS7.java ! src/share/classes/sun/security/tools/JarSigner.java ! src/share/classes/sun/security/tools/JarSignerResources.java ! src/share/classes/sun/security/tools/KeyTool.java ! src/share/classes/sun/security/tools/TimestampedSigner.java ! src/share/classes/sun/security/util/Resources.java ! src/share/classes/sun/security/util/SignatureFileVerifier.java ! src/share/classes/sun/security/x509/X509CRLImpl.java + test/sun/security/tools/jarsigner/crl.sh From dmytro_sheyko at hotmail.com Thu May 6 08:07:07 2010 From: dmytro_sheyko at hotmail.com (Dmytro Sheyko) Date: Thu, 6 May 2010 15:07:07 +0700 Subject: New portion of improvements for Dual-Pivot Quicksort Message-ID: Hello Vladimir, Could you also share performance test suite you used? Unit tests do not fit well to measure performance. You got unbelievable results after applying recent changes (proposed by Joshua Bloch and me), so I would like to reproduce these results as well. Thank you, Dmytro Sheyko > Date: Fri, 30 Apr 2010 17:11:10 +0400 > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > From: vladimir.iaroslavski at googlemail.com > To: dmytro_sheyko at hotmail.com > CC: core-libs-dev at openjdk.java.net > > Hello Dmytro, > > Please, see file test/java/util/Arrays/Sorting.java in the > JDK repository, It contains unit tests. > > Thank you, > Vladimir > > 2010/4/30 Dmytro Sheyko : > > Hello Vladimir, > > > > Could you remind me where can I find sources for the test suite? > > > > Thanks, > > Dmytro _________________________________________________________________ Hotmail: Trusted email with powerful SPAM protection. https://signup.live.com/signup.aspx?id=60969 -------------- next part -------------- An HTML attachment was scrubbed... URL: From iaroslavski at mail.ru Thu May 6 08:41:11 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Thu, 06 May 2010 12:41:11 +0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: Message-ID: <4BE280A7.5050301@mail.ru> Hello Dmytro, Sure, I'll share benchmark test suites, please, see attachment. There are 2 suites: Bentley's and mine. First suite runs test on many data inputs with several parameters. In my suite I run only on random, sorted, equal, stagger, period. In config file s.bat you should change JDK location. Note that I run on JDK *7*, build 1.7.0-ea-b84. It will be very interesting to see results on your machine. Thank you, Vladimir Dmytro Sheyko wrote: > Hello Vladimir, > > Could you also share performance test suite you used? Unit tests do not > fit well to measure performance. > You got unbelievable results after applying recent changes (proposed by > Joshua Bloch and me), so I would like to reproduce these results as well. > > Thank you, > Dmytro Sheyko > > > Date: Fri, 30 Apr 2010 17:11:10 +0400 > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > From: vladimir.iaroslavski at googlemail.com > > To: dmytro_sheyko at hotmail.com > > CC: core-libs-dev at openjdk.java.net > > > > Hello Dmytro, > > > > Please, see file test/java/util/Arrays/Sorting.java in the > > JDK repository, It contains unit tests. > > > > Thank you, > > Vladimir > > > > 2010/4/30 Dmytro Sheyko : > > > Hello Vladimir, > > > > > > Could you remind me where can I find sources for the test suite? > > > > > > Thanks, > > > Dmytro -------------- next part -------------- A non-text attachment was scrubbed... Name: benchmark.zip Type: application/zip Size: 49634 bytes Desc: not available URL: From dmytro_sheyko at hotmail.com Thu May 6 08:43:52 2010 From: dmytro_sheyko at hotmail.com (Dmytro Sheyko) Date: Thu, 6 May 2010 15:43:52 +0700 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: <4BE1A999.5050700@mail.ru> References: , , <4BE1A999.5050700@mail.ru> Message-ID: Vladimir, > If we consider case when the whole array is sorted, > we can omit setting sentinel and restoring original value: Let me define my point more precisely. We can omit setting sentinel not only in a particular case when the whole array is sorted. During partitioning the whole array is split into small chunks. Elements within a chunks remains unsorted, but every element in a certain chunk is greater than every element in preceding (lefter) chunks and less than every element in following (righter) chunks. E.g. [...A...B...]C[...D...E...]F[...G...H...] Elements C and F are pivots. Elements D and E are greater that pivot C and hence greater than A and B, and less than pivot F and hence G and H. Therefore during sorting any non-leftmost chunk we can rely on preceding chunk. Did I miss something? Is this what you mean? Thank you, Dmytro Sheyko > Date: Wed, 5 May 2010 21:23:37 +0400 > From: iaroslavski at mail.ru > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > To: dmytro_sheyko at hotmail.com > CC: core-libs-dev at openjdk.java.net > > Hi Dmytro, > > Thank you very much for suggestions! I checked it and here > is my results: > > If we consider case when the whole array is sorted, > we can omit setting sentinel and restoring original value: > > // int before = a[left - 1]; a[left - 1] = Integer.MIN_VALUE; > > for (int j, i = left + 1; i <= right; i++) { > int ai = a[i]; > for (j = i - 1; /* j >= left && */ ai < a[j]; j--) { > a[j + 1] = a[j]; > } > a[j + 1] = ai; > } > // a[left - 1] = before; > > I checked this version and found that it works little bit faster > (only 0.4-0.3%) with client VM, but loses more than 2.5% under > server mode in compare with one-pivot version from JDK 6: > > client server > original: 60.75% 48.20% > no setting sentinel: 60.40% 50.88% > > If we add additional check which case is sorted, I think, we > don't win at all. > > And if pivot candidates are not put back to array, it shows > very poor results: > > client server > original: 60.75% 48.20% > no back candidates: 66.80% 53.95% > > I run one pivot version taken from JDK 6: I replace in Dual-Pivot > implementation with all optimizations dual-pivot partitioning by one-pivot: > but it remain still slower than DPQ. So, the main point of DPQ is not only > in optimizations, but in dividing array into 3 parts instead of two. > > Thank you, > Vladimir > > Dmytro Sheyko wrote: > > Hi Vladimir, > > > > The trick with sentinel is quite cute. Going farther, I think it is not > > always necessary to replace left outer element with the least possible value > > (and restore it later after sorting) because after partitioning every > > element in adjoining array part can play the role of sentinel. > > The only exception is when the user requested to sort array partially > > (not from the beginning). Thereby we should care about setting sentinel > > explicitly in this exceptional case only and only once before sorting whole array. > > > > Also it seems to me that it is not necessary to put pivot candidates (5 > > elements that are used to choose pivots) back to array > > because anyway they are to be sorted later and likely change their > > positions. > > > > I am also interesting in theoretical rationale why dual pivot quicksort > > is better than single pivot one. The last document that I have seen > > (Last updated: September 22, 2009) > > compared classic quicksort (where pivot is chosen arbitrarily) with > > "classic" dual pivot quicksort (where pivots are also chosen arbitrarily). > > As conclusion they both perform about 2*n*ln(n) key comparisons. However > > jdk had improved quicksort: median-of-three and pseudomedian-of-nine > > approaches were used. And median-of-three approach lead to 12/7*n*ln(n) > > key comparisons. On the other hand, dual pivot quicksort is also improved: > > pivots are chosen from 5 candidates, and hence it must perform less than > > 2*n*ln(n) key comparisons. > > > > Regards, > > Dmytro Sheyko > > > > > Date: Tue, 27 Apr 2010 01:50:08 +0400 > > > Subject: New portion of improvements for Dual-Pivot Quicksort > > > From: vladimir.iaroslavski at googlemail.com > > > To: core-libs-dev at openjdk.java.net > > > > > > Hello, everyone! > > > > > > I've investigated the implementation of the Dual-Pivot Quicksort > > > which is used for sorting primitives and here is my result: > > > > > > http://cr.openjdk.java.net/~alanb/6947216/webrev.00 > > > > > > New implementation of Dual-Pivot Quicksort is faster > > > than previous one of 12% for client VM and few percents for > > > server VM. Tests on Bentley's test suite (Win XP, JDK 7, > > > build 1.7.0-ea-b84, n = 1000000) show geometry mean 0.88 > > > for client VM and 0.98-1.00 for server VM. > > > > > > In compare with sorting from JDK 6 by Jon L. Bentley and > > > M. Douglas McIlroy's (with one pivot) the ratio is 0.61 / 0.50 > > > (client / server). > > > > > > See the execution time for sorting array of 2`000`000 int elements > > > 50 times, client / server VM, in milliseconds: > > > > > > random > > > new: 16723 18776 > > > jdk7: 17571 18975 > > > jdk6: 22241 26524 > > > > > > ascendant > > > new: 3541 4702 > > > jdk7: 4486 4669 > > > jdk6: 8667 7978 > > > > > > descendant > > > new: 3854 4907 > > > jdk7: 4942 5034 > > > jdk6: 8787 8243 > > > > > > equal > > > new: 234 281 > > > jdk7: 291 230 > > > jdk6: 602 1018 > > > > > > organ pipes > > > new: 7673 8613 > > > jdk7: 8167 8993 > > > jdk6: 11902 14044 > > > > > > stagger 1 > > > new: 7648 8591 > > > jdk7: 8161 8979 > > > jdk6: 11908 13810 > > > > > > stagger 2 > > > new: 8349 9299 > > > jdk7: 10968 11916 > > > jdk6: 12194 14734 > > > > > > stagger 4 > > > new: 8475 9622 > > > jdk7: 9221 9682 > > > jdk6: 10523 12006 > > > > > > stagger 8 > > > new: 9321 10689 > > > jdk7: 11125 12387 > > > jdk6: 13829 16214 > > > > > > period 1..2 > > > new: 758 751 > > > jdk7: 870 754 > > > jdk6: 1038 1227 > > > > > > period 1..4 > > > new: 1004 963 > > > jdk7: 1365 1209 > > > jdk6: 1511 1847 > > > > > > period 1..8 > > > new: 1588 1573 > > > jdk7: 1599 1790 > > > jdk6: 2602 3045 > > > > > > random 1..2 > > > new: 1327 1125 > > > jdk7: 1362 1496 > > > jdk6: 1531 2182 > > > > > > random 1..4 > > > new: 1830 2118 > > > jdk7: 1851 2236 > > > jdk6: 2292 3025 > > > > > > where stagger(m) is array like a[i] = i * (m + 1) % length. > > > > > > The summary of changes is: > > > > > > 1. For sorting small arrays is used insertion sort with sentinel > > > instead of traditional, which has the structure: > > > > > > for (int i = left + 1; i <= right; i++) { > > > for (j = i; j > left && a[j-1] > a[j]; j--) { > > > swap(a[i], a[j-1]); > > > } > > > } > > > > > > Note that range check j > left is performed on each iteration, > > > but really helps very rare. To avoid this expensive range check, > > > it was suggested to set minimum value (negative infinity) on the > > > first position. This type of suggestion is used in new version: > > > > > > if left bound > 0, we can put sentinel on a[left - 1], do insertion > > > sort without expensive check range, and then restore a[left - 1] > > > value. If left == 0, traditional insertion sort is used. Please, > > > look at the webrev for details. > > > > > > 2. In previous implementation 5 evenly spaced elements > > > > > > sixth = length / 6; > > > a[sixth], a[2 * sixth], a[3 * sixth], a[4 * sixth], a[5 * sixth] > > > > > > were used as candidates of pivots elements. This case is very > > > sensitive for period inputs, especially by 6. The new suggestion > > > is to take 5 center evenly spaced elements like this: > > > > > > int seventh = length / 7; > > > int midpoint = (left + right) >>> 1; > > > > > > a[midpoint - 2 * seventh], a[midpoint - seventh], a[midpoint], > > > a[midpoint + seventh], a[midpoint + 2 * seventh] > > > > > > and moreover, the seventh is calculated inexpensively: > > > seventh = (length >>> 3) + (length >>> 6) + 1; > > > > > > This schema works the same on random, ascendant, descendant, equal > > > inputs, but much better for period / stagger. > > > > > > 3. The whole structure > > > > > > > > > > > > if (pivotsDiffer) { > > > > > > } > > > else { > > > > > > } > > > > > > > > > > > > if (!pivotsDiffer) { > > > return; > > > } > > > > > > > > > > > > > > > was modified to: > > > ---------------- > > > > > > > > > > > > if (pivot1 < pivot2) { > > > > > > > > > > > > > > > > > > } > > > else { > > > > > > > > > } > > > > > > 4. Partitioning for both cases have not been changed at all. > > > > > > 5. Minor javadoc and format changes. > > > > > > Please, review new implementation, > > > any comments / suggestions are welcome! > > > > > > Thank you, > > > Vladimir _________________________________________________________________ Hotmail: Powerful Free email with security by Microsoft. https://signup.live.com/signup.aspx?id=60969 -------------- next part -------------- An HTML attachment was scrubbed... URL: From iaroslavski at mail.ru Thu May 6 08:59:18 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Thu, 06 May 2010 12:59:18 +0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: <4BE1A999.5050700@mail.ru> Message-ID: <4BE284E6.8050001@mail.ru> Hello Dmytro, I got your idea, and now I'm trying to combine insertion sort with your suggestion (don't set a sentinel), to be under restriction that we cannot change anything outside of the range and to sort correctly if initially part of array only is to be sorted (not whole array), see: [ ? ] [ this range to be sorted ] [ ? ] If center part must be sorted only, left [ ? ] part cannot be sentinel. Therefore, we have to sort it by traditional insertion sort (or something else). Thank you, Vladimir Dmytro Sheyko wrote: > Vladimir, > > > If we consider case when the whole array is sorted, > > we can omit setting sentinel and restoring original value: > > Let me define my point more precisely. We can omit setting sentinel not > only in a particular case when the whole array is sorted. > > During partitioning the whole array is split into small chunks. Elements > within a chunks remains unsorted, > but every element in a certain chunk is greater than every element in > preceding (lefter) chunks > and less than every element in following (righter) chunks. > > E.g. > > [...A...B...]C[...D...E...]F[...G...H...] > > Elements C and F are pivots. > Elements D and E are greater that pivot C and hence greater than A and > B, and less than pivot F and hence G and H. > > Therefore during sorting any non-leftmost chunk we can rely on preceding > chunk. > > Did I miss something? Is this what you mean? > > Thank you, > Dmytro Sheyko > > > Date: Wed, 5 May 2010 21:23:37 +0400 > > From: iaroslavski at mail.ru > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > To: dmytro_sheyko at hotmail.com > > CC: core-libs-dev at openjdk.java.net > > > > Hi Dmytro, > > > > Thank you very much for suggestions! I checked it and here > > is my results: > > > > If we consider case when the whole array is sorted, > > we can omit setting sentinel and restoring original value: > > > > // int before = a[left - 1]; a[left - 1] = Integer.MIN_VALUE; > > > > for (int j, i = left + 1; i <= right; i++) { > > int ai = a[i]; > > for (j = i - 1; /* j >= left && */ ai < a[j]; j--) { > > a[j + 1] = a[j]; > > } > > a[j + 1] = ai; > > } > > // a[left - 1] = before; > > > > I checked this version and found that it works little bit faster > > (only 0.4-0.3%) with client VM, but loses more than 2.5% under > > server mode in compare with one-pivot version from JDK 6: > > > > client server > > original: 60.75% 48.20% > > no setting sentinel: 60.40% 50.88% > > > > If we add additional check which case is sorted, I think, we > > don't win at all. > > > > And if pivot candidates are not put back to array, it shows > > very poor results: > > > > client server > > original: 60.75% 48.20% > > no back candidates: 66.80% 53.95% > > > > I run one pivot version taken from JDK 6: I replace in Dual-Pivot > > implementation with all optimizations dual-pivot partitioning by > one-pivot: > > but it remain still slower than DPQ. So, the main point of DPQ is not > only > > in optimizations, but in dividing array into 3 parts instead of two. > > > > Thank you, > > Vladimir > > > > Dmytro Sheyko wrote: > > > Hi Vladimir, > > > > > > The trick with sentinel is quite cute. Going farther, I think it is > not > > > always necessary to replace left outer element with the least > possible value > > > (and restore it later after sorting) because after partitioning every > > > element in adjoining array part can play the role of sentinel. > > > The only exception is when the user requested to sort array partially > > > (not from the beginning). Thereby we should care about setting > sentinel > > > explicitly in this exceptional case only and only once before > sorting whole array. > > > > > > Also it seems to me that it is not necessary to put pivot > candidates (5 > > > elements that are used to choose pivots) back to array > > > because anyway they are to be sorted later and likely change their > > > positions. > > > > > > I am also interesting in theoretical rationale why dual pivot > quicksort > > > is better than single pivot one. The last document that I have seen > > > (Last updated: September 22, 2009) > > > compared classic quicksort (where pivot is chosen arbitrarily) with > > > "classic" dual pivot quicksort (where pivots are also chosen > arbitrarily). > > > As conclusion they both perform about 2*n*ln(n) key comparisons. > However > > > jdk had improved quicksort: median-of-three and pseudomedian-of-nine > > > approaches were used. And median-of-three approach lead to > 12/7*n*ln(n) > > > key comparisons. On the other hand, dual pivot quicksort is also > improved: > > > pivots are chosen from 5 candidates, and hence it must perform less > than > > > 2*n*ln(n) key comparisons. > > > > > > Regards, > > > Dmytro Sheyko From chris.hegarty at oracle.com Thu May 6 16:17:39 2010 From: chris.hegarty at oracle.com (chris.hegarty at oracle.com) Date: Thu, 06 May 2010 16:17:39 +0000 Subject: hg: jdk7/tl/jdk: 6946825: com.sun.net.httpserver.HttpServer; Memory Leak on Non HTTP conform open socket Message-ID: <20100506161752.498164459B@hg.openjdk.java.net> Changeset: 0bda20126372 Author: chegar Date: 2010-05-06 17:17 +0100 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/0bda20126372 6946825: com.sun.net.httpserver.HttpServer; Memory Leak on Non HTTP conform open socket Reviewed-by: michaelm ! src/share/classes/sun/net/httpserver/ServerImpl.java From iaroslavski at mail.ru Thu May 6 20:46:59 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Fri, 07 May 2010 00:46:59 +0400 Subject: =?koi8-r?Q?Re[2]=3A_New_portion_of_improvements_for_Dual-Pivot_Quicksort?= In-Reply-To: References: Message-ID: Hello Josh, Dmytro, I've modified the DQP and now it doesn't touch elements outside of the range and doesn't set a sentinel at all. Elements from the left part are used as a sentinel (as it was suggested by Dmytro) and index fromIndex is used as left boundary (suggestion from Josh). The index fromIndex is the initial left boundary and passed down through the recursions. No any tricks with changing outside of the range and negative infinity. The fragment of code is (full version see in attachment): * ... * @param fromIndex the first index of the original range to be sorted */ private static void dualPivotQuicksort(int[] a, int left, int right, int fromIndex) { int length = right - left + 1; // Use insertion sort on tiny arrays if (length < INSERTION_SORT_THRESHOLD) { if (left > fromIndex) { /* * TODO */ for (int j, i = left + 1; i <= right; i++) { int ai = a[i]; for (j = i - 1; /* j >= left && */ ai < a[j]; j--) { a[j + 1] = a[j]; } a[j + 1] = ai; } } else { /* * For case, when left == fromIndex, traditional (without * sentinel) insertion sort, optimized for server VM, is used. */ for (int i = fromIndex, j = i; i < right; j = ++i) { int ai = a[i + 1]; while (ai < a[j]) { a[j + 1] = a[j]; if (j-- == fromIndex) { break; } } a[j + 1] = ai; } } return; } ... This variant is little bit faster (~0.5%) on client VM and slower (~2%) on server VM than original variant. I think that it is not too bad. What do you think? And one question: the method declaration private static void dualPivotQuicksort(int[] a, int left, int right, int fromIndex) { now is too long, how should I format it? What is the guideline? Thank you, Vladimir Wed, 5 May 2010 18:21:18 -0400 ?????? ?? Joshua Bloch : > Vladimir, > > On Wed, May 5, 2010 at 12:57 AM, Joshua Bloch wrote: > > The sentinel technique that you use in lines 118 - 136 is questionable: you are modifying a portion of the array outside the specified range of the call, which arguably violates the contract of the call, and could be observed in a multithreaded program. It's not beyond the realm of reason that it could break existing clients. I will discuss it with Doug Lea and let you know what he says. > > I talked to Doug, and he agrees that it's not acceptable to modify any location outside the array range that the caller has asked you to sort. This doesn't entirely kill the optimization; it's still OK to use on subranges that don't include the first element of the range that you were asked to sort. In other words, this test > > 120 if (left > 0) { > > Should be replaced by: > > 120 if (left > fromIndex + 1) { > > and you have to pass original fromIndex down to the recursive calls (in fact, you could pass fromIndex +1 to avoid the cost of the addition in each test). It's not clear whether the cost of passing this index down through the recursive calls will eliminate the gains of the optimization, but it's worth performing the experiment. > > Sorry, > Josh -------------- next part -------------- A non-text attachment was scrubbed... Name: DualPivotQuicksortWithoutSentinel.java Type: application/octet-stream Size: 96996 bytes Desc: not available URL: From martinrb at google.com Thu May 6 22:24:23 2010 From: martinrb at google.com (Martin Buchholz) Date: Thu, 6 May 2010 15:24:23 -0700 Subject: PriorityQueue(collection) should throw NPE Message-ID: This is a bug report with fix. (Chris, please file a bug) Summary: PriorityQueue(collection) should throw NPE if collection contains a null Description: PriorityQueue spec says: "A priority queue does not permit {@code null} elements." but the constructor taking a collection does not enforce that. Fix: http://cr.openjdk.java.net/~martin/webrevs/openjdk7/PriorityQueueConstructor/ Martin From David.Holmes at oracle.com Thu May 6 22:58:22 2010 From: David.Holmes at oracle.com (David Holmes) Date: Fri, 07 May 2010 08:58:22 +1000 Subject: PriorityQueue(collection) should throw NPE In-Reply-To: References: Message-ID: <4BE3498E.8080008@oracle.com> Martin, Martin Buchholz said the following on 05/07/10 08:24: > This is a bug report with fix. > (Chris, please file a bug) > > Summary: PriorityQueue(collection) should throw NPE if collection > contains a null > > Description: > PriorityQueue spec says: > > "A priority queue does not permit {@code null} elements." > > but the constructor taking a collection does not enforce that. > > Fix: > http://cr.openjdk.java.net/~martin/webrevs/openjdk7/PriorityQueueConstructor/ I'm not sure this is necessarily the right fix. It seems to me that incidental nulls will be caught in many/most cases by the sorting code for collections assumed to contain Comparable's. And we don't need to check when filling from an existing PriorityQueue. So is it only the case for filling from a SortedSet that needs the explicit null check? David From martinrb at google.com Thu May 6 23:13:57 2010 From: martinrb at google.com (Martin Buchholz) Date: Thu, 6 May 2010 16:13:57 -0700 Subject: PriorityQueue(collection) should throw NPE In-Reply-To: <4BE3498E.8080008@oracle.com> References: <4BE3498E.8080008@oracle.com> Message-ID: On Thu, May 6, 2010 at 15:58, David Holmes wrote: >> Fix: >> >> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/PriorityQueueConstructor/ > > I'm not sure this is necessarily the right fix. It seems to me that > incidental nulls will be caught in many/most cases by the sorting code for > collections assumed to contain Comparable's. The comparator might accept nulls. But even if it doesn't, it is possible to create a "corrupted" PQ using the PQ(collection) constructor, and we don't allow that sort of thing in java.util. > And we don't need to check when > filling from an existing PriorityQueue. Strictly speaking, the source PriorityQueue might be a subclass that has been modified to accept nulls. But yes, we could have a version of the fix that only checks for nulls if the source is not a PQ. > So is it only the case for filling > from a SortedSet that needs the explicit null check? The source can be an arbitrary Collection. Martin > David > From David.Holmes at oracle.com Thu May 6 23:53:05 2010 From: David.Holmes at oracle.com (David Holmes) Date: Fri, 07 May 2010 09:53:05 +1000 Subject: PriorityQueue(collection) should throw NPE In-Reply-To: References: <4BE3498E.8080008@oracle.com> Message-ID: <4BE35661.1060608@oracle.com> Hi Martin, Martin Buchholz said the following on 05/07/10 09:13: > On Thu, May 6, 2010 at 15:58, David Holmes wrote: >>> Fix: >>> >>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/PriorityQueueConstructor/ >> I'm not sure this is necessarily the right fix. It seems to me that >> incidental nulls will be caught in many/most cases by the sorting code for >> collections assumed to contain Comparable's. > > The comparator might accept nulls. True but a Comparator is only used if the Collection is a SortedSet or a PriorityQueue. For any other Collection the elements must implement Comparable and the code in: private void siftDownComparable(int k, E x) { Comparable key = (Comparable)x; int half = size >>> 1; // loop while a non-leaf while (k < half) { int child = (k << 1) + 1; // assume left child is least Object c = queue[child]; int right = child + 1; if (right < size && ((Comparable) c).compareTo((E) queue[right]) > 0) c = queue[child = right]; if (key.compareTo((E) c) <= 0) break; queue[k] = c; k = child; } queue[k] = key; } will throw NPE at key.compareTo if the item is null. (There's probably a missed case where the collection contains only a null element). > But even if it doesn't, it is possible to create a "corrupted" PQ > using the PQ(collection) constructor, and we don't allow > that sort of thing in java.util. But that's the hole we're fixing now. >> And we don't need to check when >> filling from an existing PriorityQueue. > > Strictly speaking, the source PriorityQueue might be a subclass that > has been modified to accept nulls. Yes I suppose. So we could change from an instanceof test to a getClass() test. > But yes, we could have a version of the fix that only checks for nulls > if the source is not a PQ. > >> So is it only the case for filling >> from a SortedSet that needs the explicit null check? > > The source can be an arbitrary Collection. But as noted above for anything other than a SortedSet (or corrupt PQ) the sorting code will already catch nulls. Cheers, David > Martin > >> David >> From martinrb at google.com Fri May 7 02:19:17 2010 From: martinrb at google.com (Martin Buchholz) Date: Thu, 6 May 2010 19:19:17 -0700 Subject: PriorityQueue(collection) should throw NPE In-Reply-To: <4BE35661.1060608@oracle.com> References: <4BE3498E.8080008@oracle.com> <4BE35661.1060608@oracle.com> Message-ID: David, Of course you're right. I didn't realize that the hole was one-element nulls. (Why is software always 10 times harder than you'd think?) Updated webrev, with lots more tests for corner cases. I still need a bug filed in bugtraq. Martin On Thu, May 6, 2010 at 16:53, David Holmes wrote: > Hi Martin, > > Martin Buchholz said the following on 05/07/10 09:13: >> >> On Thu, May 6, 2010 at 15:58, David Holmes >> wrote: >>>> >>>> Fix: >>>> >>>> >>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/PriorityQueueConstructor/ >>> >>> I'm not sure this is necessarily the right fix. It seems to me that >>> incidental nulls will be caught in many/most cases by the sorting code >>> for >>> collections assumed to contain Comparable's. >> >> The comparator might accept nulls. > > True but a Comparator is only used if the Collection is a SortedSet or a > PriorityQueue. For any other Collection the elements must implement > Comparable and the code in: > > ? private void siftDownComparable(int k, E x) { > ? ? ? ?Comparable key = (Comparable)x; > ? ? ? ?int half = size >>> 1; ? ? ? ?// loop while a non-leaf > ? ? ? ?while (k < half) { > ? ? ? ? ? ?int child = (k << 1) + 1; // assume left child is least > ? ? ? ? ? ?Object c = queue[child]; > ? ? ? ? ? ?int right = child + 1; > ? ? ? ? ? ?if (right < size && > ? ? ? ? ? ? ? ?((Comparable) c).compareTo((E) queue[right]) > 0) > ? ? ? ? ? ? ? ?c = queue[child = right]; > ? ? ? ? ? ?if (key.compareTo((E) c) <= 0) > ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ?queue[k] = c; > ? ? ? ? ? ?k = child; > ? ? ? ?} > ? ? ? ?queue[k] = key; > ? ?} > > will throw NPE at key.compareTo if the item is null. (There's probably a > missed case where the collection contains only a null element). > >> But even if it doesn't, it is possible to create a "corrupted" PQ >> using the PQ(collection) constructor, and we don't allow >> that sort of thing in java.util. > > But that's the hole we're fixing now. > >>> And we don't need to check when >>> filling from an existing PriorityQueue. >> >> Strictly speaking, the source PriorityQueue might be a subclass that >> has been modified to accept nulls. > > Yes I suppose. So we could change from an instanceof test to a getClass() > test. > >> But yes, we could have a version of the fix that only checks for nulls >> if the source is not a PQ. >> >>> So is it only the case for filling >>> from a SortedSet that needs the explicit null check? >> >> The source can be an arbitrary Collection. > > But as noted above for anything other than a SortedSet (or corrupt PQ) the > sorting code will already catch nulls. > > Cheers, > David > >> Martin >> >>> David >>> > From David.Holmes at oracle.com Fri May 7 02:37:35 2010 From: David.Holmes at oracle.com (David Holmes) Date: Fri, 07 May 2010 12:37:35 +1000 Subject: PriorityQueue(collection) should throw NPE In-Reply-To: References: <4BE3498E.8080008@oracle.com> <4BE35661.1060608@oracle.com> Message-ID: <4BE37CEF.2030604@oracle.com> Hi Martin, CR 6950540 filed. (Chris might want to tidy it up :) ) Changes look okay to me. Thanks, David Martin Buchholz said the following on 05/07/10 12:19: > David, > > Of course you're right. > I didn't realize that the hole was one-element nulls. > > (Why is software always 10 times harder than you'd think?) > > Updated webrev, with lots more tests for corner cases. > > I still need a bug filed in bugtraq. > > Martin > > On Thu, May 6, 2010 at 16:53, David Holmes wrote: >> Hi Martin, >> >> Martin Buchholz said the following on 05/07/10 09:13: >>> On Thu, May 6, 2010 at 15:58, David Holmes >>> wrote: >>>>> Fix: >>>>> >>>>> >>>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/PriorityQueueConstructor/ >>>> I'm not sure this is necessarily the right fix. It seems to me that >>>> incidental nulls will be caught in many/most cases by the sorting code >>>> for >>>> collections assumed to contain Comparable's. >>> The comparator might accept nulls. >> True but a Comparator is only used if the Collection is a SortedSet or a >> PriorityQueue. For any other Collection the elements must implement >> Comparable and the code in: >> >> private void siftDownComparable(int k, E x) { >> Comparable key = (Comparable)x; >> int half = size >>> 1; // loop while a non-leaf >> while (k < half) { >> int child = (k << 1) + 1; // assume left child is least >> Object c = queue[child]; >> int right = child + 1; >> if (right < size && >> ((Comparable) c).compareTo((E) queue[right]) > 0) >> c = queue[child = right]; >> if (key.compareTo((E) c) <= 0) >> break; >> queue[k] = c; >> k = child; >> } >> queue[k] = key; >> } >> >> will throw NPE at key.compareTo if the item is null. (There's probably a >> missed case where the collection contains only a null element). >> >>> But even if it doesn't, it is possible to create a "corrupted" PQ >>> using the PQ(collection) constructor, and we don't allow >>> that sort of thing in java.util. >> But that's the hole we're fixing now. >> >>>> And we don't need to check when >>>> filling from an existing PriorityQueue. >>> Strictly speaking, the source PriorityQueue might be a subclass that >>> has been modified to accept nulls. >> Yes I suppose. So we could change from an instanceof test to a getClass() >> test. >> >>> But yes, we could have a version of the fix that only checks for nulls >>> if the source is not a PQ. >>> >>>> So is it only the case for filling >>>> from a SortedSet that needs the explicit null check? >>> The source can be an arbitrary Collection. >> But as noted above for anything other than a SortedSet (or corrupt PQ) the >> sorting code will already catch nulls. >> >> Cheers, >> David >> >>> Martin >>> >>>> David >>>> From xueming.shen at oracle.com Fri May 7 05:29:28 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Thu, 06 May 2010 22:29:28 -0700 Subject: #4263582 Message-ID: <4BE3A538.7030801@oracle.com> Martin, Do you have time to take a quick look on this one? If you agree the proposed change (throw a more specific ZipException instead of the "general" IOException when gzip specific error occurs) I will get this one into the CCC queue. http://cr.openjdk.java.net/~sherman/4263582/webrev Thanks, -Sherman From martinrb at google.com Fri May 7 07:29:39 2010 From: martinrb at google.com (Martin Buchholz) Date: Fri, 7 May 2010 00:29:39 -0700 Subject: #4263582 In-Reply-To: <4BE3A538.7030801@oracle.com> References: <4BE3A538.7030801@oracle.com> Message-ID: This seems like an improvement to me. The only question is whether it's worth doing, but you obviously think it is, and that's good enough for me. Martin On Thu, May 6, 2010 at 22:29, Xueming Shen wrote: > Martin, > > Do you have time to take a quick look on this one? If you agree the proposed > change (throw a more specific > ZipException instead of the "general" IOException when gzip specific error > occurs) ?I will get this one into > the CCC queue. > > http://cr.openjdk.java.net/~sherman/4263582/webrev > > Thanks, > -Sherman > From chris.hegarty at oracle.com Fri May 7 09:12:20 2010 From: chris.hegarty at oracle.com (chris.hegarty at oracle.com) Date: Fri, 07 May 2010 09:12:20 +0000 Subject: hg: jdk7/tl/jdk: 6947917: Error in basic authentication when user name and password are long Message-ID: <20100507091233.3418F4479F@hg.openjdk.java.net> Changeset: a6928350e1f2 Author: chegar Date: 2010-05-07 10:11 +0100 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/a6928350e1f2 6947917: Error in basic authentication when user name and password are long Reviewed-by: weijun ! src/share/classes/sun/net/www/protocol/http/BasicAuthentication.java + test/sun/net/www/protocol/http/BasicLongCredentials.java From dmytro_sheyko at hotmail.com Fri May 7 09:31:47 2010 From: dmytro_sheyko at hotmail.com (Dmytro Sheyko) Date: Fri, 7 May 2010 16:31:47 +0700 Subject: New portion of improvements for Dual-Pivot Quicksort Message-ID: Hi, Wouldn't it better to use boolean flag instead of int index? -- Dmytro Sheyko PS --- DualPivotQuicksortWithoutSentinel.java Fri May 07 10:40:14 2010 +++ DualPivotQuicksortWithoutSentinelA.java Fri May 07 11:54:51 2010 @@ -39,7 +39,7 @@ * @version 2010.04.30 m765.827.12i:5\7 * @since 1.7 */ -final class DualPivotQuicksortWithoutSentinel { +final class DualPivotQuicksortWithoutSentinelA { /** * Prevents instantiation. @@ -78,7 +78,7 @@ * @param a the array to be sorted */ public static void sort(int[] a) { - dualPivotQuicksort(a, 0, a.length - 1, 0); + dualPivotQuicksort(a, 0, a.length - 1, true); } /** @@ -96,7 +96,7 @@ */ public static void sort(int[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); - dualPivotQuicksort(a, fromIndex, toIndex - 1, fromIndex); + dualPivotQuicksort(a, fromIndex, toIndex - 1, true); } /** @@ -108,12 +108,12 @@ * @param right the index of the last element, inclusive, to be sorted * @param fromIndex the first index of the original range to be sorted */ - private static void dualPivotQuicksort(int[] a, int left, int right, int fromIndex) { + private static void dualPivotQuicksort(int[] a, int left, int right, boolean leftmost) { int length = right - left + 1; // Use insertion sort on tiny arrays if (length < INSERTION_SORT_THRESHOLD) { - if (left > fromIndex) { + if (!leftmost) { /* * TODO */ @@ -129,11 +129,11 @@ * For case, when left == fromIndex, traditional (without * sentinel) insertion sort, optimized for server VM, is used. */ - for (int i = fromIndex, j = i; i < right; j = ++i) { + for (int i = left, j = i; i < right; j = ++i) { int ai = a[i + 1]; while (ai < a[j]) { a[j + 1] = a[j]; - if (j-- == fromIndex) { + if (j-- == left) { break; } } @@ -237,8 +237,8 @@ a[right] = a[great + 1]; a[great + 1] = pivot2; // Sort left and right parts recursively, excluding known pivots - dualPivotQuicksort(a, left, less - 2, fromIndex); - dualPivotQuicksort(a, great + 2, right, fromIndex); + dualPivotQuicksort(a, left, less - 2, leftmost); + dualPivotQuicksort(a, great + 2, right, false); /* * If center part is too large (comprises > 5/7 of the array), @@ -295,7 +295,7 @@ } // Sort center part recursively - dualPivotQuicksort(a, less, great, fromIndex); + dualPivotQuicksort(a, less, great, false); } else { // Pivots are equal /* @@ -350,8 +350,8 @@ } // Sort left and right parts recursively - dualPivotQuicksort(a, left, less - 1, fromIndex); - dualPivotQuicksort(a, great + 1, right, fromIndex); + dualPivotQuicksort(a, left, less - 1, leftmost); + dualPivotQuicksort(a, great + 1, right, false); } } > From: iaroslavski at mail.ru > To: jjb at google.com; dmytro_sheyko at hotmail.com > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > Subject: Re[2]: New portion of improvements for Dual-Pivot Quicksort > Date: Fri, 7 May 2010 00:46:59 +0400 > > Hello Josh, Dmytro, > > I've modified the DQP and now it doesn't touch elements outside of > the range and doesn't set a sentinel at all. Elements from the left > part are used as a sentinel (as it was suggested by Dmytro) and index > fromIndex is used as left boundary (suggestion from Josh). The index > fromIndex is the initial left boundary and passed down through the > recursions. No any tricks with changing outside of the range and > negative infinity. > > The fragment of code is (full version see in attachment): > > * ... > * @param fromIndex the first index of the original range to be sorted > */ > private static void dualPivotQuicksort(int[] a, int left, int right, int fromIndex) { > int length = right - left + 1; > > // Use insertion sort on tiny arrays > if (length < INSERTION_SORT_THRESHOLD) { > if (left > fromIndex) { > /* > * TODO > */ > for (int j, i = left + 1; i <= right; i++) { > int ai = a[i]; > for (j = i - 1; /* j >= left && */ ai < a[j]; j--) { > a[j + 1] = a[j]; > } > a[j + 1] = ai; > } > } else { > /* > * For case, when left == fromIndex, traditional (without > * sentinel) insertion sort, optimized for server VM, is used. > */ > for (int i = fromIndex, j = i; i < right; j = ++i) { > int ai = a[i + 1]; > while (ai < a[j]) { > a[j + 1] = a[j]; > if (j-- == fromIndex) { > break; > } > } > a[j + 1] = ai; > } > } > return; > } > ... > > This variant is little bit faster (~0.5%) on client VM and slower (~2%) > on server VM than original variant. I think that it is not too bad. > What do you think? > > And one question: the method declaration > > private static void dualPivotQuicksort(int[] a, int left, int right, int fromIndex) { > > now is too long, how should I format it? What is the guideline? > > Thank you, > Vladimir > > Wed, 5 May 2010 18:21:18 -0400 ?????? ?? Joshua Bloch : > > > Vladimir, > > > > On Wed, May 5, 2010 at 12:57 AM, Joshua Bloch wrote: > > > > The sentinel technique that you use in lines 118 - 136 is questionable: you are modifying a portion of the array outside the specified range of the call, which arguably violates the contract of the call, and could be observed in a multithreaded program. It's not beyond the realm of reason that it could break existing clients. I will discuss it with Doug Lea and let you know what he says. > > > > I talked to Doug, and he agrees that it's not acceptable to modify any location outside the array range that the caller has asked you to sort. This doesn't entirely kill the optimization; it's still OK to use on subranges that don't include the first element of the range that you were asked to sort. In other words, this test > > > > 120 if (left > 0) { > > > > Should be replaced by: > > > > 120 if (left > fromIndex + 1) { > > > > and you have to pass original fromIndex down to the recursive calls (in fact, you could pass fromIndex +1 to avoid the cost of the addition in each test). It's not clear whether the cost of passing this index down through the recursive calls will eliminate the gains of the optimization, but it's worth performing the experiment. > > > > Sorry, > > Josh _________________________________________________________________ Your E-mail and More On-the-Go. Get Windows Live Hotmail Free. https://signup.live.com/signup.aspx?id=60969 -------------- next part -------------- An HTML attachment was scrubbed... URL: From iaroslavski at mail.ru Fri May 7 09:35:33 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Fri, 07 May 2010 13:35:33 +0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: Message-ID: <4BE3DEE5.4070405@mail.ru> Hello Dmytro, I tried this case too, and the results are the same. But to be sure, I will check your version again. Thank you, Vladimir Dmytro Sheyko wrote: > Hi, > > Wouldn't it better to use boolean flag instead of int index? > > -- > Dmytro Sheyko > > > PS > --- DualPivotQuicksortWithoutSentinel.java Fri May 07 10:40:14 2010 > +++ DualPivotQuicksortWithoutSentinelA.java Fri May 07 11:54:51 2010 > @@ -39,7 +39,7 @@ > * @version 2010.04.30 m765.827.12i:5\7 > * @since 1.7 > */ > -final class DualPivotQuicksortWithoutSentinel { > +final class DualPivotQuicksortWithoutSentinelA { > > /** > * Prevents instantiation. > @@ -78,7 +78,7 @@ > * @param a the array to be sorted > */ > public static void sort(int[] a) { > - dualPivotQuicksort(a, 0, a.length - 1, 0); > + dualPivotQuicksort(a, 0, a.length - 1, true); > } > > /** > @@ -96,7 +96,7 @@ > */ > public static void sort(int[] a, int fromIndex, int toIndex) { > rangeCheck(a.length, fromIndex, toIndex); > - dualPivotQuicksort(a, fromIndex, toIndex - 1, fromIndex); > + dualPivotQuicksort(a, fromIndex, toIndex - 1, true); > } > > /** > @@ -108,12 +108,12 @@ > * @param right the index of the last element, inclusive, to be sorted > * @param fromIndex the first index of the original range to be sorted > */ > - private static void dualPivotQuicksort(int[] a, int left, int > right, int fromIndex) { > + private static void dualPivotQuicksort(int[] a, int left, int > right, boolean leftmost) { > int length = right - left + 1; > > // Use insertion sort on tiny arrays > if (length < INSERTION_SORT_THRESHOLD) { > - if (left > fromIndex) { > + if (!leftmost) { > /* > * TODO > */ > @@ -129,11 +129,11 @@ > * For case, when left == fromIndex, traditional (without > * sentinel) insertion sort, optimized for server VM, > is used. > */ > - for (int i = fromIndex, j = i; i < right; j = ++i) { > + for (int i = left, j = i; i < right; j = ++i) { > int ai = a[i + 1]; > while (ai < a[j]) { > a[j + 1] = a[j]; > - if (j-- == fromIndex) { > + if (j-- == left) { > break; > } > } > @@ -237,8 +237,8 @@ > a[right] = a[great + 1]; a[great + 1] = pivot2; > > // Sort left and right parts recursively, excluding known > pivots > - dualPivotQuicksort(a, left, less - 2, fromIndex); > - dualPivotQuicksort(a, great + 2, right, fromIndex); > + dualPivotQuicksort(a, left, less - 2, leftmost); > + dualPivotQuicksort(a, great + 2, right, false); > > /* > * If center part is too large (comprises > 5/7 of the array), > @@ -295,7 +295,7 @@ > } > > // Sort center part recursively > - dualPivotQuicksort(a, less, great, fromIndex); > + dualPivotQuicksort(a, less, great, false); > > } else { // Pivots are equal > /* > @@ -350,8 +350,8 @@ > } > > // Sort left and right parts recursively > - dualPivotQuicksort(a, left, less - 1, fromIndex); > - dualPivotQuicksort(a, great + 1, right, fromIndex); > + dualPivotQuicksort(a, left, less - 1, leftmost); > + dualPivotQuicksort(a, great + 1, right, false); > } > } > > > > From: iaroslavski at mail.ru > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > Subject: Re[2]: New portion of improvements for Dual-Pivot Quicksort > > Date: Fri, 7 May 2010 00:46:59 +0400 > > > > Hello Josh, Dmytro, > > > > I've modified the DQP and now it doesn't touch elements outside of > > the range and doesn't set a sentinel at all. Elements from the left > > part are used as a sentinel (as it was suggested by Dmytro) and index > > fromIndex is used as left boundary (suggestion from Josh). The index > > fromIndex is the initial left boundary and passed down through the > > recursions. No any tricks with changing outside of the range and > > negative infinity. > > > > The fragment of code is (full version see in attachment): > > > > * ... > > * @param fromIndex the first index of the original range to be sorted > > */ > > private static void dualPivotQuicksort(int[] a, int left, int right, > int fromIndex) { > > int length = right - left + 1; > > > > // Use insertion sort on tiny arrays > > if (length < INSERTION_SORT_THRESHOLD) { > > if (left > fromIndex) { > > /* > > * TODO > > */ > > for (int j, i = left + 1; i <= right; i++) { > > int ai = a[i]; > > for (j = i - 1; /* j >= left && */ ai < a[j]; j--) { > > a[j + 1] = a[j]; > > } > > a[j + 1] = ai; > > } > > } else { > > /* > > * For case, when left == fromIndex, traditional (without > > * sentinel) insertion sort, optimized for server VM, is used. > > */ > > for (int i = fromIndex, j = i; i < right; j = ++i) { > > int ai = a[i + 1]; > > while (ai < a[j]) { > > a[j + 1] = a[j]; > > if (j-- == fromIndex) { > > break; > > } > > } > > a[j + 1] = ai; > > } > > } > > return; > > } > > ... > > > > This variant is little bit faster (~0.5%) on client VM and slower (~2%) > > on server VM than original variant. I think that it is not too bad. > > What do you think? > > > > And one question: the method declaration > > > > private static void dualPivotQuicksort(int[] a, int left, int right, > int fromIndex) { > > > > now is too long, how should I format it? What is the guideline? > > > > Thank you, > > Vladimir > > > > Wed, 5 May 2010 18:21:18 -0400 ?????? ?? Joshua Bloch : > > > > > Vladimir, > > > > > > On Wed, May 5, 2010 at 12:57 AM, Joshua Bloch wrote: > > > > > > The sentinel technique that you use in lines 118 - 136 is > questionable: you are modifying a portion of the array outside the > specified range of the call, which arguably violates the contract of the > call, and could be observed in a multithreaded program. It's not beyond > the realm of reason that it could break existing clients. I will discuss > it with Doug Lea and let you know what he says. > > > > > > I talked to Doug, and he agrees that it's not acceptable to modify > any location outside the array range that the caller has asked you to > sort. This doesn't entirely kill the optimization; it's still OK to use > on subranges that don't include the first element of the range that you > were asked to sort. In other words, this test > > > > > > 120 if (left > 0) { > > > > > > Should be replaced by: > > > > > > 120 if (left > fromIndex + 1) { > > > > > > and you have to pass original fromIndex down to the recursive calls > (in fact, you could pass fromIndex +1 to avoid the cost of the addition > in each test). It's not clear whether the cost of passing this index > down through the recursive calls will eliminate the gains of the > optimization, but it's worth performing the experiment. > > > > > > Sorry, > > > Josh From chris.hegarty at oracle.com Fri May 7 09:55:38 2010 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Fri, 07 May 2010 10:55:38 +0100 Subject: PriorityQueue(collection) should throw NPE In-Reply-To: <4BE37CEF.2030604@oracle.com> References: <4BE3498E.8080008@oracle.com> <4BE35661.1060608@oracle.com> <4BE37CEF.2030604@oracle.com> Message-ID: <4BE3E39A.7090003@oracle.com> Hi David, Martin, Thanks for filing the bug David, I'll just add a link to the email thread in the archive for reference. Just one minor observation while reviewing the changes. Is it necessary for initFromPriorityQueue to call initFromCollection ( in the case where you're given a PriorityQueue subclass), or can it simply call initElementsFromCollection? -Chris. On 07/05/2010 03:37, David Holmes wrote: > Hi Martin, > > CR 6950540 filed. (Chris might want to tidy it up :) ) > > Changes look okay to me. > > Thanks, > David > > Martin Buchholz said the following on 05/07/10 12:19: >> David, >> >> Of course you're right. >> I didn't realize that the hole was one-element nulls. >> >> (Why is software always 10 times harder than you'd think?) >> >> Updated webrev, with lots more tests for corner cases. >> >> I still need a bug filed in bugtraq. >> >> Martin >> >> On Thu, May 6, 2010 at 16:53, David Holmes >> wrote: >>> Hi Martin, >>> >>> Martin Buchholz said the following on 05/07/10 09:13: >>>> On Thu, May 6, 2010 at 15:58, David Holmes >>>> wrote: >>>>>> Fix: >>>>>> >>>>>> >>>>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/PriorityQueueConstructor/ >>>>>> >>>>> I'm not sure this is necessarily the right fix. It seems to me that >>>>> incidental nulls will be caught in many/most cases by the sorting code >>>>> for >>>>> collections assumed to contain Comparable's. >>>> The comparator might accept nulls. >>> True but a Comparator is only used if the Collection is a SortedSet or a >>> PriorityQueue. For any other Collection the elements must implement >>> Comparable and the code in: >>> >>> private void siftDownComparable(int k, E x) { >>> Comparable key = (Comparable)x; >>> int half = size >>> 1; // loop while a non-leaf >>> while (k < half) { >>> int child = (k << 1) + 1; // assume left child is least >>> Object c = queue[child]; >>> int right = child + 1; >>> if (right < size && >>> ((Comparable) c).compareTo((E) queue[right]) > 0) >>> c = queue[child = right]; >>> if (key.compareTo((E) c) <= 0) >>> break; >>> queue[k] = c; >>> k = child; >>> } >>> queue[k] = key; >>> } >>> >>> will throw NPE at key.compareTo if the item is null. (There's probably a >>> missed case where the collection contains only a null element). >>> >>>> But even if it doesn't, it is possible to create a "corrupted" PQ >>>> using the PQ(collection) constructor, and we don't allow >>>> that sort of thing in java.util. >>> But that's the hole we're fixing now. >>> >>>>> And we don't need to check when >>>>> filling from an existing PriorityQueue. >>>> Strictly speaking, the source PriorityQueue might be a subclass that >>>> has been modified to accept nulls. >>> Yes I suppose. So we could change from an instanceof test to a >>> getClass() >>> test. >>> >>>> But yes, we could have a version of the fix that only checks for nulls >>>> if the source is not a PQ. >>>> >>>>> So is it only the case for filling >>>>> from a SortedSet that needs the explicit null check? >>>> The source can be an arbitrary Collection. >>> But as noted above for anything other than a SortedSet (or corrupt >>> PQ) the >>> sorting code will already catch nulls. >>> >>> Cheers, >>> David >>> >>>> Martin >>>> >>>>> David >>>>> From David.Holmes at oracle.com Fri May 7 10:47:12 2010 From: David.Holmes at oracle.com (David Holmes) Date: Fri, 07 May 2010 20:47:12 +1000 Subject: PriorityQueue(collection) should throw NPE In-Reply-To: <4BE3E39A.7090003@oracle.com> References: <4BE3498E.8080008@oracle.com> <4BE35661.1060608@oracle.com> <4BE37CEF.2030604@oracle.com> <4BE3E39A.7090003@oracle.com> Message-ID: <4BE3EFB0.8040503@oracle.com> Hi Chris, Chris Hegarty said the following on 05/07/10 19:55: > Hi David, Martin, > > Thanks for filing the bug David, I'll just add a link to the email > thread in the archive for reference. Thanks. > Just one minor observation while reviewing the changes. Is it necessary > for initFromPriorityQueue to call initFromCollection ( in the case where > you're given a PriorityQueue subclass), or can it simply call > initElementsFromCollection? It's possible that the subclass overrides toArray to return an array that doesn't preserve the internal order. Hence we need to re-sort, hence initFromCollection. David > -Chris. > > On 07/05/2010 03:37, David Holmes wrote: >> Hi Martin, >> >> CR 6950540 filed. (Chris might want to tidy it up :) ) >> >> Changes look okay to me. >> >> Thanks, >> David >> >> Martin Buchholz said the following on 05/07/10 12:19: >>> David, >>> >>> Of course you're right. >>> I didn't realize that the hole was one-element nulls. >>> >>> (Why is software always 10 times harder than you'd think?) >>> >>> Updated webrev, with lots more tests for corner cases. >>> >>> I still need a bug filed in bugtraq. >>> >>> Martin >>> >>> On Thu, May 6, 2010 at 16:53, David Holmes >>> wrote: >>>> Hi Martin, >>>> >>>> Martin Buchholz said the following on 05/07/10 09:13: >>>>> On Thu, May 6, 2010 at 15:58, David Holmes >>>>> wrote: >>>>>>> Fix: >>>>>>> >>>>>>> >>>>>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/PriorityQueueConstructor/ >>>>>>> >>>>>>> >>>>>> I'm not sure this is necessarily the right fix. It seems to me that >>>>>> incidental nulls will be caught in many/most cases by the sorting >>>>>> code >>>>>> for >>>>>> collections assumed to contain Comparable's. >>>>> The comparator might accept nulls. >>>> True but a Comparator is only used if the Collection is a SortedSet >>>> or a >>>> PriorityQueue. For any other Collection the elements must implement >>>> Comparable and the code in: >>>> >>>> private void siftDownComparable(int k, E x) { >>>> Comparable key = (Comparable)x; >>>> int half = size >>> 1; // loop while a non-leaf >>>> while (k < half) { >>>> int child = (k << 1) + 1; // assume left child is least >>>> Object c = queue[child]; >>>> int right = child + 1; >>>> if (right < size && >>>> ((Comparable) c).compareTo((E) queue[right]) > 0) >>>> c = queue[child = right]; >>>> if (key.compareTo((E) c) <= 0) >>>> break; >>>> queue[k] = c; >>>> k = child; >>>> } >>>> queue[k] = key; >>>> } >>>> >>>> will throw NPE at key.compareTo if the item is null. (There's >>>> probably a >>>> missed case where the collection contains only a null element). >>>> >>>>> But even if it doesn't, it is possible to create a "corrupted" PQ >>>>> using the PQ(collection) constructor, and we don't allow >>>>> that sort of thing in java.util. >>>> But that's the hole we're fixing now. >>>> >>>>>> And we don't need to check when >>>>>> filling from an existing PriorityQueue. >>>>> Strictly speaking, the source PriorityQueue might be a subclass that >>>>> has been modified to accept nulls. >>>> Yes I suppose. So we could change from an instanceof test to a >>>> getClass() >>>> test. >>>> >>>>> But yes, we could have a version of the fix that only checks for nulls >>>>> if the source is not a PQ. >>>>> >>>>>> So is it only the case for filling >>>>>> from a SortedSet that needs the explicit null check? >>>>> The source can be an arbitrary Collection. >>>> But as noted above for anything other than a SortedSet (or corrupt >>>> PQ) the >>>> sorting code will already catch nulls. >>>> >>>> Cheers, >>>> David >>>> >>>>> Martin >>>>> >>>>>> David >>>>>> From chris.hegarty at oracle.com Fri May 7 10:50:36 2010 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Fri, 07 May 2010 11:50:36 +0100 Subject: PriorityQueue(collection) should throw NPE In-Reply-To: <4BE3EFB0.8040503@oracle.com> References: <4BE3498E.8080008@oracle.com> <4BE35661.1060608@oracle.com> <4BE37CEF.2030604@oracle.com> <4BE3E39A.7090003@oracle.com> <4BE3EFB0.8040503@oracle.com> Message-ID: <4BE3F07C.50807@oracle.com> On 07/05/2010 11:47, David Holmes wrote: > Hi Chris, > > Chris Hegarty said the following on 05/07/10 19:55: >> Hi David, Martin, >> >> Thanks for filing the bug David, I'll just add a link to the email >> thread in the archive for reference. > > Thanks. > >> Just one minor observation while reviewing the changes. Is it >> necessary for initFromPriorityQueue to call initFromCollection ( in >> the case where you're given a PriorityQueue subclass), or can it >> simply call initElementsFromCollection? > > It's possible that the subclass overrides toArray to return an array > that doesn't preserve the internal order. Hence we need to re-sort, > hence initFromCollection. OK, not problem. Just checking. -Chris. > > David > From iaroslavski at mail.ru Fri May 7 12:27:55 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Fri, 07 May 2010 16:27:55 +0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: <4BE3DEE5.4070405@mail.ru> References: <4BE3DEE5.4070405@mail.ru> Message-ID: <4BE4074B.5040100@mail.ru> Hi Dmytro, Your suggested variant is better than variant with fromIndex. It works little bit faster than my original one: ~0.7% for client and the same for server VM (my variant with boolean flag uses opposite value, and it works slower than yours). Now the ratio of times is: new / jdk7: 0.88 for client, 1.01 for server new / jdk6: 0.61 for client, 0.49 for server And what about long method declaration: private static void dualPivotQuicksort(int[] a, int left, int right, boolean leftmost) I think that we can use name "sort" for it, and the line will be shorter. I'm preparing new version, and will send it soon. Thank you, Vladimir Vladimir Iaroslavski wrote: > Hello Dmytro, > > I tried this case too, and the results are the same. > But to be sure, I will check your version again. > > Thank you, > Vladimir > > Dmytro Sheyko wrote: >> Hi, >> >> Wouldn't it better to use boolean flag instead of int index? >> >> -- >> Dmytro Sheyko >> >> PS >> --- DualPivotQuicksortWithoutSentinel.java Fri May 07 10:40:14 2010 >> +++ DualPivotQuicksortWithoutSentinelA.java Fri May 07 11:54:51 2010 >> @@ -39,7 +39,7 @@ >> * @version 2010.04.30 m765.827.12i:5\7 >> * @since 1.7 >> */ >> -final class DualPivotQuicksortWithoutSentinel { >> +final class DualPivotQuicksortWithoutSentinelA { >> >> /** >> * Prevents instantiation. >> @@ -78,7 +78,7 @@ >> * @param a the array to be sorted >> */ >> public static void sort(int[] a) { >> - dualPivotQuicksort(a, 0, a.length - 1, 0); >> + dualPivotQuicksort(a, 0, a.length - 1, true); >> } >> >> /** >> @@ -96,7 +96,7 @@ >> */ >> public static void sort(int[] a, int fromIndex, int toIndex) { >> rangeCheck(a.length, fromIndex, toIndex); >> - dualPivotQuicksort(a, fromIndex, toIndex - 1, fromIndex); >> + dualPivotQuicksort(a, fromIndex, toIndex - 1, true); >> } >> >> /** >> @@ -108,12 +108,12 @@ >> * @param right the index of the last element, inclusive, to be >> sorted >> * @param fromIndex the first index of the original range to be >> sorted >> */ >> - private static void dualPivotQuicksort(int[] a, int left, int >> right, int fromIndex) { >> + private static void dualPivotQuicksort(int[] a, int left, int >> right, boolean leftmost) { >> int length = right - left + 1; >> >> // Use insertion sort on tiny arrays >> if (length < INSERTION_SORT_THRESHOLD) { >> - if (left > fromIndex) { >> + if (!leftmost) { >> /* >> * TODO >> */ >> @@ -129,11 +129,11 @@ >> * For case, when left == fromIndex, traditional >> (without >> * sentinel) insertion sort, optimized for server VM, >> is used. >> */ >> - for (int i = fromIndex, j = i; i < right; j = ++i) { >> + for (int i = left, j = i; i < right; j = ++i) { >> int ai = a[i + 1]; >> while (ai < a[j]) { >> a[j + 1] = a[j]; >> - if (j-- == fromIndex) { >> + if (j-- == left) { >> break; >> } >> } >> @@ -237,8 +237,8 @@ >> a[right] = a[great + 1]; a[great + 1] = pivot2; >> >> // Sort left and right parts recursively, excluding known >> pivots >> - dualPivotQuicksort(a, left, less - 2, fromIndex); >> - dualPivotQuicksort(a, great + 2, right, fromIndex); >> + dualPivotQuicksort(a, left, less - 2, leftmost); >> + dualPivotQuicksort(a, great + 2, right, false); >> >> /* >> * If center part is too large (comprises > 5/7 of the >> array), >> @@ -295,7 +295,7 @@ >> } >> >> // Sort center part recursively >> - dualPivotQuicksort(a, less, great, fromIndex); >> + dualPivotQuicksort(a, less, great, false); >> >> } else { // Pivots are equal >> /* >> @@ -350,8 +350,8 @@ >> } >> >> // Sort left and right parts recursively >> - dualPivotQuicksort(a, left, less - 1, fromIndex); >> - dualPivotQuicksort(a, great + 1, right, fromIndex); >> + dualPivotQuicksort(a, left, less - 1, leftmost); >> + dualPivotQuicksort(a, great + 1, right, false); >> } >> } >> >> > From: iaroslavski at mail.ru >> > To: jjb at google.com; dmytro_sheyko at hotmail.com >> > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru >> > Subject: Re[2]: New portion of improvements for Dual-Pivot Quicksort >> > Date: Fri, 7 May 2010 00:46:59 +0400 >> > >> > Hello Josh, Dmytro, >> > >> > I've modified the DQP and now it doesn't touch elements outside of >> > the range and doesn't set a sentinel at all. Elements from the left >> > part are used as a sentinel (as it was suggested by Dmytro) and index >> > fromIndex is used as left boundary (suggestion from Josh). The index >> > fromIndex is the initial left boundary and passed down through the >> > recursions. No any tricks with changing outside of the range and >> > negative infinity. >> > >> > The fragment of code is (full version see in attachment): >> > >> > * ... >> > * @param fromIndex the first index of the original range to be sorted >> > */ >> > private static void dualPivotQuicksort(int[] a, int left, int >> right, int fromIndex) { >> > int length = right - left + 1; >> > >> > // Use insertion sort on tiny arrays >> > if (length < INSERTION_SORT_THRESHOLD) { >> > if (left > fromIndex) { >> > /* >> > * TODO >> > */ >> > for (int j, i = left + 1; i <= right; i++) { >> > int ai = a[i]; >> > for (j = i - 1; /* j >= left && */ ai < a[j]; j--) { >> > a[j + 1] = a[j]; >> > } >> > a[j + 1] = ai; >> > } >> > } else { >> > /* >> > * For case, when left == fromIndex, traditional (without >> > * sentinel) insertion sort, optimized for server VM, is used. >> > */ >> > for (int i = fromIndex, j = i; i < right; j = ++i) { >> > int ai = a[i + 1]; >> > while (ai < a[j]) { >> > a[j + 1] = a[j]; >> > if (j-- == fromIndex) { >> > break; >> > } >> > } >> > a[j + 1] = ai; >> > } >> > } >> > return; >> > } >> > ... >> > >> > This variant is little bit faster (~0.5%) on client VM and slower >> (~2%) >> > on server VM than original variant. I think that it is not too bad. >> > What do you think? >> > >> > And one question: the method declaration >> > >> > private static void dualPivotQuicksort(int[] a, int left, int >> right, int fromIndex) { >> > >> > now is too long, how should I format it? What is the guideline? >> > >> > Thank you, >> > Vladimir >> > >> > Wed, 5 May 2010 18:21:18 -0400 ?????? ?? Joshua Bloch >> : >> > >> > > Vladimir, >> > > >> > > On Wed, May 5, 2010 at 12:57 AM, Joshua Bloch >> wrote: >> > > >> > > The sentinel technique that you use in lines 118 - 136 is >> questionable: you are modifying a portion of the array outside the >> specified range of the call, which arguably violates the contract of >> the call, and could be observed in a multithreaded program. It's not >> beyond the realm of reason that it could break existing clients. I >> will discuss it with Doug Lea and let you know what he says. >> > > >> > > I talked to Doug, and he agrees that it's not acceptable to >> modify any location outside the array range that the caller has asked >> you to sort. This doesn't entirely kill the optimization; it's still >> OK to use on subranges that don't include the first element of the >> range that you were asked to sort. In other words, this test >> > > >> > > 120 if (left > 0) { >> > > >> > > Should be replaced by: >> > > >> > > 120 if (left > fromIndex + 1) { >> > > >> > > and you have to pass original fromIndex down to the recursive >> calls (in fact, you could pass fromIndex +1 to avoid the cost of the >> addition in each test). It's not clear whether the cost of passing >> this index down through the recursive calls will eliminate the gains >> of the optimization, but it's worth performing the experiment. >> > > >> > > Sorry, >> > > Josh From chris.hegarty at oracle.com Fri May 7 15:12:40 2010 From: chris.hegarty at oracle.com (chris.hegarty at oracle.com) Date: Fri, 07 May 2010 15:12:40 +0000 Subject: hg: jdk7/tl/jdk: 6946673: DatagramSocket.connect() documentation contradicts the implementation Message-ID: <20100507151313.794D144869@hg.openjdk.java.net> Changeset: 4fba3512c566 Author: chegar Date: 2010-05-07 16:11 +0100 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/4fba3512c566 6946673: DatagramSocket.connect() documentation contradicts the implementation Reviewed-by: alanb ! src/share/classes/java/net/DatagramSocket.java From martinrb at google.com Fri May 7 17:07:10 2010 From: martinrb at google.com (Martin Buchholz) Date: Fri, 7 May 2010 10:07:10 -0700 Subject: PriorityQueue(collection) should throw NPE In-Reply-To: <4BE3EFB0.8040503@oracle.com> References: <4BE3498E.8080008@oracle.com> <4BE35661.1060608@oracle.com> <4BE37CEF.2030604@oracle.com> <4BE3E39A.7090003@oracle.com> <4BE3EFB0.8040503@oracle.com> Message-ID: On Fri, May 7, 2010 at 03:47, David Holmes wrote: > Hi Chris, > > Chris Hegarty said the following on 05/07/10 19:55: >> >> Hi David, Martin, >> >> Thanks for filing the bug David, I'll just add a link to the email thread >> in the archive for reference. > > Thanks. > >> Just one minor observation while reviewing the changes. Is it necessary >> for initFromPriorityQueue to call initFromCollection ( in the case where >> you're given a PriorityQueue subclass), or can it simply call >> initElementsFromCollection? > > It's possible that the subclass overrides toArray to return an array that > doesn't preserve the internal order. Hence we need to re-sort, hence > initFromCollection. Yes. As a thought experiment, suppose you're writing a spiffy new priority queue implementation that is supposed to be a drop-in replacement for PriorityQueue. You might choose to subclass PriorityQueue even if you're not reusing any of the implementation (because we made the mistake of not making PriorityQueue an interface). PriorityQueue's iterator and toArray methods make no promises about element order. On the bright side, heapify() will be O(N), not O(N log N) if the input array is already heapified. Martin From iaroslavski at mail.ru Sat May 8 14:58:59 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Sat, 08 May 2010 18:58:59 +0400 Subject: =?koi8-r?Q?Re[4]=3A_New_portion_of_improvements_for_Dual-Pivot_Quicksort?= In-Reply-To: References: Message-ID: Josh, Dmytro, I've updated DualPivotQuicksort class, changes have been done for all types. Please, review the new version. Thank you, Vladimir Fri, 7 May 2010 16:31:47 +0700 ?????? ?? Dmytro Sheyko : > Hi, > > Wouldn't it better to use boolean flag instead of int index? > > -- > Dmytro Sheyko > > > PS > --- DualPivotQuicksortWithoutSentinel.java Fri May 07 10:40:14 2010 > +++ DualPivotQuicksortWithoutSentinelA.java Fri May 07 11:54:51 2010 > @@ -39,7 +39,7 @@ > * @version 2010.04.30 m765.827.12i:5\7 > * @since 1.7 > */ > -final class DualPivotQuicksortWithoutSentinel { > +final class DualPivotQuicksortWithoutSentinelA { > > /** > * Prevents instantiation. > @@ -78,7 +78,7 @@ > * @param a the array to be sorted > */ > public static void sort(int[] a) { > - dualPivotQuicksort(a, 0, a.length - 1, 0); > + dualPivotQuicksort(a, 0, a.length - 1, true); > } > > /** > @@ -96,7 +96,7 @@ > */ > public static void sort(int[] a, int fromIndex, int toIndex) { > rangeCheck(a.length, fromIndex, toIndex); > - dualPivotQuicksort(a, fromIndex, toIndex - 1, fromIndex); > + dualPivotQuicksort(a, fromIndex, toIndex - 1, true); > } > > /** > @@ -108,12 +108,12 @@ > * @param right the index of the last element, inclusive, to be sorted > * @param fromIndex the first index of the original range to be sorted > */ > - private static void dualPivotQuicksort(int[] a, int left, int right, int fromIndex) { > + private static void dualPivotQuicksort(int[] a, int left, int right, boolean leftmost) { > int length = right - left + 1; > > // Use insertion sort on tiny arrays > if (length < INSERTION_SORT_THRESHOLD) { > - if (left > fromIndex) { > + if (!leftmost) { > /* > * TODO > */ > @@ -129,11 +129,11 @@ > * For case, when left == fromIndex, traditional (without > * sentinel) insertion sort, optimized for server VM, is used. > */ > - for (int i = fromIndex, j = i; i < right; j = ++i) { > + for (int i = left, j = i; i < right; j = ++i) { > int ai = a[i + 1]; > while (ai < a[j]) { > a[j + 1] = a[j]; > - if (j-- == fromIndex) { > + if (j-- == left) { > break; > } > } > @@ -237,8 +237,8 @@ > a[right] = a[great + 1]; a[great + 1] = pivot2; > > // Sort left and right parts recursively, excluding known pivots > - dualPivotQuicksort(a, left, less - 2, fromIndex); > - dualPivotQuicksort(a, great + 2, right, fromIndex); > + dualPivotQuicksort(a, left, less - 2, leftmost); > + dualPivotQuicksort(a, great + 2, right, false); > > /* > * If center part is too large (comprises > 5/7 of the array), > @@ -295,7 +295,7 @@ > } > > // Sort center part recursively > - dualPivotQuicksort(a, less, great, fromIndex); > + dualPivotQuicksort(a, less, great, false); > > } else { // Pivots are equal > /* > @@ -350,8 +350,8 @@ > } > > // Sort left and right parts recursively > - dualPivotQuicksort(a, left, less - 1, fromIndex); > - dualPivotQuicksort(a, great + 1, right, fromIndex); > + dualPivotQuicksort(a, left, less - 1, leftmost); > + dualPivotQuicksort(a, great + 1, right, false); > } > } > > > > From: iaroslavski at mail.ru > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > Subject: Re[2]: New portion of improvements for Dual-Pivot Quicksort > > Date: Fri, 7 May 2010 00:46:59 +0400 > > > > Hello Josh, Dmytro, > > > > I've modified the DQP and now it doesn't touch elements outside of > > the range and doesn't set a sentinel at all. Elements from the left > > part are used as a sentinel (as it was suggested by Dmytro) and index > > fromIndex is used as left boundary (suggestion from Josh). The index > > fromIndex is the initial left boundary and passed down through the > > recursions. No any tricks with changing outside of the range and > > negative infinity. > > > > The fragment of code is (full version see in attachment): > > > > * ... > > * @param fromIndex the first index of the original range to be sorted > > */ > > private static void dualPivotQuicksort(int[] a, int left, int right, int fromIndex) { > > int length = right - left + 1; > > > > // Use insertion sort on tiny arrays > > if (length < INSERTION_SORT_THRESHOLD) { > > if (left > fromIndex) { > > /* > > * TODO > > */ > > for (int j, i = left + 1; i <= right; i++) { > > int ai = a[i]; > > for (j = i - 1; /* j >= left && */ ai < a[j]; j--) { > > a[j + 1] = a[j]; > > } > > a[j + 1] = ai; > > } > > } else { > > /* > > * For case, when left == fromIndex, traditional (without > > * sentinel) insertion sort, optimized for server VM, is used. > > */ > > for (int i = fromIndex, j = i; i < right; j = ++i) { > > int ai = a[i + 1]; > > while (ai < a[j]) { > > a[j + 1] = a[j]; > > if (j-- == fromIndex) { > > break; > > } > > } > > a[j + 1] = ai; > > } > > } > > return; > > } > > ... > > > > This variant is little bit faster (~0.5%) on client VM and slower (~2%) > > on server VM than original variant. I think that it is not too bad. > > What do you think? > > > > And one question: the method declaration > > > > private static void dualPivotQuicksort(int[] a, int left, int right, int fromIndex) { > > > > now is too long, how should I format it? What is the guideline? > > > > Thank you, > > Vladimir -------------- next part -------------- A non-text attachment was scrubbed... Name: DualPivotQuicksort.java Type: application/octet-stream Size: 100790 bytes Desc: not available URL: From xueming.shen at oracle.com Sat May 8 21:49:22 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Sat, 08 May 2010 14:49:22 -0700 Subject: Unicode script support in Regex and Character class In-Reply-To: References: <4BD00250.3020206@oracle.com> Message-ID: <4BE5DC62.6020304@oracle.com> Hi, The API proposals for Unicode script support below have been approved. 6945564: Unicode script support in Character class 6948903: Make Unicode scripts available for use in regular expressions Here is the final webrev ready for push. http://cr.openjdk.java.net/~sherman/6945564_6948903/webrev (1) It is suggested that the access to the UnicodeScript and UnicodeBlock's ranges data might be desirable for certain use scenario, for example our regex engine might benefit from such access to avoid runime binary search for each/every matching operation. I'm considering to add a pair of UnicodeScript.is(codePoint) & UnicdeBlock.is(codePoint) to address this issue, but prefer to handle it in a separate RFE (it seems like it's a no-brainer for UnicodeBlock, but tricky for the UncodeScript, given its wide ranges of lots scripts, any suggestion? or alternative?). (2)Testing result suggests there is not too much runtime benefit of keeping a huge string data pool + an access hashmap for getName() implementation. The latest implementation now takes Ulf's suggestion to keep a relatively small byte[] pool and generate the names at runtime. (there is "even smaller" implementation, which consumes about 300K memory at runtime http://cr.openjdk.java.net/~sherman/script/webrev.00/ but it has a "scalability" problem need to address when string pool grows beyond 64k and it is little slow) (3)The UnicodeScript implementation is built on Unicode 5.2 Script.txt. The rest of the Character class however is still using the previous version waiting for Yuka's Unicode 5.2 RFE to get back in. (4)The previous webrev can be found at http://cr.openjdk.java.net/~sherman/scripte Please help review. Thanks, -Sherman From kevin.l.stern at gmail.com Sun May 9 13:14:16 2010 From: kevin.l.stern at gmail.com (Kevin L. Stern) Date: Sun, 9 May 2010 08:14:16 -0500 Subject: A List implementation backed by multiple small arrays rather than the traditional single large array. In-Reply-To: References: <1704b7a21003280455u784d4d2ape39a47e2367b79a8@mail.gmail.com> Message-ID: Trying to understand this: public static void main(String[] args) { final NumberFormat format = new DecimalFormat("0.000000"); final Random rng = new Random(); final int maxSize = 100000; final int warmup = 100; final long[] time = new long[2]; for (int i = 0; i < 1000; i++) { if (i % 3 == 0) System.gc(); List cad = new ChunkedArrayDeque(); List al = new ArrayList(1); int size = rng.nextInt(maxSize - 1) + 1; long thisTime = System.nanoTime(); for (int j = 0; j < size; j++) { al.add(j); } if (i > warmup) time[0] += System.nanoTime() - thisTime; thisTime = System.nanoTime(); for (int j = 0; j < size; j++) { cad.add(j); } if (i > warmup) time[1] += System.nanoTime() - thisTime; } System.out.println(format.format((double)time[1] / time[0])); } Consistently prints around 0.834112, whereas if I change List al = new ArrayList(1); to ArrayList al = new ArrayList(1); I consistently see around 0.965947. Any ideas why the type of the reference would make such a difference? Kevin On Sun, Apr 25, 2010 at 4:25 AM, Benedict Elliott Smith wrote: > Wow, those numbers really are very impressive. I had to double check > against your previous statistics to confirm the direction of the ratio... > Those numbers make this data structure look like the weapon of choice for > any but the smallest of lists. > > On 24 April 2010 19:41, Kevin L. Stern wrote: > >> Hi Benedict, >> >> You are absolutely right - the constant on the cost of growth is going to >> be higher with the new data structure. That being said, the performance >> numbers that I'm getting with it are actually quite impressive when compared >> to ArrayList: >> >> Note that all numbers are with a client VM and are generated using the >> same routine that I used for the ChunkedArrayList performance numbers. >> >> 1000000 elements: >> >> Add to ChunkedArrayDeque over ArrayList: 0.89 >> Indexed access ChunkedArrayDeque over ArrayList: 0.81 >> Iterator ChunkedArrayDeque over ArrayList: 0.51 >> >> 100000 elements: >> >> Add to ChunkedArrayDeque over ArrayList: 1.01 >> Indexed access ChunkedArrayDeque over ArrayList: 0.79 >> Iterator ChunkedArrayDeque over ArrayList: 0.50 >> >> 10000 elements: >> >> Add to ChunkedArrayDeque over ArrayList: 1.15 >> Indexed access ChunkedArrayDeque over ArrayList: 1.15 >> Iterator ChunkedArrayDeque over ArrayList: 0.51 >> >> 1000 elements: >> >> Add to ChunkedArrayDeque over ArrayList: 1.35 >> Indexed access ChunkedArrayDeque over ArrayList: 1.12 >> Iterator ChunkedArrayDeque over ArrayList: 0.54 >> >> Kevin >> >> >> On Sat, Apr 24, 2010 at 1:27 PM, Benedict Elliott Smith > > wrote: >> >>> Yes, I had spotted that benefit - but (please correct me if I am >>> misreading this as it is quite possible) in order to maintain your array >>> allocation invariant, array copies are needed (rather than straight >>> allocations) - and so the cost of growth is likely to be noticeably larger. >>> That said, if random access is considerably quicker this might be a sensible >>> trade off, but perhaps there is a place for both data structures. >>> >>> >>> >>> On 24 April 2010 19:14, Kevin L. Stern wrote: >>> >>>> Hi Benedict, >>>> >>>> Thanks, I'll definitely give this a try. I certainly don't see any >>>> issue with skipping the size 1 array in order to speed up general operation. >>>> >>>> By the way, I'm currently focused a bit more on the deque - I'm not sure >>>> that anything is going to come of this ChunkedArrayList on its own. With >>>> the deque, index decomposition is much faster than any of these >>>> implementations as it lends itself to bit operations without the requirement >>>> of computing the logarithm. >>>> >>>> Kevin >>>> >>>> >>>> On Sat, Apr 24, 2010 at 12:30 PM, Benedict Elliott Smith < >>>> lists at laerad.com> wrote: >>>> >>>>> If you want a drop in replacement with minimal fuss to test it out, try >>>>> below (although it's a quick hack of including the >>>>> Integer.numberOfLeadingZeros() call to avoid its now unnecessary non-zero >>>>> test, and instead utilise this op to return the zero index). Just delete the >>>>> existing get() method and replace it with this code. Actually this version >>>>> seems to improve throughput further - on my laptop regular ChunkedArrayList >>>>> is currently averaging around 790ms per run of my hacky speed test, whereas >>>>> with the modifications below it averages around 610ms, making it almost 25% >>>>> faster. I've included my performance benchmark as well, for reference. I'm >>>>> sure with some thought a better one could be put together. >>>>> >>>>> private static final int arrayIndex2(int index) { >>>>> if (index == 1) >>>>> return 0 ; >>>>> int i = index >>> 1 ; >>>>> int n = 1; >>>>> if (i >>> 16 == 0) { n += 16; i <<= 16; } >>>>> if (i >>> 24 == 0) { n += 8; i <<= 8; } >>>>> if (i >>> 28 == 0) { n += 4; i <<= 4; } >>>>> if (i >>> 30 == 0) { n += 2; i <<= 2; } >>>>> n -= i >>> 31; >>>>> final int arraySizeShiftMinusSeed = (31 - n) >>> 1 ; >>>>> final int b1 = (2 << arraySizeShiftMinusSeed << >>>>> arraySizeShiftMinusSeed) ; >>>>> final int a1 = (1 << arraySizeShiftMinusSeed + 2) ; >>>>> final int b2 = index - b1 ; >>>>> final int a2 = (1 << arraySizeShiftMinusSeed) ; >>>>> final int b4 = b2 >>> arraySizeShiftMinusSeed + 1 ; >>>>> final int av = a1 - a2 ; >>>>> final int bv = b4 - 2 ; >>>>> return av + bv ; >>>>> } >>>>> >>>>> @Override >>>>> public T get(int index) { >>>>> if ((0 > index) | (index >= _size)) >>>>> throw new IndexOutOfBoundsException(); >>>>> index += 1 ; >>>>> final Object[] array = _backingArray[arrayIndex2(index)] ; >>>>> return (T) array[index & (array.length - 1)] ; >>>>> } >>>>> >>>>> >>>>> //// benchmarked by >>>>> >>>>> static final int count = 1 << 24 ; >>>>> static final int mask = count - 1 ; >>>>> public static void main(String[] args) { >>>>> double sum = 0 ; >>>>> final List list = new ChunkedArrayList() ; >>>>> for (int i = 0 ; i != count ; i++) >>>>> list.add(i) ; >>>>> for (int r = 0 ; r != 100 ; r++) { >>>>> final long start = System.currentTimeMillis() ; >>>>> int o = 0 ; >>>>> for (int j = 0 ; j != count ; j++) { >>>>> list.get((j + o) & mask) ; >>>>> o += 1 ; >>>>> } >>>>> final long end = System.currentTimeMillis() ; >>>>> sum += (end - start) ; >>>>> System.out.println(String.format("run %d: >>>>> %dms; avg=%.0fms", r, (end - start), sum / (r + 1))) ; >>>>> } >>>>> } >>>>> >>>>> >>>>> On 24 April 2010 09:34, Benedict Elliott Smith wrote: >>>>> >>>>>> Hi Kevin, >>>>>> >>>>>> If you are willing to change the pattern of allocation just slightly, >>>>>> I have come up with an alternate algorithm (optimised for the seed = 1 case) >>>>>> that on my laptop I notice around a 10-20% speed up over ChunkedArrayList >>>>>> for random(ish) calls to get() on a list of size 1 << 24. The change is to >>>>>> simply drop your first array allocation (so that there are no arrays of size >>>>>> 1, but that all remaining allocations follow the existing pattern), as this >>>>>> allows simplifying the algorithm noticeably (several ops in the previous >>>>>> algorithm were unnecessary for any but the first two arrays). >>>>>> >>>>>> My get(index) method is defined as: >>>>>> >>>>>> if ((index < 0) | (index >= _size)) >>>>>> throw new IllegalArgumentException() ; >>>>>> index += 2 ; >>>>>> final Object[] array = _backingArray[arrayFor(index)] ; >>>>>> return (T) array[index & (array.length - 1)] ; >>>>>> >>>>>> and arrayFor(index) is defined as: >>>>>> >>>>>> private static final int arrayFor(int index) { >>>>>> final int arraySizeShiftMinusSeed = (31 - >>>>>> Integer.numberOfLeadingZeros(index >>> 1)) >>> 1 ; >>>>>> final int b1 = (2 << arraySizeShiftMinusSeed << >>>>>> arraySizeShiftMinusSeed) ; >>>>>> final int a1 = (1 << arraySizeShiftMinusSeed + 2) ; >>>>>> final int b2 = index - b1 ; >>>>>> final int a2 = (1 << arraySizeShiftMinusSeed) ; >>>>>> final int b4 = b2 >>> arraySizeShiftMinusSeed + 1 ; >>>>>> final int av = a1 - a2 ; >>>>>> final int bv = b4 - 3 ; >>>>>> return av + bv ; >>>>>> } >>>>>> >>>>>> I have deliberately interleaved the calculations here to make sure the >>>>>> pipeline is being used (just in case javac+hotspot are not re-ordering the >>>>>> intermediate calculations for us) >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> On 24 April 2010 08:24, Benedict Elliott Smith wrote: >>>>>> >>>>>>> Hi Kevin, >>>>>>> >>>>>>> It looks like this is because ChunkedArrayList creates only one >>>>>>> initial array of size s, whereas my algorithm expects two . Apologies for >>>>>>> not spotting this - the pattern of allocations is identical after this >>>>>>> point. I'll see if it can be modified to support your pattern of allocation. >>>>>>> >>>>>>> >>>>>>> On 24 April 2010 01:31, Kevin L. Stern wrote: >>>>>>> >>>>>>>> Hi Benedict, >>>>>>>> >>>>>>>> I took a look at your index decomposition routine; it was not >>>>>>>> working for seed = 1 until I made index the query index plus one (similar to >>>>>>>> my r variable) and arrayIndex ((firstArrayOfThisSize + arrayOffset) & >>>>>>>> Integer.MAX_VALUE) - 1 (notice I'm subtracting one). Once I made these >>>>>>>> changes the routine was actually slower than my version (although not by >>>>>>>> much). Let me know if you have a better way to bring your routine in line >>>>>>>> with the arraylet structure. >>>>>>>> >>>>>>>> Kevin >>>>>>>> >>>>>>>> >>>>>>>> On Fri, Apr 23, 2010 at 2:26 PM, Benedict Elliott Smith < >>>>>>>> lists at laerad.com> wrote: >>>>>>>> >>>>>>>>> Hi Kevin, >>>>>>>>> >>>>>>>>> Unfortunately this week has been pretty hectic, and I haven't had >>>>>>>>> much time to much more than theorise on this topic - and this weekend the >>>>>>>>> weather looks set to be much too nice to stay in doors! It looks like you've >>>>>>>>> made really good progress on the ChunkedArrayDeque - I haven't fully >>>>>>>>> digested it yet, but it looks pretty impressive. I'm not sure (since I >>>>>>>>> misunderstood your list implementation prior to reading it in detail) but I >>>>>>>>> think I may have been toying with a similar growth strategy for a hash map >>>>>>>>> variant since the copies are necessary there anyway. >>>>>>>>> >>>>>>>>> I have taken another look at the index algorithm and have tidied it >>>>>>>>> up as below, and it now supports a seed size of 1; however I am not sure >>>>>>>>> that using a value this small is advisable, given that the overhead for the >>>>>>>>> first array is at least 60 bytes; with a seed size of 1 the first 8 indexes >>>>>>>>> would utilise less than 20% of the allocated memory for data, the first 24 >>>>>>>>> less than 25%. I would have thought a seed of at least 2 and perhaps 3 would >>>>>>>>> be advisable. >>>>>>>>> >>>>>>>>> As an aside, it is worth noting that the indexOffset calculation >>>>>>>>> below can be replaced with index & (_backingArray[arrayIndex].length - 1) , >>>>>>>>> although I am not certain what effect this will have on performance, given >>>>>>>>> that this would be another memory operation to retrieve the length from the >>>>>>>>> array; but it would make the separation of the calculation into functions >>>>>>>>> more straight forward. >>>>>>>>> >>>>>>>>> final int arraySizeShiftMinusSeed = (31 - >>>>>>>>> Integer.numberOfLeadingZeros(index >>> seed)) >>> 1 ; >>>>>>>>> final int arraySizeShift = arraySizeShiftMinusSeed + seed ; >>>>>>>>> >>>>>>>>> final int firstArrayOfThisSize = >>>>>>>>> (1 << arraySizeShiftMinusSeed + 2) >>>>>>>>> - (1 << arraySizeShiftMinusSeed) >>>>>>>>> - 1 - (arraySizeShift >>> 31) ; >>>>>>>>> final int indexRemainder = index - (1 << arraySizeShift << >>>>>>>>> arraySizeShiftMinusSeed) ; >>>>>>>>> >>>>>>>>> final int arrayOffset = indexRemainder >>> arraySizeShift ; >>>>>>>>> final int arrayIndex = (firstArrayOfThisSize + arrayOffset) & >>>>>>>>> Integer.MAX_VALUE ; >>>>>>>>> >>>>>>>>> final int itemIndex = index & ((1 << arraySizeShift) - 1) ; >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On 23 April 2010 11:00, Kevin L. Stern wrote: >>>>>>>>> >>>>>>>>>> Hi Benedict, >>>>>>>>>> >>>>>>>>>> Have you had a chance to get your index decomposition procedure to >>>>>>>>>> work with seed values less than two? >>>>>>>>>> >>>>>>>>>> Kevin >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Sat, Apr 17, 2010 at 11:48 AM, Benedict Elliott Smith < >>>>>>>>>> lists at laerad.com> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Kevin, >>>>>>>>>>> >>>>>>>>>>> As it happens I might have something useful still to contribute. >>>>>>>>>>> As an exercise in saving face I revisited the problem to see if I could >>>>>>>>>>> achieve the same complexity bounds as ChunkedArrayList but with a lower >>>>>>>>>>> overhead. I must admit I still didn't fully appreciate how the algorithm in >>>>>>>>>>> ChunkedArrayList worked until I tried to come up with an algorithm with >>>>>>>>>>> similar properties. What I have ended up with is almost identical except >>>>>>>>>>> adds I think a couple of incremental improvements, simply by redefining the >>>>>>>>>>> arrayIndex() method. I should note that I have not yet implemented more than >>>>>>>>>>> a prototype as it seems to me your implementation is excellent already, and >>>>>>>>>>> if it is decided to include my modifications the changes should be modest. >>>>>>>>>>> >>>>>>>>>>> Firstly, (I hope that) what I have produced is a little more CPU >>>>>>>>>>> pipe-line friendly; there is less dependency on immediately preceding >>>>>>>>>>> calculations at each stage (i.e. so more operations should be able to >>>>>>>>>>> proceed simultaneously in the pipeline), and consists exclusively of shifts, >>>>>>>>>>> addition/subtraction and bit-wise (&)ands (except for the conditionals in >>>>>>>>>>> Integer.numberOfLeadingZeros(i)), although the total number of instructions >>>>>>>>>>> is approximately the same. >>>>>>>>>>> >>>>>>>>>>> Secondly, I have modified the algorithm so that a "seed" size can >>>>>>>>>>> be specified (although I expect hard coding a suitable one will ultimately >>>>>>>>>>> be best). Whereas ChunkedArrayList currently requires that the pattern of >>>>>>>>>>> array allocation sizes be [1, 1, 2, 2, 2, 4(..*6), 8(..*12), 16(..*24)] we >>>>>>>>>>> can now support, for some "*s*", [*s*(..*2), 2*s*(..*3), 4*s*(..*6), >>>>>>>>>>> 8*s*(..*12), 16*s*(..*24)] etc. although when put in simple text >>>>>>>>>>> like that it does appear to trivialise the change. The benefit of this, >>>>>>>>>>> though, is two fold: 1) for small n the constant factor is reduced (both CPU >>>>>>>>>>> and memory wise); and 2) the sqrt(n) bounds are reached more quickly also. >>>>>>>>>>> >>>>>>>>>>> As an illustration, consider setting *s* to 4, and assume the >>>>>>>>>>> backing array is size two and doubles in size with each growth; with >>>>>>>>>>> ChunkedArrayList we would resize at i=2, i=6, i=20, i=72; with * >>>>>>>>>>> s* as 4 we would instead resize at i=8,i=24,i=80,i=288; the cost >>>>>>>>>>> at each would be some multiple of 2,4,8,16 respectively. As you can see the >>>>>>>>>>> latter is much closer to the sqrt(n) cost - both approach it eventually, but >>>>>>>>>>> my suggestion is to reach it more quickly. This is at the expense of more >>>>>>>>>>> slowly reaching the sqrt(n) wasted memory condition, but given the high >>>>>>>>>>> constant factor cost wrt to memory at this early stage, this seems a very >>>>>>>>>>> sensible trade off. It seems likely this should also have a positive impact >>>>>>>>>>> on cache performance for smaller lists as well. >>>>>>>>>>> >>>>>>>>>>> Finally, after playing with this idea in my head I am confident I >>>>>>>>>>> can extend the core ideas of this data structure to hashing relatively >>>>>>>>>>> easily, getting the the same worst case O(sqrt(n)) insertion cost, and >>>>>>>>>>> O(sqrt(n)) wasted memory guarantees. I notice that this case hasn't been >>>>>>>>>>> addressed yet, although I see from Martin's recent mail that this was raised >>>>>>>>>>> before. Unless there are better suggestions for solving the hash table >>>>>>>>>>> problem I will have a go at it as it seems an interesting problem - that is, >>>>>>>>>>> assuming there are no objections? >>>>>>>>>>> >>>>>>>>>>> I'm interested to hear your thoughts. I hope this time I've been >>>>>>>>>>> a bit more considered in what I've put forward, and hence less of a waste of >>>>>>>>>>> time! >>>>>>>>>>> >>>>>>>>>>> Code snippet for calculation of array index and item offset: >>>>>>>>>>> >>>>>>>>>>> final int arraySizeShiftMinusSeed = ((31 - >>>>>>>>>>> Integer.numberOfLeadingZeros(index >>> seed)) >>> 1) ; >>>>>>>>>>> final int arraySizeShift = arraySizeShiftMinusSeed + seed ; >>>>>>>>>>> final int firstArrayOfThisSize = ((((1 << >>>>>>>>>>> arraySizeShiftMinusSeed + 3) - (1 << arraySizeShiftMinusSeed + 1))) >>> 1) - >>>>>>>>>>> 1 ; >>>>>>>>>>> final int indexRemainder = index - ((1 << seed) << >>>>>>>>>>> arraySizeShiftMinusSeed + arraySizeShiftMinusSeed) ; >>>>>>>>>>> final int arrayOffset = indexRemainder >>> arraySizeShift ; >>>>>>>>>>> >>>>>>>>>>> final int arrayIndex = firstArrayOfThisSize + arrayOffset ; >>>>>>>>>>> final int itemIndex = index & ((1 << arraySizeShift) - 1) ; >>>>>>>>>>> >>>>>>>>>>> the first array size will be 1 << seed - 1 (i.e. seed is equal to >>>>>>>>>>> *s* + 1); seed only works for values for 2 or more at this >>>>>>>>>>> moment, fyi >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On 16 April 2010 00:18, Kevin L. Stern wrote: >>>>>>>>>>> >>>>>>>>>>>> Oh no worries Benedict, thanks for your interest in the topic. >>>>>>>>>>>> Let me know if you have any other questions or if you have any related ideas >>>>>>>>>>>> or concerns. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Thu, Apr 15, 2010 at 8:00 AM, Benedict Elliott Smith < >>>>>>>>>>>> lists at laerad.com> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Sorry Kevin - it sounds like I might be being of more hindrance >>>>>>>>>>>>> than help. that part of the discussion was clearly truncated by the time I >>>>>>>>>>>>> had joined the list - I haven't been able to find the history in the >>>>>>>>>>>>> archives either... >>>>>>>>>>>>> >>>>>>>>>>>>> I was just wondering about the worst case cost of add() as >>>>>>>>>>>>> described by your javadoc; admittedly it is optimal with respect to unused >>>>>>>>>>>>> memory, but the worst case cost of an add is still sqrt(n), with a >>>>>>>>>>>>> relatively high constant factor. I had been thinking that once n passed a >>>>>>>>>>>>> threshold the cost of additions in this other structure would become a >>>>>>>>>>>>> constant factor, offering nice algorithmic complexity guarantees for large >>>>>>>>>>>>> n; however since sqrt(Integer.MAX_VALUE) is ~46,000, the maximum size of new >>>>>>>>>>>>> array allocations would have to be unrealistically small (assuming linear >>>>>>>>>>>>> cost for allocation) for this to be the case. It would still be nice to have >>>>>>>>>>>>> a data structure that avoids needing to copy data with each grow, whilst >>>>>>>>>>>>> still maintaining good memory performance. >>>>>>>>>>>>> >>>>>>>>>>>>> That *all* being said, I had been going by your javadoc and >>>>>>>>>>>>> emails to ascertain the behaviour of this class, as I couldn't locate a free >>>>>>>>>>>>> copy of [Brodnik99resizablearrays], and it seems this was a bad idea; as the >>>>>>>>>>>>> sqrt(n) cost appears to be associated with growing the backing array, rather >>>>>>>>>>>>> than with what I assumed to be copying data between arraylets, and it seems >>>>>>>>>>>>> this cost is pretty optimal. That will teach me to post to a list without >>>>>>>>>>>>> getting my facts straight first. The interesting thing is simply that the >>>>>>>>>>>>> constant factor for this implementation still seems to be quite high, >>>>>>>>>>>>> although perhaps that is simply because I was not benchmarking sufficiently >>>>>>>>>>>>> large values of n. >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> On 15 April 2010 12:12, Kevin L. Stern < >>>>>>>>>>>>> kevin.l.stern at gmail.com> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Benedict, >>>>>>>>>>>>>> >>>>>>>>>>>>>> Unless I am misreading your post, this now has a very similar >>>>>>>>>>>>>> feel to the first data structure that I posted to the list. Martin Buchholz >>>>>>>>>>>>>> then pointed out that we can incorporate the ideas from >>>>>>>>>>>>>> [Brodnik99resizablearrays] and reap additional benefits. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>> >>>>>>>>>>>>>> Kevin >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Thu, Apr 15, 2010 at 4:07 AM, Benedict Elliott Smith < >>>>>>>>>>>>>> lists at laerad.com> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi Kevin, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Yes, as I was going to bed last night I realised I had not >>>>>>>>>>>>>>> fully addressed the problem that was originally being visited; only reduced >>>>>>>>>>>>>>> the constant factor for addition to the end of the list. A trivial >>>>>>>>>>>>>>> modification fixes that, however; same scheme but up to some maximum >>>>>>>>>>>>>>> arraylet size (of a power of 2), after which the array is increased in size >>>>>>>>>>>>>>> linearly. Performance doesn't seem to have been affected appreciably, >>>>>>>>>>>>>>> although not been exhaustive in the benchmarking: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> 10 items inserts versus ArrayList: Chunked=1.15, >>>>>>>>>>>>>>> ExpArray=1.16 >>>>>>>>>>>>>>> 10 items inserts Chunked / ExpArray = 0.99 >>>>>>>>>>>>>>> 10 items get versus ArrayList: Chunked=1.15, ExpArray=1.16 >>>>>>>>>>>>>>> 10 items get Chunked / ExpArray = 0.99 >>>>>>>>>>>>>>> 100 items inserts versus ArrayList: Chunked=1.24, >>>>>>>>>>>>>>> ExpArray=1.01 >>>>>>>>>>>>>>> 100 items inserts Chunked / ExpArray = 1.23 >>>>>>>>>>>>>>> 100 items get versus ArrayList: Chunked=1.24, ExpArray=1.01 >>>>>>>>>>>>>>> 100 items get Chunked / ExpArray = 1.23 >>>>>>>>>>>>>>> 1000 items inserts versus ArrayList: Chunked=1.22, >>>>>>>>>>>>>>> ExpArray=1.03 >>>>>>>>>>>>>>> 1000 items inserts Chunked / ExpArray = 1.19 >>>>>>>>>>>>>>> 1000 items get versus ArrayList: Chunked=1.22, ExpArray=1.03 >>>>>>>>>>>>>>> 1000 items get Chunked / ExpArray = 1.19 >>>>>>>>>>>>>>> 10000 items inserts versus ArrayList: Chunked=1.22, >>>>>>>>>>>>>>> ExpArray=1.03 >>>>>>>>>>>>>>> 10000 items inserts Chunked / ExpArray = 1.18 >>>>>>>>>>>>>>> 10000 items get versus ArrayList: Chunked=1.22, ExpArray=1.03 >>>>>>>>>>>>>>> 10000 items get Chunked / ExpArray = 1.18 >>>>>>>>>>>>>>> 100000 items inserts versus ArrayList: Chunked=0.82, >>>>>>>>>>>>>>> ExpArray=0.75 >>>>>>>>>>>>>>> 100000 items inserts Chunked / ExpArray = 1.09 >>>>>>>>>>>>>>> 100000 items get versus ArrayList: Chunked=0.82, >>>>>>>>>>>>>>> ExpArray=0.75 >>>>>>>>>>>>>>> 100000 items get Chunked / ExpArray = 1.09 >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> The nice thing about this is that the maximum amount of >>>>>>>>>>>>>>> wasted memory is user configurable. Even with a low setting as above (65K) >>>>>>>>>>>>>>> performance seems pretty consistent. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Code for calculating index and array offset are pretty >>>>>>>>>>>>>>> straight forward; haven't given much thought to optimisations just yet: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> private final int indexFor(int a, int i) { >>>>>>>>>>>>>>> return 1 + i - (a > maxArrayIndex ? (1 + a - maxArrayIndex) >>>>>>>>>>>>>>> << maxArraySizeShift : 1 << a) ; >>>>>>>>>>>>>>> } >>>>>>>>>>>>>>> private final int arrayFor(int i) { >>>>>>>>>>>>>>> return i >= (maxArraySize << 1) ? (i + 1 >>> >>>>>>>>>>>>>>> maxArraySizeShift) + maxArrayIndex - 1 : 31 - Integer.numberOfLeadingZeros(i >>>>>>>>>>>>>>> + 1) ; >>>>>>>>>>>>>>> } >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Regarding the double list idea - yes, I agree, I certainly >>>>>>>>>>>>>>> didn't think that one through fully! >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On 15 April 2010 02:44, Kevin L. Stern < >>>>>>>>>>>>>>> kevin.l.stern at gmail.com> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi Benedict, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Like you, I am relatively new to this mailing list; I am >>>>>>>>>>>>>>>> also trying to tread lightly so as not to step on any toes. That being >>>>>>>>>>>>>>>> said, I think that I can offer a response to your inquiry. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Regarding: "The idea is to simply double the new array size >>>>>>>>>>>>>>>> each time a new array needs to be allocated" >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> It seems this would not address the desire of offering an >>>>>>>>>>>>>>>> alternative to the allocation of a large backing array for ArrayList (your >>>>>>>>>>>>>>>> largest backing array could still reach a size of 1/2 * Integer.MAX_VALUE) >>>>>>>>>>>>>>>> and would not address the desire of wasting the (asymptotically) minimum >>>>>>>>>>>>>>>> amount of memory in the worst case while maintaining O(1) amortized time >>>>>>>>>>>>>>>> bounds. The data structure described in [Brodnik99resizablearrays] has a >>>>>>>>>>>>>>>> maximum backing array size of sqrt(n) and caps wasted memory at sqrt(n). >>>>>>>>>>>>>>>> What advantage over ArrayList do you see in your data structure? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Regarding: "Also, with regard to a Deque implementation, it >>>>>>>>>>>>>>>> seems that the simplest solution would be to simply have two lists, with one >>>>>>>>>>>>>>>> accepting inserts for near the beginning and being ordered in reverse whilst >>>>>>>>>>>>>>>> the other accepted inserts for near to the end." >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> What happens with your structure when you add n elements and >>>>>>>>>>>>>>>> then remove element 0 n times? I think that once you work out all the kinks >>>>>>>>>>>>>>>> you'll end up with the two stacks approach, which is mentioned in >>>>>>>>>>>>>>>> [Brodnik99resizablearrays] and which I mentioned in an earlier email, or >>>>>>>>>>>>>>>> you'll end up with the circular list approach, which is not friendly to O(1) >>>>>>>>>>>>>>>> amortized time bounds in a data structure that resizes more often than O(n) >>>>>>>>>>>>>>>> due to the 'unshift' to the front = 0 position. I think the best approach >>>>>>>>>>>>>>>> is the one mentioned in [Brodnik99resizablearrays], which is the approach >>>>>>>>>>>>>>>> that I am currently working on. Incidentally, this approach also provides >>>>>>>>>>>>>>>> for a much improved index unpacking procedure using only bit shifts and bit >>>>>>>>>>>>>>>> masks, although it is at the expense of (O(1)) additional work during >>>>>>>>>>>>>>>> resize. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Kevin >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Wed, Apr 14, 2010 at 4:42 PM, Benedict Elliott Smith < >>>>>>>>>>>>>>>> lists at laerad.com> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi, >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I hope you don't consider it rude to involve myself in this >>>>>>>>>>>>>>>>> conversation towards the end - I joined the mailing list only recently. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I'm not sure if this offers a huge amount to the >>>>>>>>>>>>>>>>> discussion, but I have tinkered with a "chunked" array list which seems to >>>>>>>>>>>>>>>>> offer better time performance in general at the cost of greater (worst case) >>>>>>>>>>>>>>>>> memory utilisation. It is easier to understand IMHO as well, although this >>>>>>>>>>>>>>>>> is not necessarily a great benefit here. It turns out the idea is very >>>>>>>>>>>>>>>>> similar to the one implemented already by Kevin, though; but perhaps >>>>>>>>>>>>>>>>> simpler. The idea is to simply double the new array size each time a new >>>>>>>>>>>>>>>>> array needs to be allocated, or in effect allocate an array that is the size >>>>>>>>>>>>>>>>> of all existing arrays put together. With this scheme the calculation for >>>>>>>>>>>>>>>>> array and offset are really very straight forward ( floor(log(i)) and 1 + i >>>>>>>>>>>>>>>>> - 2^floor(log(i))) ). Memory utilisation is the same as for ArrayList, but >>>>>>>>>>>>>>>>> obviously inserts at the end are much quicker. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I have prototyped the data structure this evening and >>>>>>>>>>>>>>>>> benchmarked additions at the end of the list, for which the performance is >>>>>>>>>>>>>>>>> pretty impressive. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Some random statistics for addition only on the client JVM >>>>>>>>>>>>>>>>> (I have quickly dubbed my implementation ExpArrayList) >>>>>>>>>>>>>>>>> All statistics were run in two rounds with ~1000 runs per >>>>>>>>>>>>>>>>> round per statistic per list, and the second round results were used. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> 10 items versus ArrayList: Chunked=1.14, ExpArray=1.02 >>>>>>>>>>>>>>>>> 10 items Chunked / ExpArray = 1.12 >>>>>>>>>>>>>>>>> 100 items versus ArrayList: Chunked=1.20, ExpArray=0.82 >>>>>>>>>>>>>>>>> 100 items Chunked / ExpArray = 1.45 >>>>>>>>>>>>>>>>> 1000 items versus ArrayList: Chunked=1.03, ExpArray=0.51 >>>>>>>>>>>>>>>>> 1000 items Chunked / ExpArray = 2.02 >>>>>>>>>>>>>>>>> 10000 items versus ArrayList: Chunked=0.88, ExpArray=0.49 >>>>>>>>>>>>>>>>> 10000 items Chunked / ExpArray = 1.79 >>>>>>>>>>>>>>>>> 100000 items versus ArrayList: Chunked=0.32, ExpArray=0.20 >>>>>>>>>>>>>>>>> 100000 items Chunked / ExpArray = 1.64 >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> and server JVM: >>>>>>>>>>>>>>>>> 10 items versus ArrayList: Chunked=1.00, ExpArray=1.16 >>>>>>>>>>>>>>>>> 10 items Chunked / ExpArray = 0.86 >>>>>>>>>>>>>>>>> 100 items versus ArrayList: Chunked=1.29, ExpArray=0.96 >>>>>>>>>>>>>>>>> 100 items Chunked / ExpArray = 1.34 >>>>>>>>>>>>>>>>> 1000 items versus ArrayList: Chunked=1.16, ExpArray=0.92 >>>>>>>>>>>>>>>>> 1000 items Chunked / ExpArray = 1.27 >>>>>>>>>>>>>>>>> 10000 items versus ArrayList: Chunked=0.93, ExpArray=0.84 >>>>>>>>>>>>>>>>> 10000 items Chunked / ExpArray = 1.12 >>>>>>>>>>>>>>>>> 100000 items versus ArrayList: Chunked=0.71, ExpArray=0.65 >>>>>>>>>>>>>>>>> 100000 items Chunked / ExpArray = 1.10 >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Interestingly insertion at the beginning of the list >>>>>>>>>>>>>>>>> appears to be quicker with ExpArrayList, at least on the server JVM, whereas >>>>>>>>>>>>>>>>> I would have expected them to be fairly close. >>>>>>>>>>>>>>>>> Amazingly ExpArrayList is faster even than ArrayList for >>>>>>>>>>>>>>>>> insertion at the beginning of large lists, which I haven't yet tried to >>>>>>>>>>>>>>>>> understand. Insertion in the middle is similar. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> 10 items versus ArrayList: Chunked=9.82, ExpArray=3.80 >>>>>>>>>>>>>>>>> 10 items Chunked / ExpArray = 2.59 >>>>>>>>>>>>>>>>> 100 items versus ArrayList: Chunked=7.30, ExpArray=3.41 >>>>>>>>>>>>>>>>> 100 items Chunked / ExpArray = 2.14 >>>>>>>>>>>>>>>>> 1000 items versus ArrayList: Chunked=2.83, ExpArray=1.09 >>>>>>>>>>>>>>>>> 1000 items Chunked / ExpArray = 2.59 >>>>>>>>>>>>>>>>> 10000 items versus ArrayList: Chunked=1.56, ExpArray=0.72 >>>>>>>>>>>>>>>>> 10000 items Chunked / ExpArray = 2.16 >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Finally, there are promising results for get() from the >>>>>>>>>>>>>>>>> ExpArrayList as well (server JVM), again somehow beating ArrayList for >>>>>>>>>>>>>>>>> larger lists: >>>>>>>>>>>>>>>>> 10 items get versus ArrayList: Chunked=1.27, ExpArray=1.16 >>>>>>>>>>>>>>>>> 10 items get Chunked / ExpArray = 1.10 >>>>>>>>>>>>>>>>> 100 items get versus ArrayList: Chunked=1.45, ExpArray=1.17 >>>>>>>>>>>>>>>>> 100 items get Chunked / ExpArray = 1.25 >>>>>>>>>>>>>>>>> 1000 items get versus ArrayList: Chunked=1.42, >>>>>>>>>>>>>>>>> ExpArray=1.07 >>>>>>>>>>>>>>>>> 1000 items get Chunked / ExpArray = 1.33 >>>>>>>>>>>>>>>>> 10000 items get versus ArrayList: Chunked=1.26, >>>>>>>>>>>>>>>>> ExpArray=1.02 >>>>>>>>>>>>>>>>> 10000 items get Chunked / ExpArray = 1.24 >>>>>>>>>>>>>>>>> 100000 items get versus ArrayList: Chunked=1.05, >>>>>>>>>>>>>>>>> ExpArray=0.86 >>>>>>>>>>>>>>>>> 100000 items get Chunked / ExpArray = 1.22 >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I'm willing to explore this further but I'm not sure how >>>>>>>>>>>>>>>>> desirable that is, given that Kevin's data structure appears to perform >>>>>>>>>>>>>>>>> pretty well already wrt to CPU time, and better wrt to memory utilisation, >>>>>>>>>>>>>>>>> and in effect this mostly changes only the function to determine which array >>>>>>>>>>>>>>>>> to use, not the body of the implementation. Let me know if you would like a >>>>>>>>>>>>>>>>> copy of the source code and I will find somewhere to upload it. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Also, with regard to a Deque implementation, it seems that >>>>>>>>>>>>>>>>> the simplest solution would be to simply have two lists, with one accepting >>>>>>>>>>>>>>>>> inserts for near the beginning and being ordered in reverse whilst the other >>>>>>>>>>>>>>>>> accepted inserts for near to the end. The only trick would be having the >>>>>>>>>>>>>>>>> list at the beginning support iteration in reverse order cheaply, but this >>>>>>>>>>>>>>>>> could easily be achieved by creating an extension of List with a >>>>>>>>>>>>>>>>> reverseIterator() method. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Anyway, not sure if this helped at all but fancied joining >>>>>>>>>>>>>>>>> in... >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On 14 April 2010 12:25, Joe Kearney < >>>>>>>>>>>>>>>>> joe.j.kearney at googlemail.com> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi Kevin, >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> It implements List, as well as Deque. It is indeed based >>>>>>>>>>>>>>>>>> on ArrayDeque, with the added operations to implement list. It does so >>>>>>>>>>>>>>>>>> reasonably efficiently, moving the fewest elements possible on each >>>>>>>>>>>>>>>>>> operation, that is zero for the queue operations, at most n/2 for the rest >>>>>>>>>>>>>>>>>> and all of them for a backing array resize. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> The idea is to get a replacement for arraylist that >>>>>>>>>>>>>>>>>> performs like arraydeque on remove(0). As a side effect, we should be able >>>>>>>>>>>>>>>>>> to get better performance on other operations by requiring fewer elements to >>>>>>>>>>>>>>>>>> be moved. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Thanks, >>>>>>>>>>>>>>>>>> Joe >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> 2010/4/14 Kevin L. Stern >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi Joe, >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> I was referring to the ChunkedArrayList when I stated >>>>>>>>>>>>>>>>>>> that add does not amortize to constant time when the data structure employs >>>>>>>>>>>>>>>>>>> the circular list trick to achieve deque behavior; ChunkedArrayList >>>>>>>>>>>>>>>>>>> potentially resizes every n^(1/2) operations. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Regarding your CircularArrayList, does it differ from >>>>>>>>>>>>>>>>>>> Java's ArrayDeque? I took only a cursory look at it, so please understand >>>>>>>>>>>>>>>>>>> if I have missed your reason for creating CircularArrayList altogether. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Kevin >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Tue, Apr 13, 2010 at 6:52 AM, Joe Kearney < >>>>>>>>>>>>>>>>>>> joe.j.kearney at googlemail.com> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi Kevin, Martin, >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> To add another discussion point, I've been writing a >>>>>>>>>>>>>>>>>>>> draft/proof-of-concept of retrofitting the List interface onto ArrayDeque. >>>>>>>>>>>>>>>>>>>> This works over the raw array, it doesn't use the fancier structures being >>>>>>>>>>>>>>>>>>>> discussed elsewhere on this list that deal with splitting huge arrays into >>>>>>>>>>>>>>>>>>>> arraylets, or that provide for O(1) insert in the middle. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> http://code.google.com/p/libjoe/source/browse/trunk/src/joe/collect/CircularArrayList.java >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> I'd be interested if you have any comments in the >>>>>>>>>>>>>>>>>>>> context of this discussion. The code is not entirely ready yet, a couple of >>>>>>>>>>>>>>>>>>>> tests fail (6/789) because of a corner case I haven't nailed yet, but the >>>>>>>>>>>>>>>>>>>> idea is there at least. I'd like to add array shrinking later, when the size >>>>>>>>>>>>>>>>>>>> dips below capacity*0.4 perhaps, to avoid flickering up and down around... >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Tests show performance to be close to ArrayList for the >>>>>>>>>>>>>>>>>>>> O(1) operations. Timings for indexed reads and writes showed >>>>>>>>>>>>>>>>>>>> no discernible difference between implementations last time I ran the >>>>>>>>>>>>>>>>>>>> tests. I don't understand at the moment why the iterator add at index >>>>>>>>>>>>>>>>>>>> size/3, size/2 perform 30% slower than ArrayList on smaller lists, nor the >>>>>>>>>>>>>>>>>>>> dodgy numbers for ArrayList.insert(5), I'll look at this soon. Those >>>>>>>>>>>>>>>>>>>> operations that become O(1) in a circular implementation (that are >>>>>>>>>>>>>>>>>>>> implemented and tested here) are faster than in ArrayList. Insert/remove in >>>>>>>>>>>>>>>>>>>> the middle are somewhat faster than ArrayList because we only have to copy >>>>>>>>>>>>>>>>>>>> at most half of the elements, except when resizing the array. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Kevin, I don't fully understand your point about not >>>>>>>>>>>>>>>>>>>> amortizing to O(1). Certainly that's true for insert not at head or tail. >>>>>>>>>>>>>>>>>>>> Otherwise this implementation only moves array elements to the front on an >>>>>>>>>>>>>>>>>>>> array resize operation which happens every O(ln n) operations at most, if we >>>>>>>>>>>>>>>>>>>> do lots of adds, maybe a little more if we add array shrinking too. This is >>>>>>>>>>>>>>>>>>>> the same as ArrayList. Are you just referring to the add-in-the-middle case? >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Some performance results below, code for these is in the >>>>>>>>>>>>>>>>>>>> repository above too. This was the second run, after a warmup. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Thanks, >>>>>>>>>>>>>>>>>>>> Joe >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> ------------------------------------------------ >>>>>>>>>>>>>>>>>>>> CircularArrayList ------------------------------------------------ >>>>>>>>>>>>>>>>>>>> size add get set iterAdd/3 >>>>>>>>>>>>>>>>>>>> iterAdd/2 insert(5) removeRnd removeMid remove(0) >>>>>>>>>>>>>>>>>>>> 10 20 67 70 125 >>>>>>>>>>>>>>>>>>>> 102 90 240 191 138 >>>>>>>>>>>>>>>>>>>> 100 19 67 70 166 >>>>>>>>>>>>>>>>>>>> 138 94 230 194 118 >>>>>>>>>>>>>>>>>>>> 1000 28 64 67 681 >>>>>>>>>>>>>>>>>>>> 538 91 324 382 119 >>>>>>>>>>>>>>>>>>>> 10000 30 65 67 5884 >>>>>>>>>>>>>>>>>>>> 4425 94 1296 2330 124 >>>>>>>>>>>>>>>>>>>> ---------------------------------------------------- >>>>>>>>>>>>>>>>>>>> ArrayList ---------------------------------------------------- >>>>>>>>>>>>>>>>>>>> size add get set iterAdd/3 >>>>>>>>>>>>>>>>>>>> iterAdd/2 insert(5) removeRnd removeMid remove(0) >>>>>>>>>>>>>>>>>>>> 10 23 68 70 100 >>>>>>>>>>>>>>>>>>>> 69 32913 162 130 105 >>>>>>>>>>>>>>>>>>>> 100 20 67 70 129 >>>>>>>>>>>>>>>>>>>> 104 21944 169 134 135 >>>>>>>>>>>>>>>>>>>> 1000 29 63 67 651 >>>>>>>>>>>>>>>>>>>> 506 9602 364 333 526 >>>>>>>>>>>>>>>>>>>> 10000 30 63 66 5878 >>>>>>>>>>>>>>>>>>>> 4414 9947 2312 2280 4437 >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> 2010/4/13 Kevin L. Stern >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi Martin, >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> I had intended to address your request for absolute >>>>>>>>>>>>>>>>>>>>> O(1) operations in the previous email. The approach to achieving this >>>>>>>>>>>>>>>>>>>>> suggested in [Brodnik99resizablearrays] is tantamount to making ArrayList >>>>>>>>>>>>>>>>>>>>> operations absolute O(1) by keeping around an array of size (3/2)*n and >>>>>>>>>>>>>>>>>>>>> filling it with a constant number of entries from the main array each time >>>>>>>>>>>>>>>>>>>>> add is called. Although this distributes the work done during a resize >>>>>>>>>>>>>>>>>>>>> across the n operations required to enter a resize-required state, it is at >>>>>>>>>>>>>>>>>>>>> the expense of additional memory usage and slower add operations. My >>>>>>>>>>>>>>>>>>>>> thought is that this would be a fine approach for a real-time application >>>>>>>>>>>>>>>>>>>>> that requires hard guarantees on performance but would be a liability in so >>>>>>>>>>>>>>>>>>>>> many Java applications that do not require these hard guarantees. I look >>>>>>>>>>>>>>>>>>>>> forward to hearing your thoughts on the matter, though. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Kevin >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> On Tue, Apr 13, 2010 at 6:18 AM, Kevin L. Stern < >>>>>>>>>>>>>>>>>>>>> kevin.l.stern at gmail.com> wrote: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Hi Martin, >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> It's interesting to note that the old circular list >>>>>>>>>>>>>>>>>>>>>> trick will not suffice to turn this data structure into a deque since we >>>>>>>>>>>>>>>>>>>>>> might be copying all n elements back to the front = 0 position every n^(1/2) >>>>>>>>>>>>>>>>>>>>>> operations (add wouldn't amortize to O(1)). We could use the old two stacks >>>>>>>>>>>>>>>>>>>>>> trick (push elements onto one stack, flip (the bottom) half (of) the >>>>>>>>>>>>>>>>>>>>>> elements to the 'other' stack when the 'other' stack becomes empty), >>>>>>>>>>>>>>>>>>>>>> mentioned in [Brodnik99resizablearrays], but I find this to be a bit CS >>>>>>>>>>>>>>>>>>>>>> 101. In [Brodnik99resizablearrays] the authors suggest a method for making >>>>>>>>>>>>>>>>>>>>>> all blocks roughly the same size, allowing us to expand/shrink capacity at >>>>>>>>>>>>>>>>>>>>>> the beginning or the end; this is the approach that I will take to create a >>>>>>>>>>>>>>>>>>>>>> deque. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> The FAQ for the Sun Contributor Agreement Q3 ( >>>>>>>>>>>>>>>>>>>>>> http://www.sun.com/software/opensource/contributor_agreement.jsp#sa_3) >>>>>>>>>>>>>>>>>>>>>> indicates that one should check with the project to determine where the SCA >>>>>>>>>>>>>>>>>>>>>> should be sent. Do you know where I would find this information? >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Kevin >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> @MISC{Brodnik99resizablearrays, >>>>>>>>>>>>>>>>>>>>>> author = {Andrej Brodnik and Svante Carlsson and >>>>>>>>>>>>>>>>>>>>>> Erik D. Demaine and J. Ian Munro and Robert Sedgewick}, >>>>>>>>>>>>>>>>>>>>>> title = {Resizable Arrays in Optimal Time and >>>>>>>>>>>>>>>>>>>>>> Space}, >>>>>>>>>>>>>>>>>>>>>> year = {1999} >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> On Sun, Apr 11, 2010 at 4:17 PM, Martin Buchholz < >>>>>>>>>>>>>>>>>>>>>> martinrb at google.com> wrote: >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Hi Kevin, >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Thanks for your continuing work on this. >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> I like the test results, and agree with your >>>>>>>>>>>>>>>>>>>>>>> analysis. >>>>>>>>>>>>>>>>>>>>>>> I'm especially happy that you're beating >>>>>>>>>>>>>>>>>>>>>>> ArrayList at some operations. >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> I'd like to see O(1) addition at the beginning, >>>>>>>>>>>>>>>>>>>>>>> implement both List and Deque (I regret >>>>>>>>>>>>>>>>>>>>>>> our not having done this with ArrayDeque). >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> An additional property that would be nice to >>>>>>>>>>>>>>>>>>>>>>> have (but don't try too hard) >>>>>>>>>>>>>>>>>>>>>>> is to provide some kind of real-time >>>>>>>>>>>>>>>>>>>>>>> guarantees on the cost of an individual operation, >>>>>>>>>>>>>>>>>>>>>>> not just amortized time. E.g. ArrayList.add >>>>>>>>>>>>>>>>>>>>>>> is worst-case O(n), making it unsuitable for use >>>>>>>>>>>>>>>>>>>>>>> in some real-time applications. >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> I will help get your changes into the obvious >>>>>>>>>>>>>>>>>>>>>>> software distributions. I assume you're happy >>>>>>>>>>>>>>>>>>>>>>> with having this class included in any of >>>>>>>>>>>>>>>>>>>>>>> Doug Lea's jsr166, guava-libraries, or the JDK >>>>>>>>>>>>>>>>>>>>>>> itself. >>>>>>>>>>>>>>>>>>>>>>> You should sign a Sun contributor agreement, >>>>>>>>>>>>>>>>>>>>>>> or whatever the Oracle equivalent is, >>>>>>>>>>>>>>>>>>>>>>> if you have not done so yet. >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Doug Lea likes public domain, >>>>>>>>>>>>>>>>>>>>>>> guava-libraries likes the Apache license. >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> We should get various people a chance to give >>>>>>>>>>>>>>>>>>>>>>> a thumbs up on the design of this class - >>>>>>>>>>>>>>>>>>>>>>> Doug Lea, Josh Bloch. >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Martin >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> On Sun, Apr 11, 2010 at 09:32, Kevin L. Stern < >>>>>>>>>>>>>>>>>>>>>>> kevin.l.stern at gmail.com> wrote: >>>>>>>>>>>>>>>>>>>>>>> > Hello Martin, >>>>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>>>> > I spent some time this weekend trying to bring out >>>>>>>>>>>>>>>>>>>>>>> bugs in the >>>>>>>>>>>>>>>>>>>>>>> > implementation; I believe the latest version to be >>>>>>>>>>>>>>>>>>>>>>> in decent shape. I have >>>>>>>>>>>>>>>>>>>>>>> > also gathered some data on the performance of >>>>>>>>>>>>>>>>>>>>>>> ChunkedArrayList over >>>>>>>>>>>>>>>>>>>>>>> > ArrayList using the latest 1.6 JDK, which I've >>>>>>>>>>>>>>>>>>>>>>> included below (note that the >>>>>>>>>>>>>>>>>>>>>>> > numbers represent the time spent performing the >>>>>>>>>>>>>>>>>>>>>>> specified operation with >>>>>>>>>>>>>>>>>>>>>>> > ChunkedArrayList over the time spent with >>>>>>>>>>>>>>>>>>>>>>> ArrayList, so 1.00 indicates >>>>>>>>>>>>>>>>>>>>>>> > equivalent performance, < 1.00 indicates that >>>>>>>>>>>>>>>>>>>>>>> ChunkedArrayList is less >>>>>>>>>>>>>>>>>>>>>>> > costly and > 1.00 indicates that ArrayList is less >>>>>>>>>>>>>>>>>>>>>>> costly). I've noticed >>>>>>>>>>>>>>>>>>>>>>> > relatively significant variability in a few of the >>>>>>>>>>>>>>>>>>>>>>> numbers when I switch >>>>>>>>>>>>>>>>>>>>>>> > hardware; though, these data do seem to represent >>>>>>>>>>>>>>>>>>>>>>> rough performance >>>>>>>>>>>>>>>>>>>>>>> > expectations. For my test I generated x elements >>>>>>>>>>>>>>>>>>>>>>> and then timed the process >>>>>>>>>>>>>>>>>>>>>>> > of adding them to ArrayList/ChunkedArrayList, then >>>>>>>>>>>>>>>>>>>>>>> I performed a get >>>>>>>>>>>>>>>>>>>>>>> > operation on each for indices 0 through x-1 and >>>>>>>>>>>>>>>>>>>>>>> finally I used the iterator >>>>>>>>>>>>>>>>>>>>>>> > mechanism to retrieve the first through xth element >>>>>>>>>>>>>>>>>>>>>>> (of course, I performed >>>>>>>>>>>>>>>>>>>>>>> > each of these operations multiple times throwing >>>>>>>>>>>>>>>>>>>>>>> away the timing for the >>>>>>>>>>>>>>>>>>>>>>> > first few iterations to warm up the JVM). >>>>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>>>> > Regarding the question of whether or not this >>>>>>>>>>>>>>>>>>>>>>> belongs in java.util, I would >>>>>>>>>>>>>>>>>>>>>>> > suggest that if it is desirable from a GC point of >>>>>>>>>>>>>>>>>>>>>>> view to eliminate the >>>>>>>>>>>>>>>>>>>>>>> > large backing array from ArrayList then your >>>>>>>>>>>>>>>>>>>>>>> suggestion of achieving this by >>>>>>>>>>>>>>>>>>>>>>> > way of a data structure that is both time and space >>>>>>>>>>>>>>>>>>>>>>> optimal is a >>>>>>>>>>>>>>>>>>>>>>> > particularly elegant solution as it not only >>>>>>>>>>>>>>>>>>>>>>> guarantees that no backing >>>>>>>>>>>>>>>>>>>>>>> > array will be larger than sqrt(n) elements but it >>>>>>>>>>>>>>>>>>>>>>> also provides dynamic >>>>>>>>>>>>>>>>>>>>>>> > shrinking behavior, has less maximum memory >>>>>>>>>>>>>>>>>>>>>>> overhead than ArrayList, and >>>>>>>>>>>>>>>>>>>>>>> > copies (asymptotically) fewer elements during a >>>>>>>>>>>>>>>>>>>>>>> resize than ArrayList. Of >>>>>>>>>>>>>>>>>>>>>>> > course, this data structure does not do everything >>>>>>>>>>>>>>>>>>>>>>> better than ArrayList; in >>>>>>>>>>>>>>>>>>>>>>> > particular, indexed access is more costly, due to >>>>>>>>>>>>>>>>>>>>>>> the required decomposition >>>>>>>>>>>>>>>>>>>>>>> > of the index into backing array index and offset >>>>>>>>>>>>>>>>>>>>>>> and the additional memory >>>>>>>>>>>>>>>>>>>>>>> > indirection, and insertion-at-an-index is more >>>>>>>>>>>>>>>>>>>>>>> costly, due to the multiple >>>>>>>>>>>>>>>>>>>>>>> > array copies necessary to complete the shift. That >>>>>>>>>>>>>>>>>>>>>>> being said, I think that >>>>>>>>>>>>>>>>>>>>>>> > the additional cost of indexed access is partially >>>>>>>>>>>>>>>>>>>>>>> mitigated by the >>>>>>>>>>>>>>>>>>>>>>> > availability of iterator and listIterator, whose >>>>>>>>>>>>>>>>>>>>>>> implementations do not use >>>>>>>>>>>>>>>>>>>>>>> > the index decomposition procedure, and the >>>>>>>>>>>>>>>>>>>>>>> additional cost of >>>>>>>>>>>>>>>>>>>>>>> > insertion-at-an-index is partially mitigated by the >>>>>>>>>>>>>>>>>>>>>>> fact that >>>>>>>>>>>>>>>>>>>>>>> > insertion-at-an-index is already an undesirable >>>>>>>>>>>>>>>>>>>>>>> operation on ArrayList due >>>>>>>>>>>>>>>>>>>>>>> > to its linear time complexity. >>>>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>>>> > Kevin >>>>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>>>> > 1000000 elements: >>>>>>>>>>>>>>>>>>>>>>> > Client JVM: >>>>>>>>>>>>>>>>>>>>>>> > Add to ChunkedArrayList over ArrayList: 1.30 >>>>>>>>>>>>>>>>>>>>>>> > Indexed access ChunkedArrayList over ArrayList: >>>>>>>>>>>>>>>>>>>>>>> 1.80 >>>>>>>>>>>>>>>>>>>>>>> > Iterator ChunkedArrayList over ArrayList: 0.52 >>>>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>>>> > Server JVM: >>>>>>>>>>>>>>>>>>>>>>> > Add to ChunkedArrayList over ArrayList: 0.81 >>>>>>>>>>>>>>>>>>>>>>> > Indexed access ChunkedArrayList over ArrayList: >>>>>>>>>>>>>>>>>>>>>>> 2.87 >>>>>>>>>>>>>>>>>>>>>>> > Iterator ChunkedArrayList over ArrayList: 1.31 >>>>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>>>> > 100000 elements: >>>>>>>>>>>>>>>>>>>>>>> > Client JVM: >>>>>>>>>>>>>>>>>>>>>>> > Add to ChunkedArrayList over ArrayList: 0.96 >>>>>>>>>>>>>>>>>>>>>>> > Indexed access ChunkedArrayList over ArrayList: >>>>>>>>>>>>>>>>>>>>>>> 1.86 >>>>>>>>>>>>>>>>>>>>>>> > Iterator ChunkedArrayList over ArrayList: 0.48 >>>>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>>>> > Server JVM: >>>>>>>>>>>>>>>>>>>>>>> > Add to ChunkedArrayList over ArrayList: 0.96 >>>>>>>>>>>>>>>>>>>>>>> > Indexed access ChunkedArrayList over ArrayList: >>>>>>>>>>>>>>>>>>>>>>> 1.89 >>>>>>>>>>>>>>>>>>>>>>> > Iterator ChunkedArrayList over ArrayList: 2.68 >>>>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>>>> > 10000 elements: >>>>>>>>>>>>>>>>>>>>>>> > Client JVM: >>>>>>>>>>>>>>>>>>>>>>> > Add to ChunkedArrayList over ArrayList: 1.04 >>>>>>>>>>>>>>>>>>>>>>> > Indexed access ChunkedArrayList over ArrayList: >>>>>>>>>>>>>>>>>>>>>>> 2.33 >>>>>>>>>>>>>>>>>>>>>>> > Iterator ChunkedArrayList over ArrayList: 0.53 >>>>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>>>> > Server JVM: >>>>>>>>>>>>>>>>>>>>>>> > Add to ChunkedArrayList over ArrayList: 0.97 >>>>>>>>>>>>>>>>>>>>>>> > Indexed access ChunkedArrayList over ArrayList: >>>>>>>>>>>>>>>>>>>>>>> 2.45 >>>>>>>>>>>>>>>>>>>>>>> > Iterator ChunkedArrayList over ArrayList: 2.52 >>>>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>>>> > 1000 elements: >>>>>>>>>>>>>>>>>>>>>>> > Client JVM: >>>>>>>>>>>>>>>>>>>>>>> > Add to ChunkedArrayList over ArrayList: 0.99 >>>>>>>>>>>>>>>>>>>>>>> > Indexed access ChunkedArrayList over ArrayList: >>>>>>>>>>>>>>>>>>>>>>> 2.27 >>>>>>>>>>>>>>>>>>>>>>> > Iterator ChunkedArrayList over ArrayList: 0.54 >>>>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>>>> > Server JVM: >>>>>>>>>>>>>>>>>>>>>>> > Add to ChunkedArrayList over ArrayList: 0.84 >>>>>>>>>>>>>>>>>>>>>>> > Indexed access ChunkedArrayList over ArrayList: >>>>>>>>>>>>>>>>>>>>>>> 1.23 >>>>>>>>>>>>>>>>>>>>>>> > Iterator ChunkedArrayList over ArrayList: 1.11 >>>>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>>>> > On Fri, Apr 9, 2010 at 7:42 PM, Martin Buchholz < >>>>>>>>>>>>>>>>>>>>>>> martinrb at google.com> wrote: >>>>>>>>>>>>>>>>>>>>>>> >> >>>>>>>>>>>>>>>>>>>>>>> >> My feeling on whether to support O(1) at both ends >>>>>>>>>>>>>>>>>>>>>>> >> is that any flavor of this that ends up in the JDK >>>>>>>>>>>>>>>>>>>>>>> eventually >>>>>>>>>>>>>>>>>>>>>>> >> should really do this. My idea is that we can >>>>>>>>>>>>>>>>>>>>>>> >> wholeheartedly recommend this collection class >>>>>>>>>>>>>>>>>>>>>>> >> for overall good behavior without any of the >>>>>>>>>>>>>>>>>>>>>>> surprising >>>>>>>>>>>>>>>>>>>>>>> >> performance traps of existing collection classes. >>>>>>>>>>>>>>>>>>>>>>> >> >>>>>>>>>>>>>>>>>>>>>>> >> But for the preliminary version, it makes sense to >>>>>>>>>>>>>>>>>>>>>>> >> support only O(1) at one end, if it simplifies the >>>>>>>>>>>>>>>>>>>>>>> >> implementation. Random access will of course >>>>>>>>>>>>>>>>>>>>>>> >> be worse than ArrayList, but by how much? >>>>>>>>>>>>>>>>>>>>>>> >> We can do some benchmarking and look for >>>>>>>>>>>>>>>>>>>>>>> >> micro-optimizations now. >>>>>>>>>>>>>>>>>>>>>>> >> >>>>>>>>>>>>>>>>>>>>>>> >> Kevin, what is you own personal feeling? >>>>>>>>>>>>>>>>>>>>>>> >> Is the algorithm correct, and efficient enough? >>>>>>>>>>>>>>>>>>>>>>> >> Do you think your new collection belongs in >>>>>>>>>>>>>>>>>>>>>>> java.util? >>>>>>>>>>>>>>>>>>>>>>> >> >>>>>>>>>>>>>>>>>>>>>>> >> Martin >>>>>>>>>>>>>>>>>>>>>>> >> >>>>>>>>>>>>>>>>>>>>>>> >> On Sun, Apr 4, 2010 at 04:12, Kevin L. Stern < >>>>>>>>>>>>>>>>>>>>>>> kevin.l.stern at gmail.com> >>>>>>>>>>>>>>>>>>>>>>> >> wrote: >>>>>>>>>>>>>>>>>>>>>>> >> > The data structure is available at the second >>>>>>>>>>>>>>>>>>>>>>> link that I originally >>>>>>>>>>>>>>>>>>>>>>> >> > provided (once again, it is >>>>>>>>>>>>>>>>>>>>>>> >> > >>>>>>>>>>>>>>>>>>>>>>> >> > >>>>>>>>>>>>>>>>>>>>>>> https://docs.google.com/Doc?docid=0Aabrz3MPBDdhZGdrbnEzejdfM2M3am5wM2Mz&hl=en >>>>>>>>>>>>>>>>>>>>>>> ). >>>>>>>>>>>>>>>>>>>>>>> >> > This does not have O(1) time insertion at the >>>>>>>>>>>>>>>>>>>>>>> front as yet as it was >>>>>>>>>>>>>>>>>>>>>>> >> > unclear >>>>>>>>>>>>>>>>>>>>>>> >> > to me whether or not it was agreed upon: >>>>>>>>>>>>>>>>>>>>>>> >> > _________________ >>>>>>>>>>>>>>>>>>>>>>> >> > From: Osvaldo Doederlein >>>>>>>>>>>>>>>>>>>>>>> >> > Date: Mon, Mar 29, 2010 at 10:08 AM >>>>>>>>>>>>>>>>>>>>>>> >> > Subject: Re: A List implementation backed by >>>>>>>>>>>>>>>>>>>>>>> multiple small arrays >>>>>>>>>>>>>>>>>>>>>>> >> > rather >>>>>>>>>>>>>>>>>>>>>>> >> > than the traditional single large array. >>>>>>>>>>>>>>>>>>>>>>> >> > To: Martin Buchholz >>>>>>>>>>>>>>>>>>>>>>> >> > Cc: "Kevin L. Stern" , >>>>>>>>>>>>>>>>>>>>>>> >> > core-libs-dev at openjdk.java.net >>>>>>>>>>>>>>>>>>>>>>> >> > >>>>>>>>>>>>>>>>>>>>>>> >> > Initially, it would be good enough to replace >>>>>>>>>>>>>>>>>>>>>>> only java.util.ArrayList >>>>>>>>>>>>>>>>>>>>>>> >> > with >>>>>>>>>>>>>>>>>>>>>>> >> > minimal overhead. ArrayList does not support >>>>>>>>>>>>>>>>>>>>>>> efficient add-at-front or >>>>>>>>>>>>>>>>>>>>>>> >> > other >>>>>>>>>>>>>>>>>>>>>>> >> > enhancements of ArrayDeque; but ArrayList is >>>>>>>>>>>>>>>>>>>>>>> still a much more important >>>>>>>>>>>>>>>>>>>>>>> >> > and >>>>>>>>>>>>>>>>>>>>>>> >> > popular collection, it's the primary "straight >>>>>>>>>>>>>>>>>>>>>>> replacement for primitive >>>>>>>>>>>>>>>>>>>>>>> >> > arrrays" and I guess it should continue with >>>>>>>>>>>>>>>>>>>>>>> that role. >>>>>>>>>>>>>>>>>>>>>>> >> > _________________ >>>>>>>>>>>>>>>>>>>>>>> >> > >>>>>>>>>>>>>>>>>>>>>>> >> > As a disclaimer, I'm still tinkering with this >>>>>>>>>>>>>>>>>>>>>>> so I'll be updating the >>>>>>>>>>>>>>>>>>>>>>> >> > document at the provided link as I find >>>>>>>>>>>>>>>>>>>>>>> improvements. >>>>>>>>>>>>>>>>>>>>>>> >> > >>>>>>>>>>>>>>>>>>>>>>> >> > Thoughts? >>>>>>>>>>>>>>>>>>>>>>> >> > >>>>>>>>>>>>>>>>>>>>>>> >> > Thanks, >>>>>>>>>>>>>>>>>>>>>>> >> > >>>>>>>>>>>>>>>>>>>>>>> >> > Kevin >>>>>>>>>>>>>>>>>>>>>>> >> > >>>>>>>>>>>>>>>>>>>>>>> >> > On Thu, Apr 1, 2010 at 10:28 PM, Martin Buchholz >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >> > wrote: >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>>>>>>>>>>>>>>>>>>>>> >> >> Hi Kevin, >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>>>>>>>>>>>>>>>>>>>>> >> >> You're probably the only one on this list who >>>>>>>>>>>>>>>>>>>>>>> has >>>>>>>>>>>>>>>>>>>>>>> >> >> seriously read the paper. It is not surprising >>>>>>>>>>>>>>>>>>>>>>> that >>>>>>>>>>>>>>>>>>>>>>> >> >> taking a research paper into production would >>>>>>>>>>>>>>>>>>>>>>> >> >> discover bugs - the research never had to >>>>>>>>>>>>>>>>>>>>>>> undergo >>>>>>>>>>>>>>>>>>>>>>> >> >> rigorous testing. (I like the Java culture of >>>>>>>>>>>>>>>>>>>>>>> >> >> combining spec + implementation + test suite) >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>>>>>>>>>>>>>>>>>>>>> >> >> I suggest you ask the authors directly about >>>>>>>>>>>>>>>>>>>>>>> the bug. >>>>>>>>>>>>>>>>>>>>>>> >> >> They would probably also be interested to hear >>>>>>>>>>>>>>>>>>>>>>> >> >> about your implementation. >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>>>>>>>>>>>>>>>>>>>>> >> >> Are you aware of Integer.numberOfLeadingZeros? >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>>>>>>>>>>>>>>>>>>>>> http://download.java.net/jdk7/docs/api/java/lang/Integer.html#numberOfLeadingZeros(int) >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>>>>>>>>>>>>>>>>>>>>> >> >> Martin >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>>>>>>>>>>>>>>>>>>>>> >> >> On Wed, Mar 31, 2010 at 19:34, Kevin L. Stern < >>>>>>>>>>>>>>>>>>>>>>> kevin.l.stern at gmail.com> >>>>>>>>>>>>>>>>>>>>>>> >> >> wrote: >>>>>>>>>>>>>>>>>>>>>>> >> >> > I'm almost convinced now that the paper is >>>>>>>>>>>>>>>>>>>>>>> incorrect. The code below >>>>>>>>>>>>>>>>>>>>>>> >> >> > gives >>>>>>>>>>>>>>>>>>>>>>> >> >> > me the appropriate index into the index array >>>>>>>>>>>>>>>>>>>>>>> and the offset into the >>>>>>>>>>>>>>>>>>>>>>> >> >> > data >>>>>>>>>>>>>>>>>>>>>>> >> >> > block. That being said, remember when I >>>>>>>>>>>>>>>>>>>>>>> mentioned that this will >>>>>>>>>>>>>>>>>>>>>>> >> >> > include a >>>>>>>>>>>>>>>>>>>>>>> >> >> > bit more work to access an element than a >>>>>>>>>>>>>>>>>>>>>>> simple bit shift and a bit >>>>>>>>>>>>>>>>>>>>>>> >> >> > mask? >>>>>>>>>>>>>>>>>>>>>>> >> >> > Well this is more than a bit more - we'll be >>>>>>>>>>>>>>>>>>>>>>> doing this each time an >>>>>>>>>>>>>>>>>>>>>>> >> >> > index >>>>>>>>>>>>>>>>>>>>>>> >> >> > is requested. I'll spend some time trying to >>>>>>>>>>>>>>>>>>>>>>> twiddle the bits to see >>>>>>>>>>>>>>>>>>>>>>> >> >> > if >>>>>>>>>>>>>>>>>>>>>>> >> >> > I >>>>>>>>>>>>>>>>>>>>>>> >> >> > can eliminate/combine some of the operations. >>>>>>>>>>>>>>>>>>>>>>> >> >> > >>>>>>>>>>>>>>>>>>>>>>> >> >> > for (int r = 1; r < 33; r++) { >>>>>>>>>>>>>>>>>>>>>>> >> >> > int k = lg(r); >>>>>>>>>>>>>>>>>>>>>>> >> >> > int floorKO2 = k >> 1; >>>>>>>>>>>>>>>>>>>>>>> >> >> > int powFloorKO2 = (1 << >>>>>>>>>>>>>>>>>>>>>>> floorKO2); >>>>>>>>>>>>>>>>>>>>>>> >> >> > int p = ((1 << floorKO2) - 1) << >>>>>>>>>>>>>>>>>>>>>>> 1; >>>>>>>>>>>>>>>>>>>>>>> >> >> > int ceilKO2; >>>>>>>>>>>>>>>>>>>>>>> >> >> > if ((k & 1) == 1) { >>>>>>>>>>>>>>>>>>>>>>> >> >> > ceilKO2 = floorKO2 + 1; >>>>>>>>>>>>>>>>>>>>>>> >> >> > p += powFloorKO2; >>>>>>>>>>>>>>>>>>>>>>> >> >> > } else { >>>>>>>>>>>>>>>>>>>>>>> >> >> > ceilKO2 = floorKO2; >>>>>>>>>>>>>>>>>>>>>>> >> >> > } >>>>>>>>>>>>>>>>>>>>>>> >> >> > int e = r & ((1 << ceilKO2) - 1); >>>>>>>>>>>>>>>>>>>>>>> >> >> > int b = (r >> ceilKO2) & >>>>>>>>>>>>>>>>>>>>>>> (powFloorKO2 - 1); >>>>>>>>>>>>>>>>>>>>>>> >> >> > >>>>>>>>>>>>>>>>>>>>>>> >> >> > System.out.println((r - 1) + " " >>>>>>>>>>>>>>>>>>>>>>> + (p + b) + " " + e); >>>>>>>>>>>>>>>>>>>>>>> >> >> > } >>>>>>>>>>>>>>>>>>>>>>> >> >> > >>>>>>>>>>>>>>>>>>>>>>> >> >> > Kevin >>>>>>>>>>>>>>>>>>>>>>> >> >> > >>>>>>>>>>>>>>>>>>>>>>> >> >> > On Wed, Mar 31, 2010 at 7:08 PM, Kevin L. >>>>>>>>>>>>>>>>>>>>>>> Stern >>>>>>>>>>>>>>>>>>>>>>> >> >> > >>>>>>>>>>>>>>>>>>>>>>> >> >> > wrote: >>>>>>>>>>>>>>>>>>>>>>> >> >> >> >>>>>>>>>>>>>>>>>>>>>>> >> >> >> I realize that 2 * (2^(k/2) - 1) only works >>>>>>>>>>>>>>>>>>>>>>> for even numbered >>>>>>>>>>>>>>>>>>>>>>> >> >> >> superblocks, >>>>>>>>>>>>>>>>>>>>>>> >> >> >> the odd numbered superblocks need an >>>>>>>>>>>>>>>>>>>>>>> additional term added (the >>>>>>>>>>>>>>>>>>>>>>> >> >> >> number >>>>>>>>>>>>>>>>>>>>>>> >> >> >> of >>>>>>>>>>>>>>>>>>>>>>> >> >> >> data blocks in SB_[k-1]) to jive with my >>>>>>>>>>>>>>>>>>>>>>> interpretation; anyhow, I >>>>>>>>>>>>>>>>>>>>>>> >> >> >> also >>>>>>>>>>>>>>>>>>>>>>> >> >> >> came >>>>>>>>>>>>>>>>>>>>>>> >> >> >> across an alternative characterization of >>>>>>>>>>>>>>>>>>>>>>> superblock in the paper >>>>>>>>>>>>>>>>>>>>>>> >> >> >> which >>>>>>>>>>>>>>>>>>>>>>> >> >> >> states that data blocks are grouped within a >>>>>>>>>>>>>>>>>>>>>>> superblock when they >>>>>>>>>>>>>>>>>>>>>>> >> >> >> are >>>>>>>>>>>>>>>>>>>>>>> >> >> >> the >>>>>>>>>>>>>>>>>>>>>>> >> >> >> same size - to me, though, that implies that >>>>>>>>>>>>>>>>>>>>>>> my example structure >>>>>>>>>>>>>>>>>>>>>>> >> >> >> below >>>>>>>>>>>>>>>>>>>>>>> >> >> >> would be >>>>>>>>>>>>>>>>>>>>>>> >> >> >> >>>>>>>>>>>>>>>>>>>>>>> >> >> >> SB_0: [1] >>>>>>>>>>>>>>>>>>>>>>> >> >> >> SB_1: [2][2][2] >>>>>>>>>>>>>>>>>>>>>>> >> >> >> SB_2: [4][4][4][4][4][4] >>>>>>>>>>>>>>>>>>>>>>> >> >> >> >>>>>>>>>>>>>>>>>>>>>>> >> >> >> which seems to contradict my understanding >>>>>>>>>>>>>>>>>>>>>>> of (1) below. I must be >>>>>>>>>>>>>>>>>>>>>>> >> >> >> reading this upside down. >>>>>>>>>>>>>>>>>>>>>>> >> >> >> >>>>>>>>>>>>>>>>>>>>>>> >> >> >> On Wed, Mar 31, 2010 at 6:36 PM, Kevin L. >>>>>>>>>>>>>>>>>>>>>>> Stern >>>>>>>>>>>>>>>>>>>>>>> >> >> >> >>>>>>>>>>>>>>>>>>>>>>> >> >> >> wrote: >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> What am I missing here? In "Resizable >>>>>>>>>>>>>>>>>>>>>>> arrays in optimal time and >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> space" >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> the authors define their data structure >>>>>>>>>>>>>>>>>>>>>>> with the following >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> property: >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> (1) "When superblock SB_k is fully >>>>>>>>>>>>>>>>>>>>>>> allocated, it consists of >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> 2^(floor(k/2)) data blocks, each of size >>>>>>>>>>>>>>>>>>>>>>> 2^(ceil(k/2))." >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> Since the superblock is zero-based indexed >>>>>>>>>>>>>>>>>>>>>>> this implies the >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> following >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> structure: >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> SB_0: [1] >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> SB_1: [2] >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> SB_2: [2][2] >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> SB_3: [4][4] >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> SB_4: [4][4][4][4] >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> [...] >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> Let's have a look at Algorithm 3, >>>>>>>>>>>>>>>>>>>>>>> Locate(i), with i = 3: >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> r = 100 (the binary expansion of i + 1) >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> k = |r| - 1 = 2 >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> p = 2^k - 1 = 3 >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> What concerns me is their statement that p >>>>>>>>>>>>>>>>>>>>>>> represents "the number >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> of >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> data >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> blocks in superblocks prior to SB_k." >>>>>>>>>>>>>>>>>>>>>>> There are only two data >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> blocks >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> in >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> superblocks prior to SB_2, not three. >>>>>>>>>>>>>>>>>>>>>>> Given (1) above, unless I'm >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> misinterpreting it, the number of data >>>>>>>>>>>>>>>>>>>>>>> blocks in superblocks prior >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> to >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> SB_k >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> should be: >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> 2 * Sum[i=0->k/2-1] 2^i = 2 * (2^(k/2) - 1) >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> This, of course, seems to work out much >>>>>>>>>>>>>>>>>>>>>>> better in my example above, >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> giving the correct answer to my >>>>>>>>>>>>>>>>>>>>>>> interpretation of their data >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> structure, but >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> I have a hard time believing that this is >>>>>>>>>>>>>>>>>>>>>>> their mistake rather than >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> my >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> misinterpretation. >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> Thoughts? >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> Kevin >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> On Tue, Mar 30, 2010 at 5:20 PM, Martin >>>>>>>>>>>>>>>>>>>>>>> Buchholz >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> wrote: >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> On Tue, Mar 30, 2010 at 04:25, Kevin L. >>>>>>>>>>>>>>>>>>>>>>> Stern >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> wrote: >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > Hi Martin, >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > Thanks much for your feedback. The >>>>>>>>>>>>>>>>>>>>>>> first approach that comes to >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > mind >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > to >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > implement O(1) time front as well as >>>>>>>>>>>>>>>>>>>>>>> rear insertion is to create >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > a >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > cyclic >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > list structure with a front/rear pointer >>>>>>>>>>>>>>>>>>>>>>> - to insert at the >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > front >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > requires >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > decrementing the front pointer (modulo >>>>>>>>>>>>>>>>>>>>>>> the size) and to insert >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > at >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > the >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > rear >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > requires incrementing the rear pointer >>>>>>>>>>>>>>>>>>>>>>> (modulo the size). We >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > need >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > to >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > resize >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > when the two pointers bump into each >>>>>>>>>>>>>>>>>>>>>>> other. Could you explain >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > more >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > about >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > your suggestion of introducing an >>>>>>>>>>>>>>>>>>>>>>> arraylet that is shared by the >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > front >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > and >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > the rear? >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> It was a half-baked idea - I don't know if >>>>>>>>>>>>>>>>>>>>>>> there's a way to turn >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> it >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> into >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> something useful. I was thinking of the >>>>>>>>>>>>>>>>>>>>>>> ArrayDeque >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> implementation, >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> where all the elements live in a single >>>>>>>>>>>>>>>>>>>>>>> array. >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > It's not clear to me how that would >>>>>>>>>>>>>>>>>>>>>>> help and/or be a better >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > approach than the cyclic list. Anyhow, >>>>>>>>>>>>>>>>>>>>>>> the paper that you >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > reference, >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > "Resizable arrays in optimal time and >>>>>>>>>>>>>>>>>>>>>>> space", gives a deque so >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > if >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > we >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > take >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> > that approach then the deque is >>>>>>>>>>>>>>>>>>>>>>> specified. >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> Technically, ArrayList also supports the >>>>>>>>>>>>>>>>>>>>>>> Deque operations - >>>>>>>>>>>>>>>>>>>>>>> >> >> >>>> just not efficiently. >>>>>>>>>>>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>>>>>>>>>>> >> >> >> >>>>>>>>>>>>>>>>>>>>>>> >> >> > >>>>>>>>>>>>>>>>>>>>>>> >> >> > >>>>>>>>>>>>>>>>>>>>>>> >> > >>>>>>>>>>>>>>>>>>>>>>> >> > >>>>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From Ulf.Zibis at gmx.de Sun May 9 16:35:39 2010 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Sun, 09 May 2010 18:35:39 +0200 Subject: Unicode script support in Regex and Character class In-Reply-To: <4BE5DC62.6020304@oracle.com> References: <4BD00250.3020206@oracle.com> <4BE5DC62.6020304@oracle.com> Message-ID: <4BE6E45B.304@gmx.de> Sherman, I don't understand, why you use so much buffering. InputStream from getResourceAsStream, and I believe InflaterInputStream too, is yet buffered. My understanding until now was, that access to buffered byte streams is as fast as to naked byte arrays. Am I wrong? -Ulf Am 08.05.2010 23:49, schrieb Xueming Shen: > Hi, > > The API proposals for Unicode script support below have been approved. > > 6945564: Unicode script support in Character class > 6948903: Make Unicode scripts available for use in regular expressions > > Here is the final webrev ready for push. > > http://cr.openjdk.java.net/~sherman/6945564_6948903/webrev > From iaroslavski at mail.ru Sun May 9 19:51:27 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Sun, 09 May 2010 23:51:27 +0400 Subject: =?koi8-r?Q?Re[2]=3A_New_portion_of_improvements_for_Dual-Pivot_Quicksort?= In-Reply-To: References: Message-ID: Josh, Dmytro, I have done more thoroughly testing "great - less > 5 * seventh" vs. "less < e1 && great > e5", and found that more symmetric code "less < e1 && great > e5" is little bit faster, ~0.5..0.7% on both VMs. Other code has not been changed. Please, take the latest version in attachment. Vladimir Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua Bloch : > Vladimir, > > Old: > >298 if (less < e1 && great > e5) { > > New: > >256 if (great - less > 5 * seventh) { >Regards, >Josh -------------- next part -------------- A non-text attachment was scrubbed... Name: DualPivotQuicksort.java Type: application/octet-stream Size: 100769 bytes Desc: not available URL: From David.Holmes at oracle.com Sun May 9 22:02:13 2010 From: David.Holmes at oracle.com (David Holmes) Date: Mon, 10 May 2010 08:02:13 +1000 Subject: A List implementation backed by multiple small arrays rather than the traditional single large array. In-Reply-To: References: <1704b7a21003280455u784d4d2ape39a47e2367b79a8@mail.gmail.com> Message-ID: <4BE730E5.2010404@oracle.com> (re-sent with previous emails trimmed to reduce size) Kevin, The difference is the use of invokeInterface vs invokeVirtual. Now, as to why those two differ so much, you'd have to ask the VM compiler guys. David Holmes Kevin L. Stern said the following on 05/09/10 23:14: > Trying to understand this: > > public static void main(String[] args) { > final NumberFormat format = new DecimalFormat("0.000000"); > final Random rng = new Random(); > final int maxSize = 100000; > final int warmup = 100; > final long[] time = new long[2]; > > for (int i = 0; i < 1000; i++) { > if (i % 3 == 0) > System.gc(); > List cad = new ChunkedArrayDeque(); > List al = new ArrayList(1); > int size = rng.nextInt(maxSize - 1) + 1; > long thisTime = System.nanoTime(); > for (int j = 0; j < size; j++) { > al.add(j); > } > if (i > warmup) > time[0] += System.nanoTime() - thisTime; > thisTime = System.nanoTime(); > for (int j = 0; j < size; j++) { > cad.add(j); > } > if (i > warmup) > time[1] += System.nanoTime() - thisTime; > } > > System.out.println(format.format((double)time[1] / time[0])); > } > > Consistently prints around 0.834112, whereas if I change > > List al = new ArrayList(1); > > to > > ArrayList al = new ArrayList(1); > > I consistently see around 0.965947. > > Any ideas why the type of the reference would make such a difference? > > Kevin From xueming.shen at oracle.com Mon May 10 01:05:59 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Sun, 09 May 2010 18:05:59 -0700 Subject: Unicode script support in Regex and Character class In-Reply-To: <4BE6E45B.304@gmx.de> References: <4BD00250.3020206@oracle.com> <4BE5DC62.6020304@oracle.com> <4BE6E45B.304@gmx.de> Message-ID: <4BE75BF7.2070508@oracle.com> Ulf, Can you be more specific? I'm not sure I understand your question. What "buffering" are we talking here? If you are referring to code below dis = new DataInputStream(new InflaterInputStream( AccessController.doPrivileged(new PrivilegedAction() { public InputStream run() { return getClass().getResourceAsStream("uniName.dat"); } }))); None of the layers added on top of the "InputStream" is for buffering purpose. -Sherman Ulf Zibis wrote: > Sherman, I don't understand, why you use so much buffering. > InputStream from getResourceAsStream, and I believe > InflaterInputStream too, is yet buffered. > > My understanding until now was, that access to buffered byte streams > is as fast as to naked byte arrays. > Am I wrong? > > -Ulf > > > Am 08.05.2010 23:49, schrieb Xueming Shen: >> Hi, >> >> The API proposals for Unicode script support below have been approved. >> >> 6945564: Unicode script support in Character class >> 6948903: Make Unicode scripts available for use in regular expressions >> >> Here is the final webrev ready for push. >> >> http://cr.openjdk.java.net/~sherman/6945564_6948903/webrev >> > From Ulf.Zibis at gmx.de Mon May 10 17:53:49 2010 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Mon, 10 May 2010 19:53:49 +0200 Subject: Unicode script support in Regex and Character class In-Reply-To: <4BE75BF7.2070508@oracle.com> References: <4BD00250.3020206@oracle.com> <4BE5DC62.6020304@oracle.com> <4BE6E45B.304@gmx.de> <4BE75BF7.2070508@oracle.com> Message-ID: <4BE8482D.70606@gmx.de> Am 10.05.2010 03:05, schrieb Xueming Shen: > > Ulf, > > Can you be more specific? I'm not sure I understand your question. > What "buffering" > are we talking here? In http://cr.openjdk.java.net/~sherman/6945564_6948903/webrev , I think byte[] ba could be saved in initNamePool(), as you could directly read from dis. In http://cr.openjdk.java.net/~sherman/script/webrev.00/: dis.readFully(pool); wordPool = new String(pool, "iso-8859-1").toCharArray(); 1st copies to pool[] 2nd copies to internal String.value[] and then 3rd again to wordPool. You could: do { wordPool[i++] = (char)dis.read(); } dis.readFully(head); dis.readFully(index); startCP = dHead.readInt(); numCP = dHead.readShort() & 0xffff; prefixOff = dIndex.readShort() & 0xffff; int len = dIndex.read() & 0xff; wordOff[off++] = (char)dIndex.readShort(); If you would fold index[] into head[], here you could also directly read the values from dis. wordOff = new char[index.length]; If you would init wordOff to it's true final size, you could save: wordOff = Arrays.copyOf(wordOff, off); Additionally I'm wondering about your love on while loops. In most cases I would prefer for loops with the concerning params defined in the for statement. -Ulf > Ulf Zibis wrote: >> Sherman, I don't understand, why you use so much buffering. >> InputStream from getResourceAsStream, and I believe >> InflaterInputStream too, is yet buffered. >> >> My understanding until now was, that access to buffered byte streams >> is as fast as to naked byte arrays. >> Am I wrong? >> >> -Ulf >> From martinrb at google.com Mon May 10 17:58:54 2010 From: martinrb at google.com (martinrb at google.com) Date: Mon, 10 May 2010 17:58:54 +0000 Subject: hg: jdk7/tl/jdk: 4 new changesets Message-ID: <20100510180010.5605E44178@hg.openjdk.java.net> Changeset: ec45423a4700 Author: martin Date: 2010-05-09 00:59 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/ec45423a4700 6933217: Huge arrays handled poorly in core libraries Summary: Write overflow-conscious array resizing code Reviewed-by: chegar ! src/share/classes/java/io/ByteArrayOutputStream.java ! src/share/classes/java/lang/AbstractStringBuilder.java ! src/share/classes/java/util/AbstractCollection.java ! src/share/classes/java/util/ArrayList.java ! src/share/classes/java/util/Hashtable.java ! src/share/classes/java/util/PriorityQueue.java ! src/share/classes/java/util/Vector.java Changeset: 0144f2fc69a3 Author: martin Date: 2010-05-09 00:59 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/0144f2fc69a3 6950540: PriorityQueue(collection) should throw NPE if collection contains a null Summary: Rewrite PriorityQueue constructors for best performance and error handling Reviewed-by: dholmes, chegar ! src/share/classes/java/util/PriorityQueue.java + test/java/util/PriorityQueue/NoNulls.java Changeset: df4d3e3e465a Author: martin Date: 2010-05-09 16:03 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/df4d3e3e465a 6937857: Concurrent calls to new Random() not random enough Summary: seed uniquifier should use an independent PRNG Reviewed-by: dl ! src/share/classes/java/util/Random.java ! test/java/util/Random/DistinctSeeds.java Changeset: ab0673a2e681 Author: martin Date: 2010-05-09 16:37 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/ab0673a2e681 6937842: Unreadable \uXXXX in javadoc Summary: Replace \uXXXX by \u005CXXXX, or simply delete Reviewed-by: sherman ! src/share/classes/java/lang/String.java ! src/share/classes/java/util/zip/Deflater.java From xueming.shen at oracle.com Mon May 10 18:10:27 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Mon, 10 May 2010 11:10:27 -0700 Subject: Unicode script support in Regex and Character class In-Reply-To: <4BE8482D.70606@gmx.de> References: <4BD00250.3020206@oracle.com> <4BE5DC62.6020304@oracle.com> <4BE6E45B.304@gmx.de> <4BE75BF7.2070508@oracle.com> <4BE8482D.70606@gmx.de> Message-ID: <4BE84C13.3000801@oracle.com> Ulf, Stuff under http://cr.openjdk.java.net/~sherman/script/webrev.00 just an idea about a smaller-size alternative It is not a intended to replace the final bits for review at http://cr.openjdk.java.net/~sherman/6945564_6948903/webrev My bad, probably I should not mixed 2 things in one email. Regarding "while" instead of "for" loop", it's because...I don't know:-) Maybe squeezing multiple variables into a "for" statement makes it more "encapsulated"? but I doubt it really matters. -Sherman Ulf Zibis wrote: > Am 10.05.2010 03:05, schrieb Xueming Shen: >> >> Ulf, >> >> Can you be more specific? I'm not sure I understand your question. >> What "buffering" >> are we talking here? > > In http://cr.openjdk.java.net/~sherman/6945564_6948903/webrev , > I think byte[] ba could be saved in initNamePool(), as you could > directly read from dis. > > In http://cr.openjdk.java.net/~sherman/script/webrev.00/: > dis.readFully(pool); > wordPool = new String(pool, "iso-8859-1").toCharArray(); > 1st copies to pool[] 2nd copies to internal String.value[] and then > 3rd again to wordPool. > You could: > do { > wordPool[i++] = (char)dis.read(); > } > > dis.readFully(head); > dis.readFully(index); > startCP = dHead.readInt(); > numCP = dHead.readShort() & 0xffff; > prefixOff = dIndex.readShort() & 0xffff; > int len = dIndex.read() & 0xff; > wordOff[off++] = (char)dIndex.readShort(); > If you would fold index[] into head[], here you could also directly > read the values from dis. > > wordOff = new char[index.length]; > If you would init wordOff to it's true final size, you could save: > wordOff = Arrays.copyOf(wordOff, off); > > Additionally I'm wondering about your love on while loops. > In most cases I would prefer for loops with the concerning params > defined in the for statement. > > -Ulf > >> Ulf Zibis wrote: >>> Sherman, I don't understand, why you use so much buffering. >>> InputStream from getResourceAsStream, and I believe >>> InflaterInputStream too, is yet buffered. >>> >>> My understanding until now was, that access to buffered byte streams >>> is as fast as to naked byte arrays. >>> Am I wrong? >>> >>> -Ulf >>> > From Ulf.Zibis at gmx.de Mon May 10 21:56:07 2010 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Mon, 10 May 2010 23:56:07 +0200 Subject: Unicode script support in Regex and Character class In-Reply-To: <4BE5DC62.6020304@oracle.com> References: <4BD00250.3020206@oracle.com> <4BE5DC62.6020304@oracle.com> Message-ID: <4BE880F7.50104@gmx.de> Some additional thoughts: - out.writeShort((short)(num & 0xffff)); ---short form---> out.writeShort((short)num); - use Arrays.binarySearch() in Character.UnicodeBlock.of(). - "if (notFirst)" could be saved if you would first append the first word to sb outside the while loop. - StringBuilder sb could be initialized by the maximum name length (=83) to avoid resizing; - we could reuse the same Stringbuilder for multiple invokations of Character.getName(cp)? -- make CharacterName.get(cp) instance method and save CharacterName object as ThreadLocal from Character.getName(cp). -- synchronize Character.getName(cp). - Instead using StringBuilder we could use ByteBuffer, omit the char[] and build the final String by new String(bb.toArray(), "ASCII"). -- saves the twice bigger char[] for the pool. -- I imagine, ByteBuffer would perform better than StringBuilder. - save UnicodeBlocks, BlockStarts and scriptStarts in a file instead statically in classfile. -- e.g. init of scriptStarts is a big waste of byte code (7/11 bytes per short/integer entry). Am 08.05.2010 23:49, schrieb Xueming Shen: > Hi, > > The API proposals for Unicode script support below have been approved. > > 6945564: Unicode script support in Character class > 6948903: Make Unicode scripts available for use in regular expressions > > (2)Testing result suggests there is not too much runtime benefit of > keeping a huge string > data pool + an access hashmap for getName() implementation. The latest > implementation now > takes Ulf's suggestion to keep a relatively small byte[] pool and > generate the names at runtime. > (there is "even smaller" implementation, which consumes about 300K > memory at runtime > http://cr.openjdk.java.net/~sherman/script/webrev.00/ > but it has a "scalability" problem need to address when string pool > grows beyond 64k and it > is little slow) I'm investigating in that. For 1st, my string pool has size of only 35243. -Ulf From mbien at fh-landshut.de Sat May 8 11:31:17 2010 From: mbien at fh-landshut.de (Michael Bien) Date: Sat, 08 May 2010 13:31:17 +0200 Subject: signal chaining and self defence Message-ID: <4BE54B85.7040000@fh-landshut.de> Hello everyone, i am one of the maintainers of JOGL and wrote JOCL (http://jogamp.org/) and we are currently facing some signal handling issues caused by the nvidia and amd drivers. (I got the hint to post to this list since there is no better alias for this kind of topics) e.g. the nvidia OpenCL driver uses at least the following handlers: Warning: SIGSEGV handler expected:libjvm.so+0x5d8cf0 found:libnvidia-compiler.so+0x1865e0 Warning: SIGILL handler expected:libjvm.so+0x5d8cf0 found:libnvidia-compiler.so+0x1865e0 Warning: SIGFPE handler expected:libjvm.so+0x5d8cf0 found:libnvidia-compiler.so+0x1865e0 Warning: SIGBUS handler expected:libjvm.so+0x5d8cf0 found:libnvidia-compiler.so+0x1865e0 Warning: SIGXFSZ handler expected:libjvm.so+0x5d8cf0 found:libnvidia-compiler.so+0x1865e0 (-Xcheck:jni) which basically makes the jvm unusable on Linux and leads to segmentation faults (in the driver, I suppose the driver catches jvm signals). LD_PRELOAD (http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/signals.html#gbzbl) works perfectly but it is not allowed for webstart + applets... do you have any advice how we could workaround this issue? The perfect solution would be a "-XX:enableSignalChaining" flag which we could set via jnlp. Since the webstart JVM is out of process anyway (since u10 or so) this would probably work. Why isn't signal chaining enabled by default on linux and solaris? It looks like a good self-defence mechanism for me :) best regards, Michael Bien --- http://michael-bien.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From David.Holmes at oracle.com Sun May 9 21:55:21 2010 From: David.Holmes at oracle.com (David Holmes) Date: Mon, 10 May 2010 07:55:21 +1000 Subject: A List implementation backed by multiple small arrays rather than the traditional single large array. In-Reply-To: References: <1704b7a21003280455u784d4d2ape39a47e2367b79a8@mail.gmail.com> Message-ID: <4BE72F49.1000708@oracle.com> Kevin, The difference is the use of invokeInterface vs invokeVirtual. Now, as to why those two differ so much, you'd have to ask the VM compiler guys. David Holmes Kevin L. Stern said the following on 05/09/10 23:14: > Trying to understand this: > > public static void main(String[] args) { > final NumberFormat format = new DecimalFormat("0.000000"); > final Random rng = new Random(); > final int maxSize = 100000; > final int warmup = 100; > final long[] time = new long[2]; > > for (int i = 0; i < 1000; i++) { > if (i % 3 == 0) > System.gc(); > List cad = new ChunkedArrayDeque(); > List al = new ArrayList(1); > int size = rng.nextInt(maxSize - 1) + 1; > long thisTime = System.nanoTime(); > for (int j = 0; j < size; j++) { > al.add(j); > } > if (i > warmup) > time[0] += System.nanoTime() - thisTime; > thisTime = System.nanoTime(); > for (int j = 0; j < size; j++) { > cad.add(j); > } > if (i > warmup) > time[1] += System.nanoTime() - thisTime; > } > > System.out.println(format.format((double)time[1] / time[0])); > } > > Consistently prints around 0.834112, whereas if I change > > List al = new ArrayList(1); > > to > > ArrayList al = new ArrayList(1); > > I consistently see around 0.965947. > > Any ideas why the type of the reference would make such a difference? > > Kevin > > On Sun, Apr 25, 2010 at 4:25 AM, Benedict Elliott Smith > > wrote: > > Wow, those numbers really are very impressive. I had to double check > against your previous statistics to confirm the direction of the > ratio... Those numbers make this data structure look like the weapon > of choice for any but the smallest of lists. > > On 24 April 2010 19:41, Kevin L. Stern > wrote: > > Hi Benedict, > > You are absolutely right - the constant on the cost of growth is > going to be higher with the new data structure. That being > said, the performance numbers that I'm getting with it are > actually quite impressive when compared to ArrayList: > > Note that all numbers are with a client VM and are generated > using the same routine that I used for the ChunkedArrayList > performance numbers. > > 1000000 elements: > > Add to ChunkedArrayDeque over ArrayList: 0.89 > Indexed access ChunkedArrayDeque over ArrayList: 0.81 > Iterator ChunkedArrayDeque over ArrayList: 0.51 > > 100000 elements: > > Add to ChunkedArrayDeque over ArrayList: 1.01 > Indexed access ChunkedArrayDeque over ArrayList: 0.79 > Iterator ChunkedArrayDeque over ArrayList: 0.50 > > 10000 elements: > > Add to ChunkedArrayDeque over ArrayList: 1.15 > Indexed access ChunkedArrayDeque over ArrayList: 1.15 > Iterator ChunkedArrayDeque over ArrayList: 0.51 > > 1000 elements: > > Add to ChunkedArrayDeque over ArrayList: 1.35 > Indexed access ChunkedArrayDeque over ArrayList: 1.12 > Iterator ChunkedArrayDeque over ArrayList: 0.54 > > Kevin > > > On Sat, Apr 24, 2010 at 1:27 PM, Benedict Elliott Smith > > wrote: > > Yes, I had spotted that benefit - but (please correct me if > I am misreading this as it is quite possible) in order to > maintain your array allocation invariant, array copies are > needed (rather than straight allocations) - and so the cost > of growth is likely to be noticeably larger. That said, if > random access is considerably quicker this might be a > sensible trade off, but perhaps there is a place for both > data structures. > > > > On 24 April 2010 19:14, Kevin L. Stern > > > wrote: > > Hi Benedict, > > Thanks, I'll definitely give this a try. I certainly > don't see any issue with skipping the size 1 array in > order to speed up general operation. > > By the way, I'm currently focused a bit more on the > deque - I'm not sure that anything is going to come of > this ChunkedArrayList on its own. With the deque, index > decomposition is much faster than any of these > implementations as it lends itself to bit operations > without the requirement of computing the logarithm. > > Kevin > > > On Sat, Apr 24, 2010 at 12:30 PM, Benedict Elliott Smith > > wrote: > > If you want a drop in replacement with minimal fuss > to test it out, try below (although it's a quick > hack of including the Integer.numberOfLeadingZeros() > call to avoid its now unnecessary non-zero test, and > instead utilise this op to return the zero index). > Just delete the existing get() method and replace it > with this code. Actually this version seems to > improve throughput further - on my laptop regular > ChunkedArrayList is currently averaging around 790ms > per run of my hacky speed test, whereas with the > modifications below it averages around 610ms, making > it almost 25% faster. I've included my performance > benchmark as well, for reference. I'm sure with some > thought a better one could be put together. > > private static final int arrayIndex2(int index) > { > if (index == 1) > return 0 ; > int i = index >>> 1 ; > int n = 1; > if (i >>> 16 == 0) { n += 16; i <<= 16; } > if (i >>> 24 == 0) { n += 8; i <<= 8; } > if (i >>> 28 == 0) { n += 4; i <<= 4; } > if (i >>> 30 == 0) { n += 2; i <<= 2; } > n -= i >>> 31; > final int arraySizeShiftMinusSeed = (31 - n) > >>> 1 ; > final int b1 = (2 << arraySizeShiftMinusSeed << > arraySizeShiftMinusSeed) ; > final int a1 = (1 << arraySizeShiftMinusSeed + 2) ; > final int b2 = index - b1 ; > final int a2 = (1 << arraySizeShiftMinusSeed) ; > final int b4 = b2 >>> arraySizeShiftMinusSeed + 1 ; > final int av = a1 - a2 ; > final int bv = b4 - 2 ; > return av + bv ; > } > > @Override > public T get(int index) { > if ((0 > index) | (index >= _size)) > throw new IndexOutOfBoundsException(); > index += 1 ; > final Object[] array = > _backingArray[arrayIndex2(index)] ; > return (T) array[index & (array.length - 1)] ; > } > > > //// benchmarked by > > static final int count = 1 << 24 ; > static final int mask = count - 1 ; > public static void main(String[] args) { > double sum = 0 ; > final List list = new > ChunkedArrayList() ; > for (int i = 0 ; i != count ; i++) > list.add(i) ; > for (int r = 0 ; r != 100 ; r++) { > final long start = System.currentTimeMillis() ; > int o = 0 ; > for (int j = 0 ; j != count ; j++) { > list.get((j + o) & mask) ; > o += 1 ; > } > final long end = System.currentTimeMillis() ; > sum += (end - start) ; > > System.out.println(String.format("run %d: %dms; > avg=%.0fms", r, (end - start), sum / (r + 1))) ; > } > } > > > On 24 April 2010 09:34, Benedict Elliott Smith > > wrote: > > Hi Kevin, > > If you are willing to change the pattern of > allocation just slightly, I have come up with an > alternate algorithm (optimised for the seed = 1 > case) that on my laptop I notice around a 10-20% > speed up over ChunkedArrayList for random(ish) > calls to get() on a list of size 1 << 24. The > change is to simply drop your first array > allocation (so that there are no arrays of size > 1, but that all remaining allocations follow the > existing pattern), as this allows simplifying > the algorithm noticeably (several ops in the > previous algorithm were unnecessary for any but > the first two arrays). > > My get(index) method is defined as: > > if ((index < 0) | (index >= _size)) > throw new IllegalArgumentException() ; > index += 2 ; > final Object[] array = > _backingArray[arrayFor(index)] ; > return (T) array[index & (array.length - 1)] ; > > and arrayFor(index) is defined as: > > private static final int arrayFor(int index) { > final int arraySizeShiftMinusSeed = (31 - > Integer.numberOfLeadingZeros(index >>> 1)) >>> 1 ; > final int b1 = (2 << arraySizeShiftMinusSeed << > arraySizeShiftMinusSeed) ; > final int a1 = (1 << > arraySizeShiftMinusSeed + 2) ; > final int b2 = index - b1 ; > final int a2 = (1 << arraySizeShiftMinusSeed) ; > final int b4 = b2 >>> arraySizeShiftMinusSeed + 1 ; > final int av = a1 - a2 ; > final int bv = b4 - 3 ; > return av + bv ; > } > > I have deliberately interleaved the calculations > here to make sure the pipeline is being used > (just in case javac+hotspot are not re-ordering > the intermediate calculations for us) > > > > > > On 24 April 2010 08:24, Benedict Elliott Smith > > wrote: > > Hi Kevin, > > It looks like this is because > ChunkedArrayList creates only one initial > array of size s, whereas my algorithm > expects two . Apologies for not spotting > this - the pattern of allocations is > identical after this point. I'll see if it > can be modified to support your pattern of > allocation. > > > On 24 April 2010 01:31, Kevin L. Stern > > wrote: > > Hi Benedict, > > I took a look at your index > decomposition routine; it was not > working for seed = 1 until I made index > the query index plus one (similar to my > r variable) and arrayIndex > ((firstArrayOfThisSize + arrayOffset) & > Integer.MAX_VALUE) - 1 (notice I'm > subtracting one). Once I made these > changes the routine was actually slower > than my version (although not by much). > Let me know if you have a better way to > bring your routine in line with the > arraylet structure. > > Kevin > > > On Fri, Apr 23, 2010 at 2:26 PM, > Benedict Elliott Smith > wrote: > > Hi Kevin, > > Unfortunately this week has been > pretty hectic, and I haven't had > much time to much more than theorise > on this topic - and this weekend the > weather looks set to be much too > nice to stay in doors! It looks like > you've made really good progress on > the ChunkedArrayDeque - I haven't > fully digested it yet, but it looks > pretty impressive. I'm not sure > (since I misunderstood your list > implementation prior to reading it > in detail) but I think I may have > been toying with a similar growth > strategy for a hash map variant > since the copies are necessary there > anyway. > > I have taken another look at the > index algorithm and have tidied it > up as below, and it now supports a > seed size of 1; however I am not > sure that using a value this small > is advisable, given that the > overhead for the first array is at > least 60 bytes; with a seed size of > 1 the first 8 indexes would utilise > less than 20% of the allocated > memory for data, the first 24 less > than 25%. I would have thought a > seed of at least 2 and perhaps 3 > would be advisable. > > As an aside, it is worth noting that > the indexOffset calculation below > can be replaced with index & > (_backingArray[arrayIndex].length - > 1) , although I am not certain what > effect this will have on > performance, given that this would > be another memory operation to > retrieve the length from the array; > but it would make the separation of > the calculation into functions more > straight forward. > > final int > arraySizeShiftMinusSeed = (31 - > Integer.numberOfLeadingZeros(index > >>> seed)) >>> 1 ; > final int arraySizeShift = > arraySizeShiftMinusSeed + seed ; > > final int firstArrayOfThisSize = > (1 << arraySizeShiftMinusSeed > + 2) > - (1 << arraySizeShiftMinusSeed) > - 1 - (arraySizeShift >>> 31) ; > final int indexRemainder = > index - (1 << arraySizeShift << > arraySizeShiftMinusSeed) ; > > final int arrayOffset = > indexRemainder >>> arraySizeShift ; > final int arrayIndex = > (firstArrayOfThisSize + arrayOffset) > & Integer.MAX_VALUE ; > > final int itemIndex = index & > ((1 << arraySizeShift) - 1) ; > > > > On 23 April 2010 11:00, Kevin L. > Stern > wrote: > > Hi Benedict, > > Have you had a chance to get > your index decomposition > procedure to work with seed > values less than two? > > Kevin > > > On Sat, Apr 17, 2010 at 11:48 > AM, Benedict Elliott Smith > > wrote: > > Hi Kevin, > > As it happens I might have > something useful still to > contribute. As an exercise > in saving face I revisited > the problem to see if I > could achieve the same > complexity bounds as > ChunkedArrayList but with a > lower overhead. I must admit > I still didn't fully > appreciate how the algorithm > in ChunkedArrayList worked > until I tried to come up > with an algorithm with > similar properties. What I > have ended up with is almost > identical except adds I > think a couple of > incremental improvements, > simply by redefining the > arrayIndex() method. I > should note that I have not > yet implemented more than a > prototype as it seems to me > your implementation is > excellent already, and if it > is decided to include my > modifications the changes > should be modest. > > Firstly, (I hope that) what > I have produced is a little > more CPU pipe-line friendly; > there is less dependency on > immediately preceding > calculations at each stage > (i.e. so more operations > should be able to proceed > simultaneously in the > pipeline), and consists > exclusively of shifts, > addition/subtraction and > bit-wise (&)ands (except for > the conditionals in > Integer.numberOfLeadingZeros(i)), although > the total number of > instructions is > approximately the same. > > Secondly, I have modified > the algorithm so that a > "seed" size can be specified > (although I expect hard > coding a suitable one will > ultimately be best). Whereas > ChunkedArrayList currently > requires that the pattern of > array allocation sizes be > [1, 1, 2, 2, 2, 4(..*6), > 8(..*12), 16(..*24)] we can > now support, for some "*s*", > [*s*(..*2), 2*s*(..*3), > 4*s*(..*6), 8*s*(..*12), > 16*s*(..*24)] etc. although > when put in simple text like > that it does appear to > trivialise the change. The > benefit of this, though, is > two fold: 1) for small n the > constant factor is reduced > (both CPU and memory wise); > and 2) the sqrt(n) bounds > are reached more quickly also. > > As an illustration, consider > setting *s* to 4, and assume > the backing array is size > two and doubles in size with > each growth; with > ChunkedArrayList we would > resize at i=2, i=6, i=20, > i=72; with *s* as 4 we would > instead resize at > i=8,i=24,i=80,i=288; the > cost at each would be some > multiple of 2,4,8,16 > respectively. As you can see > the latter is much closer to > the sqrt(n) cost - both > approach it eventually, but > my suggestion is to reach it > more quickly. This is at the > expense of more slowly > reaching the sqrt(n) wasted > memory condition, but given > the high constant factor > cost wrt to memory at this > early stage, this seems a > very sensible trade off. It > seems likely this should > also have a positive impact > on cache performance for > smaller lists as well. > > Finally, after playing with > this idea in my head I am > confident I can extend the > core ideas of this data > structure to hashing > relatively easily, getting > the the same worst case > O(sqrt(n)) insertion cost, > and O(sqrt(n)) wasted memory > guarantees. I notice that > this case hasn't been > addressed yet, although I > see from Martin's recent > mail that this was raised > before. Unless there are > better suggestions for > solving the hash table > problem I will have a go at > it as it seems an > interesting problem - that > is, assuming there are no > objections? > > I'm interested to hear your > thoughts. I hope this time > I've been a bit more > considered in what I've put > forward, and hence less of a > waste of time! > > Code snippet for calculation > of array index and item offset: > > final int > arraySizeShiftMinusSeed = > ((31 - > Integer.numberOfLeadingZeros(index > >>> seed)) >>> 1) ; > final int arraySizeShift = > arraySizeShiftMinusSeed + seed ; > final int > firstArrayOfThisSize = ((((1 > << arraySizeShiftMinusSeed + > 3) - (1 << > arraySizeShiftMinusSeed + > 1))) >>> 1) - 1 ; > final int indexRemainder = > index - ((1 << seed) << > arraySizeShiftMinusSeed + > arraySizeShiftMinusSeed) ; > final int arrayOffset = > indexRemainder >>> > arraySizeShift ; > > final int arrayIndex = > firstArrayOfThisSize + > arrayOffset ; > final int itemIndex = index > & ((1 << arraySizeShift) - 1) ; > > the first array size will be > 1 << seed - 1 (i.e. seed is > equal to *s* + 1); seed only > works for values for 2 or > more at this moment, fyi > > > > On 16 April 2010 00:18, > Kevin L. Stern > > > wrote: > > Oh no worries Benedict, > thanks for your interest > in the topic. Let me > know if you have any > other questions or if > you have any related > ideas or concerns. > > > On Thu, Apr 15, 2010 at > 8:00 AM, Benedict > Elliott Smith > > > wrote: > > Sorry Kevin - it > sounds like I might > be being of more > hindrance than help. > that part of the > discussion was > clearly truncated by > the time I had > joined the list - I > haven't been able to > find the history in > the archives either... > > I was just wondering > about the worst case > cost of add() as > described by your > javadoc; admittedly > it is optimal with > respect to unused > memory, but the > worst case cost of > an add is still > sqrt(n), with a > relatively high > constant factor. I > had been thinking > that once n passed a > threshold the cost > of additions in this > other structure > would become a > constant factor, > offering nice > algorithmic > complexity > guarantees for large > n; however since > sqrt(Integer.MAX_VALUE) > is ~46,000, the > maximum size of new > array allocations > would have to be > unrealistically > small (assuming > linear cost for > allocation) for this > to be the case. It > would still be nice > to have a data > structure that > avoids needing to > copy data with each > grow, whilst still > maintaining good > memory performance. > > That /all/ being > said, I had been > going by your > javadoc and emails > to ascertain the > behaviour of this > class, as I couldn't > locate a free copy > of [Brodnik99resizablearrays], > and it seems this > was a bad idea; as > the sqrt(n) cost > appears to be > associated with > growing the backing > array, rather than > with what I assumed > to be copying data > between arraylets, > and it seems this > cost is pretty > optimal. That will > teach me to post to > a list without > getting my facts > straight first. The > interesting thing is > simply that the > constant factor for > this implementation > still seems to be > quite high, although > perhaps that is > simply because I was > not benchmarking > sufficiently large > values of n. > > > > On 15 April 2010 > 12:12, Kevin L. > Stern > > > wrote: > > Hi Benedict, > > Unless I am > misreading your > post, this now > has a very > similar feel to > the first data > structure that I > posted to the > list. Martin > Buchholz then > pointed out that > we can > incorporate the > ideas from > [Brodnik99resizablearrays] > and reap > additional benefits. > > Regards, > > Kevin > > > On Thu, Apr 15, > 2010 at 4:07 AM, > Benedict Elliott > Smith > > > wrote: > > Hi Kevin, > > Yes, as I > was going to > bed last > night I > realised I > had not > fully > addressed > the problem > that was > originally > being > visited; > only reduced > the constant > factor for > addition to > the end of > the list. A > trivial > modification > fixes that, > however; > same scheme > but up to > some maximum > arraylet > size (of a > power of 2), > after which > the array is > increased in > size > linearly. > Performance > doesn't seem > to have been > affected > appreciably, > although not > been > exhaustive > in the > benchmarking: > > 10 items > inserts > versus > ArrayList: > Chunked=1.15, > ExpArray=1.16 > 10 items > inserts > Chunked / > ExpArray = 0.99 > 10 items get > versus > ArrayList: > Chunked=1.15, > ExpArray=1.16 > 10 items get > Chunked / > ExpArray = 0.99 > 100 items > inserts > versus > ArrayList: > Chunked=1.24, > ExpArray=1.01 > 100 items > inserts > Chunked / > ExpArray = 1.23 > 100 items > get versus > ArrayList: > Chunked=1.24, > ExpArray=1.01 > 100 items > get Chunked > / ExpArray = > 1.23 > 1000 items > inserts > versus > ArrayList: > Chunked=1.22, > ExpArray=1.03 > 1000 items > inserts > Chunked / > ExpArray = 1.19 > 1000 items > get versus > ArrayList: > Chunked=1.22, > ExpArray=1.03 > 1000 items > get Chunked > / ExpArray = > 1.19 > 10000 items > inserts > versus > ArrayList: > Chunked=1.22, > ExpArray=1.03 > 10000 items > inserts > Chunked / > ExpArray = 1.18 > 10000 items > get versus > ArrayList: > Chunked=1.22, > ExpArray=1.03 > 10000 items > get Chunked > / ExpArray = > 1.18 > 100000 items > inserts > versus > ArrayList: > Chunked=0.82, > ExpArray=0.75 > 100000 items > inserts > Chunked / > ExpArray = 1.09 > 100000 items > get versus > ArrayList: > Chunked=0.82, > ExpArray=0.75 > 100000 items > get Chunked > / ExpArray = > 1.09 > > The nice > thing about > this is that > the maximum > amount of > wasted > memory is > user > configurable. > Even with a > low setting > as above > (65K) > performance > seems pretty > consistent. > > Code for > calculating > index and > array offset > are pretty > straight > forward; > haven't > given much > thought to > optimisations > just yet: > > private > final int > indexFor(int > a, int i) { > return 1 + i > - (a > > maxArrayIndex > ? (1 + a - > maxArrayIndex) > << > maxArraySizeShift > : 1 << a) ; > } > private > final int > arrayFor(int > i) { > return i >= > (maxArraySize > << 1) ? (i + > 1 >>> > maxArraySizeShift) > + > maxArrayIndex > - 1 : 31 - > Integer.numberOfLeadingZeros(i > + 1) ; > } > > Regarding > the double > list idea - > yes, I > agree, I > certainly > didn't think > that one > through fully! > > > > On 15 April > 2010 02:44, > Kevin L. > Stern > > > wrote: > > Hi Benedict, > > Like > you, I > am > relatively > new to > this > mailing > list; I > am also > trying > to tread > lightly > so as > not to > step on > any > toes. > That > being > said, I > think > that I > can > offer a > response > to your > inquiry. > > Regarding: > "The > idea is > to > simply > double > the new > array > size > each > time a > new > array > needs to > be > allocated" > > It seems > this > would > not > address > the > desire > of > offering > an > alternative > to the > allocation > of a > large > backing > array > for > ArrayList > (your > largest > backing > array > could > still > reach a > size of > 1/2 * > Integer.MAX_VALUE) > and > would > not > address > the > desire > of > wasting > the > (asymptotically) > minimum > amount > of > memory > in the > worst > case > while > maintaining > O(1) > amortized > time > bounds. > The data > structure > described > in > [Brodnik99resizablearrays] > has a > maximum > backing > array > size of > sqrt(n) > and caps > wasted > memory > at > sqrt(n). > What > advantage > over > ArrayList > do you > see in > your > data > structure? > > Regarding: > "Also, > with > regard > to a > Deque > implementation, > it seems > that the > simplest > solution > would be > to > simply > have two > lists, > with one > accepting > inserts > for near > the > beginning > and > being > ordered > in > reverse > whilst > the > other > accepted > inserts > for near > to the end." > > What > happens > with > your > structure > when you > add n > elements > and then > remove > element > 0 n > times? > I think > that > once you > work out > all the > kinks > you'll > end up > with the > two > stacks > approach, > which is > mentioned > in > [Brodnik99resizablearrays] > and > which I > mentioned > in an > earlier > email, > or > you'll > end up > with the > circular > list > approach, > which is > not > friendly > to O(1) > amortized > time > bounds > in a > data > structure > that > resizes > more > often > than > O(n) due > to the > 'unshift' > to the > front = > 0 > position. > I think > the best > approach > is the > one > mentioned > in > [Brodnik99resizablearrays], > which is > the > approach > that I > am > currently > working > on. > Incidentally, > this > approach > also > provides > for a > much > improved > index > unpacking > procedure > using > only bit > shifts > and bit > masks, > although > it is at > the > expense > of > (O(1)) > additional > work > during > resize. > > Regards, > > Kevin > > > > On Wed, > Apr 14, > 2010 at > 4:42 PM, > Benedict > Elliott > Smith > > > wrote: > > Hi, > > I > hope > you > don't > consider > it > rude > to > involve > myself > in > this > conversation > towards > the > end > - I > joined > the > mailing > list > only > recently. > > I'm > not > sure > if > this > offers > a > huge > amount > to > the > discussion, > but > I > have > tinkered > with > a > "chunked" > array > list > which > seems > to > offer > better > time > performance > in > general > at > the > cost > of > greater > (worst > case) > memory > utilisation. > It > is > easier > to > understand > IMHO > as > well, > although > this > is > not > necessarily > a > great > benefit > here. > It > turns > out > the > idea > is > very > similar > to > the > one > implemented > already > by > Kevin, > though; > but > perhaps > simpler. > The > idea > is > to > simply > double > the > new > array > size > each > time > a > new > array > needs > to > be > allocated, > or > in > effect > allocate > an > array > that > is > the > size > of > all > existing > arrays > put > together. > With > this > scheme > the > calculation > for > array > and > offset > are > really > very > straight > forward > ( > floor(log(i)) > and > 1 + > i - > 2^floor(log(i))) > ). Memory > utilisation > is > the > same > as > for > ArrayList, > but > obviously > inserts > at > the > end > are > much > quicker. > > I > have > prototyped > the > data > structure > this > evening > and > benchmarked > additions > at > the > end > of > the > list, > for > which > the > performance > is > pretty > impressive. > > Some > random > statistics > for > addition > only > on > the > client > JVM > (I > have > quickly > dubbed > my > implementation > ExpArrayList) > All > statistics > were > run > in > two > rounds > with > ~1000 > runs > per > round > per > statistic > per > list, > and > the > second > round > results > were > used. > > 10 > items > versus > ArrayList: > Chunked=1.14, > ExpArray=1.02 > 10 > items > Chunked > / > ExpArray > = 1.12 > 100 > items > versus > ArrayList: > Chunked=1.20, > ExpArray=0.82 > 100 > items > Chunked > / > ExpArray > = 1.45 > 1000 > items > versus > ArrayList: > Chunked=1.03, > ExpArray=0.51 > 1000 > items > Chunked > / > ExpArray > = 2.02 > 10000 > items > versus > ArrayList: > Chunked=0.88, > ExpArray=0.49 > 10000 > items > Chunked > / > ExpArray > = 1.79 > 100000 > items > versus > ArrayList: > Chunked=0.32, > ExpArray=0.20 > 100000 > items > Chunked > / > ExpArray > = 1.64 > > and > server > JVM: > 10 > items > versus > ArrayList: > Chunked=1.00, > ExpArray=1.16 > 10 > items > Chunked > / > ExpArray > = 0.86 > 100 > items > versus > ArrayList: > Chunked=1.29, > ExpArray=0.96 > 100 > items > Chunked > / > ExpArray > = 1.34 > 1000 > items > versus > ArrayList: > Chunked=1.16, > ExpArray=0.92 > 1000 > items > Chunked > / > ExpArray > = 1.27 > 10000 > items > versus > ArrayList: > Chunked=0.93, > ExpArray=0.84 > 10000 > items > Chunked > / > ExpArray > = 1.12 > 100000 > items > versus > ArrayList: > Chunked=0.71, > ExpArray=0.65 > 100000 > items > Chunked > / > ExpArray > = 1.10 > > Interestingly > insertion > at > the > beginning > of > the > list > appears > to > be > quicker > with > ExpArrayList, > at > least > on > the > server > JVM, > whereas > I > would > have > expected > them > to > be > fairly > close. > Amazingly > ExpArrayList > is > faster > even > than > ArrayList > for > insertion > at > the > beginning > of > large > lists, > which > I > haven't > yet > tried > to > understand. > Insertion > in > the > middle > is > similar. > > 10 > items > versus > ArrayList: > Chunked=9.82, > ExpArray=3.80 > 10 > items > Chunked > / > ExpArray > = 2.59 > 100 > items > versus > ArrayList: > Chunked=7.30, > ExpArray=3.41 > 100 > items > Chunked > / > ExpArray > = 2.14 > 1000 > items > versus > ArrayList: > Chunked=2.83, > ExpArray=1.09 > 1000 > items > Chunked > / > ExpArray > = 2.59 > 10000 > items > versus > ArrayList: > Chunked=1.56, > ExpArray=0.72 > 10000 > items > Chunked > / > ExpArray > = 2.16 > > Finally, > there > are > promising > results > for > get() > from > the > ExpArrayList > as > well > (server > JVM), > again > somehow > beating > ArrayList > for > larger > lists: > 10 > items > get > versus > ArrayList: > Chunked=1.27, > ExpArray=1.16 > 10 > items > get > Chunked > / > ExpArray > = 1.10 > 100 > items > get > versus > ArrayList: > Chunked=1.45, > ExpArray=1.17 > 100 > items > get > Chunked > / > ExpArray > = 1.25 > 1000 > items > get > versus > ArrayList: > Chunked=1.42, > ExpArray=1.07 > 1000 > items > get > Chunked > / > ExpArray > = 1.33 > 10000 > items > get > versus > ArrayList: > Chunked=1.26, > ExpArray=1.02 > 10000 > items > get > Chunked > / > ExpArray > = 1.24 > 100000 > items > get > versus > ArrayList: > Chunked=1.05, > ExpArray=0.86 > 100000 > items > get > Chunked > / > ExpArray > = 1.22 > > > I'm > willing > to > explore > this > further > but > I'm > not > sure > how > desirable > that > is, > given > that > Kevin's > data > structure > appears > to > perform > pretty > well > already > wrt > to > CPU > time, > and > better > wrt > to > memory > utilisation, > and > in > effect > this > mostly > changes > only > the > function > to > determine > which > array > to > use, > not > the > body > of > the > implementation. > Let > me > know > if > you > would > like > a > copy > of > the > source > code > and > I > will > find > somewhere > to > upload > it. > > Also, > with > regard > to a > Deque > implementation, > it > seems > that > the > simplest > solution > would > be > to > simply > have > two > lists, > with > one > accepting > inserts > for > near > the > beginning > and > being > ordered > in > reverse > whilst > the > other > accepted > inserts > for > near > to > the > end. > The > only > trick > would > be > having > the > list > at > the > beginning > support > iteration > in > reverse > order > cheaply, > but > this > could > easily > be > achieved > by > creating > an > extension > of > List > with > a > reverseIterator() > method. > > > Anyway, > not > sure > if > this > helped > at > all > but > fancied > joining > in... > > > > > On > 14 > April > 2010 > 12:25, > Joe > Kearney > > > wrote: > > Hi > Kevin, > > It > implements > List, > as > well > as > Deque. > It > is > indeed > based > on > ArrayDeque, > with > the > added > operations > to > implement > list. > It > does > so > reasonably > efficiently, > moving > the > fewest > elements > possible > on > each > operation, > that > is > zero > for > the > queue > operations, > at > most > n/2 > for > the > rest > and > all > of > them > for > a > backing > array > resize. > > The > idea > is > to > get > a > replacement > for > arraylist > that > performs > like > arraydeque > on > remove(0). > As > a > side > effect, > we > should > be > able > to > get > better > performance > on > other > operations > by > requiring > fewer > elements > to > be > moved. > > Thanks, > Joe > > 2010/4/14 > Kevin > L. > Stern > > > > Hi > Joe, > > I > was > referring > to > the > ChunkedArrayList > when > I > stated > that > add > does > not > amortize > to > constant > time > when > the > data > structure > employs > the > circular > list > trick > to > achieve > deque > behavior; > ChunkedArrayList > potentially > resizes > every > n^(1/2) > operations. > > Regarding > your > CircularArrayList, > does > it > differ > from > Java's > ArrayDeque? > I > took > only > a > cursory > look > at > it, > so > please > understand > if > I > have > missed > your > reason > for > creating > CircularArrayList > altogether. > > Regards, > > Kevin > > > On > Tue, > Apr > 13, > 2010 > at > 6:52 > AM, > Joe > Kearney > > > wrote: > > Hi > Kevin, > Martin, > > To > add > another > discussion > point, I've > been > writing > a > draft/proof-of-concept > of > retrofitting > the > List > interface > onto > ArrayDeque. > This > works > over > the > raw > array, > it > doesn't > use > the > fancier > structures > being > discussed > elsewhere > on > this > list > that > deal > with > splitting > huge > arrays > into > arraylets, > or > that > provide > for > O(1) > insert > in > the > middle. > > http://code.google.com/p/libjoe/source/browse/trunk/src/joe/collect/CircularArrayList.java > > I'd > be > interested > if > you > have > any > comments > in > the > context > of > this > discussion. > The > code > is > not > entirely > ready > yet, > a > couple > of > tests > fail > (6/789) > because > of > a > corner > case > I > haven't > nailed > yet, > but > the > idea > is > there > at > least. > I'd > like > to > add > array > shrinking > later, > when > the > size > dips > below > capacity*0.4 > perhaps, > to > avoid > flickering > up > and > down > around... > > Tests > show > performance > to > be > close > to > ArrayList > for > the > O(1) > operations. Timings > for > indexed > reads > and > writes > showed > no discernible difference > between > implementations > last > time > I > ran > the > tests. I > don't > understand > at > the > moment > why > the > iterator > add > at > index > size/3, > size/2 > perform > 30% > slower > than > ArrayList > on > smaller > lists, > nor > the > dodgy > numbers > for > ArrayList.insert(5), > I'll > look > at > this > soon. Those > operations > that > become > O(1) > in > a > circular > implementation > (that > are > implemented > and > tested > here) > are > faster > than > in > ArrayList. > Insert/remove > in > the > middle > are > somewhat > faster > than > ArrayList > because > we > only > have > to > copy > at > most > half > of > the > elements, > except > when > resizing > the > array. > > Kevin, > I > don't > fully > understand > your > point > about > not > amortizing > to > O(1). > Certainly > that's > true > for > insert > not > at > head > or > tail. > Otherwise > this > implementation > only > moves > array > elements > to > the > front > on > an > array > resize > operation > which > happens > every > O(ln > n) > operations > at > most, > if > we > do > lots > of > adds, > maybe > a > little > more > if > we > add > array > shrinking > too. > This > is > the > same > as > ArrayList. > Are > you > just > referring > to > the > add-in-the-middle > case? > > Some > performance > results > below, > code > for > these > is > in > the > repository > above > too. > This > was > the > second > run, > after > a > warmup. > > Thanks, > Joe > > ------------------------------------------------ > CircularArrayList > ------------------------------------------------ > size > > > > > add > > > > > get > > > > > set > > iterAdd/3 > > iterAdd/2 > > insert(5) > > removeRnd > > removeMid > > remove(0) > > 10 > > > > > 20 > > > > > 67 > > > > > 70 > > > > > 125 > > > > > 102 > > > > > 90 > > > > > 240 > > > > > 191 > > > > > 138 > > 100 > > > > > 19 > > > > > 67 > > > > > 70 > > > > > 166 > > > > > 138 > > > > > 94 > > > > > 230 > > > > > 194 > > > > > 118 > 1000 > > > > > 28 > > > > > 64 > > > > > 67 > > > > > 681 > > > > > 538 > > > > > 91 > > > > > 324 > > > > > 382 > > > > > 119 > 10000 > > > > > 30 > > > > > 65 > > > > > 67 > > > > 5884 > > > > 4425 > > > > > 94 > > > > 1296 > > > > 2330 > > > > > 124 > ---------------------------------------------------- > ArrayList > ---------------------------------------------------- > size > > > > > add > > > > > get > > > > > set > > iterAdd/3 > > iterAdd/2 > > insert(5) > > removeRnd > > removeMid > > remove(0) > > 10 > > > > > 23 > > > > > 68 > > > > > 70 > > > > > 100 > > > > > 69 > > > > 32913 > > > > > 162 > > > > > 130 > > > > > 105 > > 100 > > > > > 20 > > > > > 67 > > > > > 70 > > > > > 129 > > > > > 104 > > > > 21944 > > > > > 169 > > > > > 134 > > > > > 135 > 1000 > > > > > 29 > > > > > 63 > > > > > 67 > > > > > 651 > > > > > 506 > > > > 9602 > > > > > 364 > > > > > 333 > > > > > 526 > 10000 > > > > > 30 > > > > > 63 > > > > > 66 > > > > 5878 > > > > 4414 > > > > 9947 > > > > 2312 > > > > 2280 > > > > 4437 > > 2010/4/13 > Kevin > L. > Stern > > > > Hi > Martin, > > I > had > intended > to > address > your > request > for > absolute > O(1) > operations > in > the > previous > email. > The > approach > to > achieving > this > suggested > in > [Brodnik99resizablearrays] > is > tantamount > to > making > ArrayList > operations > absolute > O(1) > by > keeping > around > an > array > of > size > (3/2)*n > and > filling > it > with > a > constant > number > of > entries > from > the > main > array > each > time > add > is > called. > Although > this > distributes > the > work > done > during > a > resize > across > the > n > operations > required > to > enter > a > resize-required > state, > it > is > at > the > expense > of > additional > memory > usage > and > slower > add > operations. > My > thought > is > that > this > would > be > a > fine > approach > for > a > real-time > application > that > requires > hard > guarantees > on > performance > but > would > be > a > liability > in > so > many > Java > applications > that > do > not > require > these > hard > guarantees. > I > look > forward > to > hearing > your > thoughts > on > the > matter, > though. > > Kevin > > > On > Tue, > Apr > 13, > 2010 > at > 6:18 > AM, > Kevin > L. > Stern > > > wrote: > > Hi > Martin, > > It's > interesting > to > note > that > the > old > circular > list > trick > will > not > suffice > to > turn > this > data > structure > into > a > deque > since > we > might > be > copying > all > n > elements > back > to > the > front > = > 0 > position > every > n^(1/2) > operations > (add > wouldn't > amortize > to > O(1)). > We > could > use > the > old > two > stacks > trick > (push > elements > onto > one > stack, > flip > (the > bottom) > half > (of) > the > elements > to > the > 'other' > stack > when > the > 'other' > stack > becomes > empty), > mentioned > in > [Brodnik99resizablearrays], > but > I > find > this > to > be > a > bit > CS > 101. > In > [Brodnik99resizablearrays] > the > authors > suggest > a > method > for > making > all > blocks > roughly > the > same > size, > allowing > us > to > expand/shrink > capacity > at > the > beginning > or > the > end; > this > is > the > approach > that > I > will > take > to > create > a > deque. > > The > FAQ > for > the > Sun > Contributor > Agreement > Q3 > (http://www.sun.com/software/opensource/contributor_agreement.jsp#sa_3) > indicates > that > one > should > check > with > the > project > to > determine > where > the > SCA > should > be > sent. > Do > you > know > where > I > would > find > this > information? > > Kevin > > @MISC{Brodnik99resizablearrays, > author > = > {Andrej > Brodnik > and > Svante > Carlsson > and > Erik > D. > Demaine > and > J. > Ian > Munro > and > Robert > Sedgewick}, > title > = > {Resizable > Arrays > in > Optimal > Time > and > Space}, > year > = > {1999} > > } > > On > Sun, > Apr > 11, > 2010 > at > 4:17 > PM, > Martin > Buchholz > > > wrote: > > Hi > Kevin, > > Thanks > for > your > continuing > work > on > this. > > I > like > the > test > results, > and > agree > with > your > analysis. > I'm > especially > happy > that > you're > beating > ArrayList > at > some > operations. > > I'd > like > to > see > O(1) > addition > at > the > beginning, > implement > both > List > and > Deque > (I > regret > our > not > having > done > this > with > ArrayDeque). > > An > additional > property > that > would > be > nice > to > have > (but > don't > try > too > hard) > is > to > provide > some > kind > of > real-time > guarantees > on > the > cost > of > an > individual > operation, > not > just > amortized > time. > E.g. > ArrayList.add > is > worst-case > O(n), > making > it > unsuitable > for > use > in > some > real-time > applications. > > I > will > help > get > your > changes > into > the > obvious > software > distributions. > I > assume > you're > happy > with > having > this > class > included > in > any > of > Doug > Lea's > jsr166, > guava-libraries, > or > the > JDK > itself. > You > should > sign > a > Sun > contributor > agreement, > or > whatever > the > Oracle > equivalent > is, > if > you > have > not > done > so > yet. > > Doug > Lea > likes > public > domain, > guava-libraries > likes > the > Apache > license. > > We > should > get > various > people > a > chance > to > give > a > thumbs > up > on > the > design > of > this > class > - > Doug > Lea, > Josh > Bloch. > > Martin > > On > Sun, > Apr > 11, > 2010 > at > 09:32, > Kevin > L. > Stern > > > wrote: > > > Hello > Martin, > > > > > I > spent > some > time > this > weekend > trying > to > bring > out > bugs > in > the > > > implementation; > I > believe > the > latest > version > to > be > in > decent > shape. > I > have > > > also > gathered > some > data > on > the > performance > of > ChunkedArrayList > over > > > ArrayList > using > the > latest > 1.6 > JDK, > which > I've > included > below > (note > that > the > > > numbers > represent > the > time > spent > performing > the > specified > operation > with > > > ChunkedArrayList > over > the > time > spent > with > ArrayList, > so > 1.00 > indicates > > > equivalent > performance, > < > 1.00 > indicates > that > ChunkedArrayList > is > less > > > costly > and > > > 1.00 > indicates > that > ArrayList > is > less > costly). > I've > noticed > > > relatively > significant > variability > in > a > few > of > the > numbers > when > I > switch > > > hardware; > though, > these > data > do > seem > to > represent > rough > performance > > > expectations. > For > my > test > I > generated > x > elements > and > then > timed > the > process > > > of > adding > them > to > ArrayList/ChunkedArrayList, > then > I > performed > a > get > > > operation > on > each > for > indices > 0 > through > x-1 > and > finally > I > used > the > iterator > > > mechanism > to > retrieve > the > first > through > xth > element > (of > course, > I > performed > > > each > of > these > operations > multiple > times > throwing > away > the > timing > for > the > > > first > few > iterations > to > warm > up > the > JVM). > > > > > Regarding > the > question > of > whether > or > not > this > belongs > in > java.util, > I > would > > > suggest > that > if > it > is > desirable > from > a > GC > point > of > view > to > eliminate > the > > > large > backing > array > from > ArrayList > then > your > suggestion > of > achieving > this > by > > > way > of > a > data > structure > that > is > both > time > and > space > optimal > is > a > > > particularly > elegant > solution > as > it > not > only > guarantees > that > no > backing > > > array > will > be > larger > than > sqrt(n) > elements > but > it > also > provides > dynamic > > > shrinking > behavior, > has > less > maximum > memory > overhead > than > ArrayList, > and > > > copies > (asymptotically) > fewer > elements > during > a > resize > than > ArrayList. > Of > > > course, > this > data > structure > does > not > do > everything > better > than > ArrayList; > in > > > particular, > indexed > access > is > more > costly, > due > to > the > required > decomposition > > > of > the > index > into > backing > array > index > and > offset > and > the > additional > memory > > > indirection, > and > insertion-at-an-index > is > more > costly, > due > to > the > multiple > > > array > copies > necessary > to > complete > the > shift. > That > being > said, > I > think > that > > > the > additional > cost > of > indexed > access > is > partially > mitigated > by > the > > > availability > of > iterator > and > listIterator, > whose > implementations > do > not > use > > > the > index > decomposition > procedure, > and > the > additional > cost > of > > > insertion-at-an-index > is > partially > mitigated > by > the > fact > that > > > insertion-at-an-index > is > already > an > undesirable > operation > on > ArrayList > due > > > to > its > linear > time > complexity. > > > > > Kevin > > > > > 1000000 > elements: > > > Client > JVM: > > > Add > to > ChunkedArrayList > over > ArrayList: > 1.30 > > > Indexed > access > ChunkedArrayList > over > ArrayList: > 1.80 > > > Iterator > ChunkedArrayList > over > ArrayList: > 0.52 > > > > > Server > JVM: > > > Add > to > ChunkedArrayList > over > ArrayList: > 0.81 > > > Indexed > access > ChunkedArrayList > over > ArrayList: > 2.87 > > > Iterator > ChunkedArrayList > over > ArrayList: > 1.31 > > > > > 100000 > elements: > > > Client > JVM: > > > Add > to > ChunkedArrayList > over > ArrayList: > 0.96 > > > Indexed > access > ChunkedArrayList > over > ArrayList: > 1.86 > > > Iterator > ChunkedArrayList > over > ArrayList: > 0.48 > > > > > Server > JVM: > > > Add > to > ChunkedArrayList > over > ArrayList: > 0.96 > > > Indexed > access > ChunkedArrayList > over > ArrayList: > 1.89 > > > Iterator > ChunkedArrayList > over > ArrayList: > 2.68 > > > > > 10000 > elements: > > > Client > JVM: > > > Add > to > ChunkedArrayList > over > ArrayList: > 1.04 > > > Indexed > access > ChunkedArrayList > over > ArrayList: > 2.33 > > > Iterator > ChunkedArrayList > over > ArrayList: > 0.53 > > > > > Server > JVM: > > > Add > to > ChunkedArrayList > over > ArrayList: > 0.97 > > > Indexed > access > ChunkedArrayList > over > ArrayList: > 2.45 > > > Iterator > ChunkedArrayList > over > ArrayList: > 2.52 > > > > > 1000 > elements: > > > Client > JVM: > > > Add > to > ChunkedArrayList > over > ArrayList: > 0.99 > > > Indexed > access > ChunkedArrayList > over > ArrayList: > 2.27 > > > Iterator > ChunkedArrayList > over > ArrayList: > 0.54 > > > > > Server > JVM: > > > Add > to > ChunkedArrayList > over > ArrayList: > 0.84 > > > Indexed > access > ChunkedArrayList > over > ArrayList: > 1.23 > > > Iterator > ChunkedArrayList > over > ArrayList: > 1.11 > > > > > > > On > Fri, > Apr > 9, > 2010 > at > 7:42 > PM, > Martin > Buchholz > > > wrote: > >> > >> > My > feeling > on > whether > to > support > O(1) > at > both > ends > >> > is > that > any > flavor > of > this > that > ends > up > in > the > JDK > eventually > >> > should > really > do > this. > My > idea > is > that > we > can > >> > wholeheartedly > recommend > this > collection > class > >> > for > overall > good > behavior > without > any > of > the > surprising > >> > performance > traps > of > existing > collection > classes. > >> > >> > But > for > the > preliminary > version, > it > makes > sense > to > >> > support > only > O(1) > at > one > end, > if > it > simplifies > the > >> > implementation. > Random > access > will > of > course > >> > be > worse > than > ArrayList, > but > by > how > much? > >> > We > can > do > some > benchmarking > and > look > for > >> > micro-optimizations > now. > >> > >> > Kevin, > what > is > you > own > personal > feeling? > >> > Is > the > algorithm > correct, > and > efficient > enough? > >> > Do > you > think > your > new > collection > belongs > in > java.util? > >> > >> > Martin > >> > >> > On > Sun, > Apr > 4, > 2010 > at > 04:12, > Kevin > L. > Stern > > > >> > wrote: > >> > > > The > data > structure > is > available > at > the > second > link > that > I > originally > >> > > > provided > (once > again, > it > is > >> > > > >> > > > https://docs.google.com/Doc?docid=0Aabrz3MPBDdhZGdrbnEzejdfM2M3am5wM2Mz&hl=en > ). > >> > > > This > does > not > have > O(1) > time > insertion > at > the > front > as > yet > as > it > was > >> > > > unclear > >> > > > to > me > whether > or > not > it > was > agreed > upon: > >> > > > _________________ > >> > > > From: > Osvaldo > Doederlein > > > >> > > > Date: > Mon, > Mar > 29, > 2010 > at > 10:08 > AM > >> > > > Subject: > Re: > A > List > implementation > backed > by > multiple > small > arrays > >> > > > rather > >> > > > than > the > traditional > single > large > array. > >> > > > To: > Martin > Buchholz > > > >> > > > Cc: > "Kevin > L. > Stern" > >, > >> > > > core-libs-dev at openjdk.java.net > > >> > > > >> > > > Initially, > it > would > be > good > enough > to > replace > only > java.util.ArrayList > >> > > > with > >> > > > minimal > overhead. > ArrayList > does > not > support > efficient > add-at-front > or > >> > > > other > >> > > > enhancements > of > ArrayDeque; > but > ArrayList > is > still > a > much > more > important > >> > > > and > >> > > > popular > collection, > it's > the > primary > "straight > replacement > for > primitive > >> > > > arrrays" > and > I > guess > it > should > continue > with > that > role. > >> > > > _________________ > >> > > > >> > > > As > a > disclaimer, > I'm > still > tinkering > with > this > so > I'll > be > updating > the > >> > > > document > at > the > provided > link > as > I > find > improvements. > >> > > > >> > > > Thoughts? > >> > > > >> > > > Thanks, > >> > > > >> > > > Kevin > >> > > > >> > > > On > Thu, > Apr > 1, > 2010 > at > 10:28 > PM, > Martin > Buchholz > > > >> > > > wrote: > >> > >> > >> > >> > Hi > Kevin, > >> > >> > >> > >> > You're > probably > the > only > one > on > this > list > who > has > >> > >> > seriously > read > the > paper. > It > is > not > surprising > that > >> > >> > taking > a > research > paper > into > production > would > >> > >> > discover > bugs > - > the > research > never > had > to > undergo > >> > >> > rigorous > testing. > (I > like > the > Java > culture > of > >> > >> > combining > spec > + > implementation > + > test > suite) > >> > >> > >> > >> > I > suggest > you > ask > the > authors > directly > about > the > bug. > >> > >> > They > would > probably > also > be > interested > to > hear > >> > >> > about > your > implementation. > >> > >> > >> > >> > Are > you > aware > of > Integer.numberOfLeadingZeros? > >> > >> > >> > >> > >> > >> > http://download.java.net/jdk7/docs/api/java/lang/Integer.html#numberOfLeadingZeros(int) > > >> > >> > >> > >> > Martin > >> > >> > >> > >> > On > Wed, > Mar > 31, > 2010 > at > 19:34, > Kevin > L. > Stern > > > >> > >> > wrote: > >> > >> > > > I'm > almost > convinced > now > that > the > paper > is > incorrect. > The > code > below > >> > >> > > > gives > >> > >> > > > me > the > appropriate > index > into > the > index > array > and > the > offset > into > the > >> > >> > > > data > >> > >> > > > block. > That > being > said, > remember > when > I > mentioned > that > this > will > >> > >> > > > include > a > >> > >> > > > bit > more > work > to > access > an > element > than > a > simple > bit > shift > and > a > bit > >> > >> > > > mask? > >> > >> > > > Well > this > is > more > than > a > bit > more > - > we'll > be > doing > this > each > time > an > >> > >> > > > index > >> > >> > > > is > requested. > I'll > spend > some > time > trying > to > twiddle > the > bits > to > see > >> > >> > > > if > >> > >> > > > I > >> > >> > > > can > eliminate/combine > some > of > the > operations. > >> > >> > > > >> > >> > > > > > for > (int > r > = > 1; > r > < > 33; > r++) > { > >> > >> > > > > > > int > k > = > lg(r); > >> > >> > > > > > > int > floorKO2 > = > k > >> > 1; > >> > >> > > > > > > int > powFloorKO2 > = > (1 > << > floorKO2); > >> > >> > > > > > > int > p > = > ((1 > << > floorKO2) > - > 1) > << > 1; > >> > >> > > > > > > int > ceilKO2; > >> > >> > > > > > > if > ((k > & > 1) > == > 1) > { > >> > >> > > > > > > > ceilKO2 > = > floorKO2 > + > 1; > >> > >> > > > > > > > p > += > powFloorKO2; > >> > >> > > > > > > } > else > { > >> > >> > > > > > > > ceilKO2 > = > floorKO2; > >> > >> > > > > > > } > >> > >> > > > > > > int > e > = > r > & > ((1 > << > ceilKO2) > - > 1); > >> > >> > > > > > > int > b > = > (r > >> > ceilKO2) > & > (powFloorKO2 > - > 1); > >> > >> > > > >> > >> > > > > > > System.out.println((r > - > 1) > + > " > " > + > (p > + > b) > + > " > " > + > e); > >> > >> > > > > > } > >> > >> > > > >> > >> > > > Kevin > >> > >> > > > >> > >> > > > On > Wed, > Mar > 31, > 2010 > at > 7:08 > PM, > Kevin > L. > Stern > >> > >> > > > > > >> > >> > > > wrote: > >> > >> > >> > >> > >> > >> > I > realize > that > 2 > * > (2^(k/2) > - > 1) > only > works > for > even > numbered > >> > >> > >> > superblocks, > >> > >> > >> > the > odd > numbered > superblocks > need > an > additional > term > added > (the > >> > >> > >> > number > >> > >> > >> > of > >> > >> > >> > data > blocks > in > SB_[k-1]) > to > jive > with > my > interpretation; > anyhow, > I > >> > >> > >> > also > >> > >> > >> > came > >> > >> > >> > across > an > alternative > characterization > of > superblock > in > the > paper > >> > >> > >> > which > >> > >> > >> > states > that > data > blocks > are > grouped > within > a > superblock > when > they > >> > >> > >> > are > >> > >> > >> > the > >> > >> > >> > same > size > - > to > me, > though, > that > implies > that > my > example > structure > >> > >> > >> > below > >> > >> > >> > would > be > >> > >> > >> > >> > >> > >> > SB_0: > [1] > >> > >> > >> > SB_1: > [2][2][2] > >> > >> > >> > SB_2: > [4][4][4][4][4][4] > >> > >> > >> > >> > >> > >> > which > seems > to > contradict > my > understanding > of > (1) > below. > I > must > be > >> > >> > >> > reading > this > upside > down. > >> > >> > >> > >> > >> > >> > On > Wed, > Mar > 31, > 2010 > at > 6:36 > PM, > Kevin > L. > Stern > >> > >> > >> > > > >> > >> > >> > wrote: > >> > >> > >>> > >> > >> > >>> > What > am > I > missing > here? > In > "Resizable > arrays > in > optimal > time > and > >> > >> > >>> > space" > >> > >> > >>> > the > authors > define > their > data > structure > with > the > following > >> > >> > >>> > property: > >> > >> > >>> > >> > >> > >>> > (1) > "When > superblock > SB_k > is > fully > allocated, > it > consists > of > >> > >> > >>> > 2^(floor(k/2)) > data > blocks, > each > of > size > 2^(ceil(k/2))." > >> > >> > >>> > >> > >> > >>> > Since > the > superblock > is > zero-based > indexed > this > implies > the > >> > >> > >>> > following > >> > >> > >>> > structure: > >> > >> > >>> > >> > >> > >>> > SB_0: > [1] > >> > >> > >>> > SB_1: > [2] > >> > >> > >>> > SB_2: > [2][2] > >> > >> > >>> > SB_3: > [4][4] > >> > >> > >>> > SB_4: > [4][4][4][4] > >> > >> > >>> > [...] > >> > >> > >>> > >> > >> > >>> > Let's > have > a > look > at > Algorithm > 3, > Locate(i), > with > i > = > 3: > >> > >> > >>> > >> > >> > >>> > r > = > 100 > (the > binary > expansion > of > i > + > 1) > >> > >> > >>> > k > = > |r| > - > 1 > = > 2 > >> > >> > >>> > p > = > 2^k > - > 1 > = > 3 > >> > >> > >>> > >> > >> > >>> > What > concerns > me > is > their > statement > that > p > represents > "the > number > >> > >> > >>> > of > >> > >> > >>> > data > >> > >> > >>> > blocks > in > superblocks > prior > to > SB_k." > There > are > only > two > data > >> > >> > >>> > blocks > >> > >> > >>> > in > >> > >> > >>> > superblocks > prior > to > SB_2, > not > three. > Given > (1) > above, > unless > I'm > >> > >> > >>> > misinterpreting > it, > the > number > of > data > blocks > in > superblocks > prior > >> > >> > >>> > to > >> > >> > >>> > SB_k > >> > >> > >>> > should > be: > >> > >> > >>> > >> > >> > >>> > 2 > * > Sum[i=0->k/2-1] > 2^i > = > 2 > * > (2^(k/2) > - > 1) > >> > >> > >>> > >> > >> > >>> > This, > of > course, > seems > to > work > out > much > better > in > my > example > above, > >> > >> > >>> > giving > the > correct > answer > to > my > interpretation > of > their > data > >> > >> > >>> > structure, > but > >> > >> > >>> > I > have > a > hard > time > believing > that > this > is > their > mistake > rather > than > >> > >> > >>> > my > >> > >> > >>> > misinterpretation. > >> > >> > >>> > >> > >> > >>> > Thoughts? > >> > >> > >>> > >> > >> > >>> > Kevin > >> > >> > >>> > >> > >> > >>> > On > Tue, > Mar > 30, > 2010 > at > 5:20 > PM, > Martin > Buchholz > >> > >> > >>> > > > >> > >> > >>> > wrote: > >> > >> > >>>> > >> > >> > >>>> > On > Tue, > Mar > 30, > 2010 > at > 04:25, > Kevin > L. > Stern > >> > >> > >>>> > > > >> > >> > >>>> > wrote: > >> > >> > >>>> > > > Hi > Martin, > >> > >> > >>>> > > > >> > >> > >>>> > > > Thanks > much > for > your > feedback. > The > first > approach > that > comes > to > >> > >> > >>>> > > > mind > >> > >> > >>>> > > > to > >> > >> > >>>> > > > implement > O(1) > time > front > as > well > as > rear > insertion > is > to > create > >> > >> > >>>> > > > a > >> > >> > >>>> > > > cyclic > >> > >> > >>>> > > > list > structure > with > a > front/rear > pointer > - > to > insert > at > the > >> > >> > >>>> > > > front > >> > >> > >>>> > > > requires > >> > >> > >>>> > > > decrementing > the > front > pointer > (modulo > the > size) > and > to > insert > >> > >> > >>>> > > > at > >> > >> > >>>> > > > the > >> > >> > >>>> > > > rear > >> > >> > >>>> > > > requires > incrementing > the > rear > pointer > (modulo > the > size). > We > >> > >> > >>>> > > > need > >> > >> > >>>> > > > to > >> > >> > >>>> > > > resize > >> > >> > >>>> > > > when > the > two > pointers > bump > into > each > other. > Could > you > explain > >> > >> > >>>> > > > more > >> > >> > >>>> > > > about > >> > >> > >>>> > > > your > suggestion > of > introducing > an > arraylet > that > is > shared > by > the > >> > >> > >>>> > > > front > >> > >> > >>>> > > > and > >> > >> > >>>> > > > the > rear? > >> > >> > >>>> > >> > >> > >>>> > It > was > a > half-baked > idea > - > I > don't > know > if > there's > a > way > to > turn > >> > >> > >>>> > it > >> > >> > >>>> > into > >> > >> > >>>> > something > useful. > I > was > thinking > of > the > ArrayDeque > >> > >> > >>>> > implementation, > >> > >> > >>>> > where > all > the > elements > live > in > a > single > array. > >> > >> > >>>> > >> > >> > >>>> > > > It's > not > clear > to > me > how > that > would > help > and/or > be > a > better > >> > >> > >>>> > > > approach > than > the > cyclic > list. > Anyhow, > the > paper > that > you > >> > >> > >>>> > > > reference, > >> > >> > >>>> > > > "Resizable > arrays > in > optimal > time > and > space", > gives > a > deque > so > >> > >> > >>>> > > > if > >> > >> > >>>> > > > we > >> > >> > >>>> > > > take > >> > >> > >>>> > > > that > approach > then > the > deque > is > specified. > >> > >> > >>>> > >> > >> > >>>> > Technically, > ArrayList > also > supports > the > Deque > operations > - > >> > >> > >>>> > just > not > efficiently. > >> > >> > >>> > >> > >> > >> > >> > >> > > > >> > >> > > > >> > > > >> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > From xueming.shen at oracle.com Tue May 11 00:05:41 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Mon, 10 May 2010 17:05:41 -0700 Subject: Unicode script support in Regex and Character class In-Reply-To: <4BE880F7.50104@gmx.de> References: <4BD00250.3020206@oracle.com> <4BE5DC62.6020304@oracle.com> <4BE880F7.50104@gmx.de> Message-ID: <4BE89F55.1050205@oracle.com> Ulf, My apology for distracting you to that "smaller size alternative", as I said in my previous email please only "review" the bits at http://cr.openjdk.java.net/~sherman/6945564_6948903/webrev It's fine if you are interested in the stuff I experimented at http://cr.openjdk.java.net/~sherman/script/webrev.00 but please keep it separated from the code I'm proposing to putback. -Sherman Ulf Zibis wrote: > Some additional thoughts: > > - out.writeShort((short)(num & 0xffff)); ---short form---> > out.writeShort((short)num); > - use Arrays.binarySearch() in Character.UnicodeBlock.of(). > - "if (notFirst)" could be saved if you would first append the first > word to sb outside the while loop. > - StringBuilder sb could be initialized by the maximum name length > (=83) to avoid resizing; > - we could reuse the same Stringbuilder for multiple invokations of > Character.getName(cp)? > -- make CharacterName.get(cp) instance method and save CharacterName > object as ThreadLocal from Character.getName(cp). > -- synchronize Character.getName(cp). > - Instead using StringBuilder we could use ByteBuffer, omit the char[] > and build the final String by new String(bb.toArray(), "ASCII"). > -- saves the twice bigger char[] for the pool. > -- I imagine, ByteBuffer would perform better than StringBuilder. > - save UnicodeBlocks, BlockStarts and scriptStarts in a file instead > statically in classfile. > -- e.g. init of scriptStarts is a big waste of byte code (7/11 bytes > per short/integer entry). > > Am 08.05.2010 23:49, schrieb Xueming Shen: >> Hi, >> >> The API proposals for Unicode script support below have been approved. >> >> 6945564: Unicode script support in Character class >> 6948903: Make Unicode scripts available for use in regular expressions >> >> (2)Testing result suggests there is not too much runtime benefit of >> keeping a huge string >> data pool + an access hashmap for getName() implementation. The >> latest implementation now >> takes Ulf's suggestion to keep a relatively small byte[] pool and >> generate the names at runtime. >> (there is "even smaller" implementation, which consumes about 300K >> memory at runtime >> http://cr.openjdk.java.net/~sherman/script/webrev.00/ >> but it has a "scalability" problem need to address when string pool >> grows beyond 64k and it >> is little slow) > > I'm investigating in that. > For 1st, my string pool has size of only 35243. > > -Ulf > > > From Ulf.Zibis at gmx.de Tue May 11 14:11:58 2010 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Tue, 11 May 2010 16:11:58 +0200 Subject: Unicode script support in Regex and Character class In-Reply-To: <4BE89F55.1050205@oracle.com> References: <4BD00250.3020206@oracle.com> <4BE5DC62.6020304@oracle.com> <4BE880F7.50104@gmx.de> <4BE89F55.1050205@oracle.com> Message-ID: <4BE965AE.4060207@gmx.de> SOME of my comments below ARE ment for http://cr.openjdk.java.net/~sherman/6945564_6948903/webrev I marked the others. ;-) -Ulf Am 11.05.2010 02:05, schrieb Xueming Shen: > Ulf, > > My apology for distracting you to that "smaller size alternative", as > I said in my previous email > please only "review" the bits at > http://cr.openjdk.java.net/~sherman/6945564_6948903/webrev > > It's fine if you are interested in the stuff I experimented at > http://cr.openjdk.java.net/~sherman/script/webrev.00 > but please keep it separated from the code I'm proposing to putback. > > -Sherman > > > Ulf Zibis wrote: >> Some additional thoughts: >> >> *EXPERIMENTAL* - out.writeShort((short)(num & 0xffff)); ---short >> form---> out.writeShort((short)num); >> - use Arrays.binarySearch() in Character.UnicodeBlock.of(). >> *EXPERIMENTAL* - "if (notFirst)" could be saved if you would first >> append the first word to sb outside the while loop. >> *EXPERIMENTAL* - StringBuilder sb could be initialized by the >> maximum name length (=83) to avoid resizing; >> *EXPERIMENTAL* - we could reuse the same Stringbuilder for multiple >> invokations of Character.getName(cp)? >> *EXPERIMENTAL* -- make CharacterName.get(cp) instance method and >> save CharacterName object as ThreadLocal from Character.getName(cp). >> *EXPERIMENTAL* -- synchronize Character.getName(cp). >> *EXPERIMENTAL* - Instead using StringBuilder we could use >> ByteBuffer, omit the char[] and build the final String by new >> String(bb.toArray(), "ASCII"). >> *EXPERIMENTAL* -- saves the twice bigger char[] for the pool. >> *EXPERIMENTAL* -- I imagine, ByteBuffer would perform better than >> StringBuilder. >> - save UnicodeBlocks, BlockStarts and scriptStarts in a file instead >> statically in classfile. >> -- e.g. init of scriptStarts is a big waste of byte code (7/11 bytes >> per short/integer entry). >> >> Am 08.05.2010 23:49, schrieb Xueming Shen: >>> Hi, >>> >>> The API proposals for Unicode script support below have been approved. >>> >>> 6945564: Unicode script support in Character class >>> 6948903: Make Unicode scripts available for use in regular expressions >>> >>> (2)Testing result suggests there is not too much runtime benefit of >>> keeping a huge string >>> data pool + an access hashmap for getName() implementation. The >>> latest implementation now >>> takes Ulf's suggestion to keep a relatively small byte[] pool and >>> generate the names at runtime. >>> (there is "even smaller" implementation, which consumes about 300K >>> memory at runtime >>> http://cr.openjdk.java.net/~sherman/script/webrev.00/ >>> but it has a "scalability" problem need to address when string pool >>> grows beyond 64k and it >>> is little slow) >> >> I'm investigating in that. >> For 1st, my string pool has size of only 35243. >> >> -Ulf >> >> >> > > From Ulf.Zibis at gmx.de Tue May 11 14:14:24 2010 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Tue, 11 May 2010 16:14:24 +0200 Subject: Unicode script support in Regex and Character class In-Reply-To: <4BE8482D.70606@gmx.de> References: <4BD00250.3020206@oracle.com> <4BE5DC62.6020304@oracle.com> <4BE6E45B.304@gmx.de> <4BE75BF7.2070508@oracle.com> <4BE8482D.70606@gmx.de> Message-ID: <4BE96640.4000903@gmx.de> Am 10.05.2010 19:53, schrieb Ulf Zibis: > Am 10.05.2010 03:05, schrieb Xueming Shen: >> >> Ulf, >> >> Can you be more specific? I'm not sure I understand your question. >> What "buffering" >> are we talking here? > > In http://cr.openjdk.java.net/~sherman/6945564_6948903/webrev , > I think byte[] ba could be saved in initNamePool(), as you could > directly read from dis. I guess you owe me an answer here ;-) -Ulf From xueming.shen at oracle.com Tue May 11 16:41:13 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Tue, 11 May 2010 09:41:13 -0700 Subject: Unicode script support in Regex and Character class In-Reply-To: <4BE965AE.4060207@gmx.de> References: <4BD00250.3020206@oracle.com> <4BE5DC62.6020304@oracle.com> <4BE880F7.50104@gmx.de> <4BE89F55.1050205@oracle.com> <4BE965AE.4060207@gmx.de> Message-ID: <4BE988A9.2020805@oracle.com> Ulf Zibis wrote: > SOME of my comments below ARE ment for > http://cr.openjdk.java.net/~sherman/6945564_6948903/webrev > > I marked the others. ;-) > >>> >>> - use Arrays.binarySearch() in Character.UnicodeBlock.of(). This one can be discussed in a separate thread, I would prefer to stay with the script support in this review. >>> - save UnicodeBlocks, BlockStarts and scriptStarts in a file instead >>> statically in classfile. >>> -- e.g. init of scriptStarts is a big waste of byte code (7/11 bytes >>> per short/integer entry). >>> There are always different approaches, whatever approach you take , it always has pros cons. Lazy initialization, especially with data extracted to external resource, is not always the best choice. I truely believe it is not worth doing lazy initialization with external data storage in this case (with a total of 2k size difference). -Sherman From Ulf.Zibis at gmx.de Tue May 11 16:57:59 2010 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Tue, 11 May 2010 18:57:59 +0200 Subject: Unicode script support in Regex and Character class In-Reply-To: <4BE988A9.2020805@oracle.com> References: <4BD00250.3020206@oracle.com> <4BE5DC62.6020304@oracle.com> <4BE880F7.50104@gmx.de> <4BE89F55.1050205@oracle.com> <4BE965AE.4060207@gmx.de> <4BE988A9.2020805@oracle.com> Message-ID: <4BE98C97.5010502@gmx.de> Am 11.05.2010 18:41, schrieb Xueming Shen: > Ulf Zibis wrote: >> SOME of my comments below ARE ment for >> http://cr.openjdk.java.net/~sherman/6945564_6948903/webrev >> >> I marked the others. ;-) >> >>>> >>>> - use Arrays.binarySearch() in Character.UnicodeBlock.of(). > This one can be discussed in a separate thread, I would prefer to stay > with the script support in this review. > >>>> - save UnicodeBlocks, BlockStarts and scriptStarts in a file >>>> instead statically in classfile. >>>> -- e.g. init of scriptStarts is a big waste of byte code (7/11 >>>> bytes per short/integer entry). >>>> > There are always different approaches, whatever approach you take , it > always has pros cons. > Lazy initialization, especially with data extracted to external > resource, is not always the best choice. > I truely believe it is not worth doing lazy initialization with > external data storage in this case (with > a total of 2k size difference). Much thanks. Anyway, the UnicodeBlock strings have more than 2k. -Ulf From xueming.shen at oracle.com Tue May 11 18:12:04 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Tue, 11 May 2010 11:12:04 -0700 Subject: Unicode script support in Regex and Character class In-Reply-To: <4BE96640.4000903@gmx.de> References: <4BD00250.3020206@oracle.com> <4BE5DC62.6020304@oracle.com> <4BE6E45B.304@gmx.de> <4BE75BF7.2070508@oracle.com> <4BE8482D.70606@gmx.de> <4BE96640.4000903@gmx.de> Message-ID: <4BE99DF4.1020001@oracle.com> Ulf Zibis wrote: > Am 10.05.2010 19:53, schrieb Ulf Zibis: >> Am 10.05.2010 03:05, schrieb Xueming Shen: >>> >>> Ulf, >>> >>> Can you be more specific? I'm not sure I understand your question. >>> What "buffering" >>> are we talking here? >> >> In http://cr.openjdk.java.net/~sherman/6945564_6948903/webrev , >> I think byte[] ba could be saved in initNamePool(), as you could >> directly read from dis. > > I guess you owe me an answer here ;-) > > -Ulf > > Directly read from dis is much slower (2-3 times slower measured on my sparc machine) than do readFully() + access the byte[]. Sherman From paul.hohensee at oracle.com Tue May 11 18:53:40 2010 From: paul.hohensee at oracle.com (Paul Hohensee) Date: Tue, 11 May 2010 14:53:40 -0400 Subject: signal chaining and self defence In-Reply-To: <4BE89E34.3000308@sun.com> References: <4BE54B85.7040000@fh-landshut.de> <4BE89E34.3000308@sun.com> Message-ID: <4BE9A7B4.1040103@oracle.com> More info from Hotspot engineers. ---- >Does webstart allow running your own native code in an applet? (Does plugin while >So I am guessing that they have java interfaces using the jvm/JIT > - then gluegen -- how does gluegen work here? Is it precompiled or does it do a translation at run time? > - which talks to OpenCL "C" binaries > - there appear to be a set running on the "host" or main CPU, > including interfacing to the underlying device drivers, such as the amd and nvidia drivers mentioned > - which then can also start OpenCL "C" binaries that run on auxiliary processors like GPUs >So to answer Michael's question from a VM perspective: >It appears that the amd and nvidia native drivers that I would guess they link to in their >"host" code register for the system signals listed below, but don't support signal chaining, >i.e. they are overwriting the jvm's signal handlers. >So - the technical solution for that, assuming we can't change the amd and nvidia drivers, >is to interpose our libjsig.so before their libraries are loaded. This lets our vm chain >their signal handlers, so that the VM only handles signals that apply to the vm and then >calls their signal handlers. >I am guessing they can't link libjsig with their application or he would have done so - but >it is worth first asking why he can't. >If it is the case that he can not, then he needs to setenv LD_PRELOAD /libjsig.so >before starting up java. >Is there a way to do that with WebStart? Is there a way to specify to do that? No - there is no ability to set any env variables before launching java. If jnlp file itself is signed and trusted, you could set system propertys before launching java, but not environmental variables. ----- Paul > A partial answer: one of the Hotspot engineers says > > "I think the short answer is that chaining requires LD_PRELOAD to > override the signal entry points. Otherwise we [Hotspot] wouldn't see > the calls that change the signal handlers. If the Java command itself > linked against jsig that would work too I think. I believe that's the > only way to solve the problem he is seeing in an automatic fashion. > Depending on how the driver library gets loaded they might be able to > build their own signal handler trampolines to work around it and > correct the signal handlers after it gets loaded." > > Regards, > > Paul > > On 5/8/10 7:31 AM, Michael Bien wrote: >> Hello everyone, >> >> i am one of the maintainers of JOGL and wrote JOCL >> (http://jogamp.org/) and we are currently facing some signal handling >> issues caused by the nvidia and amd drivers. >> (I got the hint to post to this list since there is no better alias >> for this kind of topics) >> >> e.g. the nvidia OpenCL driver uses at least the following handlers: >> Warning: SIGSEGV handler expected:libjvm.so+0x5d8cf0 >> found:libnvidia-compiler.so+0x1865e0 >> Warning: SIGILL handler expected:libjvm.so+0x5d8cf0 >> found:libnvidia-compiler.so+0x1865e0 >> Warning: SIGFPE handler expected:libjvm.so+0x5d8cf0 >> found:libnvidia-compiler.so+0x1865e0 >> Warning: SIGBUS handler expected:libjvm.so+0x5d8cf0 >> found:libnvidia-compiler.so+0x1865e0 >> Warning: SIGXFSZ handler expected:libjvm.so+0x5d8cf0 >> found:libnvidia-compiler.so+0x1865e0 >> (-Xcheck:jni) >> >> which basically makes the jvm unusable on Linux and leads to >> segmentation faults (in the driver, I suppose the driver catches jvm >> signals). >> >> LD_PRELOAD >> (http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/signals.html#gbzbl) >> works perfectly but it is not allowed for webstart + applets... >> >> do you have any advice how we could workaround this issue? The >> perfect solution would be a "-XX:enableSignalChaining" flag which we >> could set via jnlp. Since the webstart JVM is out of process anyway >> (since u10 or so) this would probably work. >> >> Why isn't signal chaining enabled by default on linux and solaris? It >> looks like a good self-defence mechanism for me :) >> >> best regards, >> Michael Bien >> >> --- >> >> http://michael-bien.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From kevin.l.stern at gmail.com Wed May 12 00:13:49 2010 From: kevin.l.stern at gmail.com (Kevin L. Stern) Date: Tue, 11 May 2010 19:13:49 -0500 Subject: A List implementation backed by multiple small arrays rather than the traditional single large array. In-Reply-To: References: <1704b7a21003280455u784d4d2ape39a47e2367b79a8@mail.gmail.com> Message-ID: I've been putting together an analysis of the compact deque structure. A very early initial version is available here, https://docs.google.com/fileview?id=0B6brz3MPBDdhN2Q2NWMzZmItNWVhYy00YThjLWIzZTAtMGIwNWZkMjkxZDBh&hl=en. The deque has some interesting properties regarding index array resizing and shifting work as well as merging work, especially when compared to ArrayList. When I can find some time I'll work on a more complete theoretical analysis as well as some practical performance numbers. Regards, Kevin On Wed, Apr 21, 2010 at 5:37 PM, Kevin L. Stern wrote: > Hi Benedict, > > Please forgive my delayed response. I've been working on a new > implementation to offer support for the deque interface per Martin's > suggestion. I have this implementation here > https://docs.google.com/Doc?docid=0Aabrz3MPBDdhZGdrbnEzejdfNGY4NWhzM2Q4&hl=enin case you are interested in taking a look. > > Regards, > > Kevin > > > On Sat, Apr 17, 2010 at 11:48 AM, Benedict Elliott Smith > wrote: > >> Hi Kevin, >> >> As it happens I might have something useful still to contribute. As an >> exercise in saving face I revisited the problem to see if I could achieve >> the same complexity bounds as ChunkedArrayList but with a lower overhead. I >> must admit I still didn't fully appreciate how the algorithm in >> ChunkedArrayList worked until I tried to come up with an algorithm with >> similar properties. What I have ended up with is almost identical except >> adds I think a couple of incremental improvements, simply by redefining the >> arrayIndex() method. I should note that I have not yet implemented more than >> a prototype as it seems to me your implementation is excellent already, and >> if it is decided to include my modifications the changes should be modest. >> >> Firstly, (I hope that) what I have produced is a little more CPU pipe-line >> friendly; there is less dependency on immediately preceding calculations at >> each stage (i.e. so more operations should be able to proceed simultaneously >> in the pipeline), and consists exclusively of shifts, addition/subtraction >> and bit-wise (&)ands (except for the conditionals in >> Integer.numberOfLeadingZeros(i)), although the total number of instructions >> is approximately the same. >> >> Secondly, I have modified the algorithm so that a "seed" size can be >> specified (although I expect hard coding a suitable one will ultimately be >> best). Whereas ChunkedArrayList currently requires that the pattern of array >> allocation sizes be [1, 1, 2, 2, 2, 4(..*6), 8(..*12), 16(..*24)] we can now >> support, for some "*s*", [*s*(..*2), 2*s*(..*3), 4*s*(..*6), 8*s*(..*12), >> 16*s*(..*24)] etc. although when put in simple text like that it does >> appear to trivialise the change. The benefit of this, though, is two fold: >> 1) for small n the constant factor is reduced (both CPU and memory wise); >> and 2) the sqrt(n) bounds are reached more quickly also. >> >> As an illustration, consider setting *s* to 4, and assume the backing >> array is size two and doubles in size with each growth; with >> ChunkedArrayList we would resize at i=2, i=6, i=20, i=72; with *s* as 4 >> we would instead resize at i=8,i=24,i=80,i=288; the cost at each would be >> some multiple of 2,4,8,16 respectively. As you can see the latter is much >> closer to the sqrt(n) cost - both approach it eventually, but my suggestion >> is to reach it more quickly. This is at the expense of more slowly reaching >> the sqrt(n) wasted memory condition, but given the high constant factor cost >> wrt to memory at this early stage, this seems a very sensible trade off. It >> seems likely this should also have a positive impact on cache performance >> for smaller lists as well. >> >> Finally, after playing with this idea in my head I am confident I can >> extend the core ideas of this data structure to hashing relatively easily, >> getting the the same worst case O(sqrt(n)) insertion cost, and O(sqrt(n)) >> wasted memory guarantees. I notice that this case hasn't been addressed yet, >> although I see from Martin's recent mail that this was raised before. Unless >> there are better suggestions for solving the hash table problem I will have >> a go at it as it seems an interesting problem - that is, assuming there are >> no objections? >> >> I'm interested to hear your thoughts. I hope this time I've been a bit >> more considered in what I've put forward, and hence less of a waste of time! >> >> Code snippet for calculation of array index and item offset: >> >> final int arraySizeShiftMinusSeed = ((31 - >> Integer.numberOfLeadingZeros(index >>> seed)) >>> 1) ; >> final int arraySizeShift = arraySizeShiftMinusSeed + seed ; >> final int firstArrayOfThisSize = ((((1 << arraySizeShiftMinusSeed + 3) - >> (1 << arraySizeShiftMinusSeed + 1))) >>> 1) - 1 ; >> final int indexRemainder = index - ((1 << seed) << >> arraySizeShiftMinusSeed + arraySizeShiftMinusSeed) ; >> final int arrayOffset = indexRemainder >>> arraySizeShift ; >> >> final int arrayIndex = firstArrayOfThisSize + arrayOffset ; >> final int itemIndex = index & ((1 << arraySizeShift) - 1) ; >> >> the first array size will be 1 << seed - 1 (i.e. seed is equal to *s* + >> 1); seed only works for values for 2 or more at this moment, fyi >> >> >> >> On 16 April 2010 00:18, Kevin L. Stern wrote: >> >>> Oh no worries Benedict, thanks for your interest in the topic. Let me >>> know if you have any other questions or if you have any related ideas or >>> concerns. >>> >>> >>> On Thu, Apr 15, 2010 at 8:00 AM, Benedict Elliott Smith < >>> lists at laerad.com> wrote: >>> >>>> Sorry Kevin - it sounds like I might be being of more hindrance than >>>> help. that part of the discussion was clearly truncated by the time I had >>>> joined the list - I haven't been able to find the history in the archives >>>> either... >>>> >>>> I was just wondering about the worst case cost of add() as described by >>>> your javadoc; admittedly it is optimal with respect to unused memory, but >>>> the worst case cost of an add is still sqrt(n), with a relatively high >>>> constant factor. I had been thinking that once n passed a threshold the cost >>>> of additions in this other structure would become a constant factor, >>>> offering nice algorithmic complexity guarantees for large n; however since >>>> sqrt(Integer.MAX_VALUE) is ~46,000, the maximum size of new array >>>> allocations would have to be unrealistically small (assuming linear cost for >>>> allocation) for this to be the case. It would still be nice to have a data >>>> structure that avoids needing to copy data with each grow, whilst still >>>> maintaining good memory performance. >>>> >>>> That *all* being said, I had been going by your javadoc and emails to >>>> ascertain the behaviour of this class, as I couldn't locate a free copy >>>> of [Brodnik99resizablearrays], and it seems this was a bad idea; as the >>>> sqrt(n) cost appears to be associated with growing the backing array, rather >>>> than with what I assumed to be copying data between arraylets, and it seems >>>> this cost is pretty optimal. That will teach me to post to a list without >>>> getting my facts straight first. The interesting thing is simply that the >>>> constant factor for this implementation still seems to be quite high, >>>> although perhaps that is simply because I was not benchmarking sufficiently >>>> large values of n. >>>> >>>> >>>> >>>> On 15 April 2010 12:12, Kevin L. Stern wrote: >>>> >>>>> Hi Benedict, >>>>> >>>>> Unless I am misreading your post, this now has a very similar feel to >>>>> the first data structure that I posted to the list. Martin Buchholz then >>>>> pointed out that we can incorporate the ideas from >>>>> [Brodnik99resizablearrays] and reap additional benefits. >>>>> >>>>> Regards, >>>>> >>>>> Kevin >>>>> >>>>> >>>>> On Thu, Apr 15, 2010 at 4:07 AM, Benedict Elliott Smith < >>>>> lists at laerad.com> wrote: >>>>> >>>>>> Hi Kevin, >>>>>> >>>>>> Yes, as I was going to bed last night I realised I had not fully >>>>>> addressed the problem that was originally being visited; only reduced the >>>>>> constant factor for addition to the end of the list. A trivial modification >>>>>> fixes that, however; same scheme but up to some maximum arraylet size (of a >>>>>> power of 2), after which the array is increased in size linearly. >>>>>> Performance doesn't seem to have been affected appreciably, although not >>>>>> been exhaustive in the benchmarking: >>>>>> >>>>>> 10 items inserts versus ArrayList: Chunked=1.15, ExpArray=1.16 >>>>>> 10 items inserts Chunked / ExpArray = 0.99 >>>>>> 10 items get versus ArrayList: Chunked=1.15, ExpArray=1.16 >>>>>> 10 items get Chunked / ExpArray = 0.99 >>>>>> 100 items inserts versus ArrayList: Chunked=1.24, ExpArray=1.01 >>>>>> 100 items inserts Chunked / ExpArray = 1.23 >>>>>> 100 items get versus ArrayList: Chunked=1.24, ExpArray=1.01 >>>>>> 100 items get Chunked / ExpArray = 1.23 >>>>>> 1000 items inserts versus ArrayList: Chunked=1.22, ExpArray=1.03 >>>>>> 1000 items inserts Chunked / ExpArray = 1.19 >>>>>> 1000 items get versus ArrayList: Chunked=1.22, ExpArray=1.03 >>>>>> 1000 items get Chunked / ExpArray = 1.19 >>>>>> 10000 items inserts versus ArrayList: Chunked=1.22, ExpArray=1.03 >>>>>> 10000 items inserts Chunked / ExpArray = 1.18 >>>>>> 10000 items get versus ArrayList: Chunked=1.22, ExpArray=1.03 >>>>>> 10000 items get Chunked / ExpArray = 1.18 >>>>>> 100000 items inserts versus ArrayList: Chunked=0.82, ExpArray=0.75 >>>>>> 100000 items inserts Chunked / ExpArray = 1.09 >>>>>> 100000 items get versus ArrayList: Chunked=0.82, ExpArray=0.75 >>>>>> 100000 items get Chunked / ExpArray = 1.09 >>>>>> >>>>>> The nice thing about this is that the maximum amount of wasted memory >>>>>> is user configurable. Even with a low setting as above (65K) performance >>>>>> seems pretty consistent. >>>>>> >>>>>> Code for calculating index and array offset are pretty straight >>>>>> forward; haven't given much thought to optimisations just yet: >>>>>> >>>>>> private final int indexFor(int a, int i) { >>>>>> return 1 + i - (a > maxArrayIndex ? (1 + a - maxArrayIndex) << >>>>>> maxArraySizeShift : 1 << a) ; >>>>>> } >>>>>> private final int arrayFor(int i) { >>>>>> return i >= (maxArraySize << 1) ? (i + 1 >>> maxArraySizeShift) + >>>>>> maxArrayIndex - 1 : 31 - Integer.numberOfLeadingZeros(i + 1) ; >>>>>> } >>>>>> >>>>>> Regarding the double list idea - yes, I agree, I certainly didn't >>>>>> think that one through fully! >>>>>> >>>>>> >>>>>> >>>>>> On 15 April 2010 02:44, Kevin L. Stern wrote: >>>>>> >>>>>>> Hi Benedict, >>>>>>> >>>>>>> Like you, I am relatively new to this mailing list; I am also trying >>>>>>> to tread lightly so as not to step on any toes. That being said, I think >>>>>>> that I can offer a response to your inquiry. >>>>>>> >>>>>>> Regarding: "The idea is to simply double the new array size each >>>>>>> time a new array needs to be allocated" >>>>>>> >>>>>>> It seems this would not address the desire of offering an alternative >>>>>>> to the allocation of a large backing array for ArrayList (your largest >>>>>>> backing array could still reach a size of 1/2 * Integer.MAX_VALUE) and would >>>>>>> not address the desire of wasting the (asymptotically) minimum amount of >>>>>>> memory in the worst case while maintaining O(1) amortized time bounds. The >>>>>>> data structure described in [Brodnik99resizablearrays] has a maximum backing >>>>>>> array size of sqrt(n) and caps wasted memory at sqrt(n). What advantage >>>>>>> over ArrayList do you see in your data structure? >>>>>>> >>>>>>> Regarding: "Also, with regard to a Deque implementation, it seems >>>>>>> that the simplest solution would be to simply have two lists, with one >>>>>>> accepting inserts for near the beginning and being ordered in reverse whilst >>>>>>> the other accepted inserts for near to the end." >>>>>>> >>>>>>> What happens with your structure when you add n elements and then >>>>>>> remove element 0 n times? I think that once you work out all the kinks >>>>>>> you'll end up with the two stacks approach, which is mentioned in >>>>>>> [Brodnik99resizablearrays] and which I mentioned in an earlier email, or >>>>>>> you'll end up with the circular list approach, which is not friendly to O(1) >>>>>>> amortized time bounds in a data structure that resizes more often than O(n) >>>>>>> due to the 'unshift' to the front = 0 position. I think the best approach >>>>>>> is the one mentioned in [Brodnik99resizablearrays], which is the approach >>>>>>> that I am currently working on. Incidentally, this approach also provides >>>>>>> for a much improved index unpacking procedure using only bit shifts and bit >>>>>>> masks, although it is at the expense of (O(1)) additional work during >>>>>>> resize. >>>>>>> >>>>>>> Regards, >>>>>>> >>>>>>> Kevin >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Wed, Apr 14, 2010 at 4:42 PM, Benedict Elliott Smith < >>>>>>> lists at laerad.com> wrote: >>>>>>> >>>>>>>> Hi, >>>>>>>> >>>>>>>> I hope you don't consider it rude to involve myself in this >>>>>>>> conversation towards the end - I joined the mailing list only recently. >>>>>>>> >>>>>>>> I'm not sure if this offers a huge amount to the discussion, but I >>>>>>>> have tinkered with a "chunked" array list which seems to offer better time >>>>>>>> performance in general at the cost of greater (worst case) memory >>>>>>>> utilisation. It is easier to understand IMHO as well, although this is not >>>>>>>> necessarily a great benefit here. It turns out the idea is very similar to >>>>>>>> the one implemented already by Kevin, though; but perhaps simpler. The idea >>>>>>>> is to simply double the new array size each time a new array needs to be >>>>>>>> allocated, or in effect allocate an array that is the size of all existing >>>>>>>> arrays put together. With this scheme the calculation for array and offset >>>>>>>> are really very straight forward ( floor(log(i)) and 1 + i - >>>>>>>> 2^floor(log(i))) ). Memory utilisation is the same as for ArrayList, but >>>>>>>> obviously inserts at the end are much quicker. >>>>>>>> >>>>>>>> I have prototyped the data structure this evening and benchmarked >>>>>>>> additions at the end of the list, for which the performance is pretty >>>>>>>> impressive. >>>>>>>> >>>>>>>> Some random statistics for addition only on the client JVM (I have >>>>>>>> quickly dubbed my implementation ExpArrayList) >>>>>>>> All statistics were run in two rounds with ~1000 runs per round per >>>>>>>> statistic per list, and the second round results were used. >>>>>>>> >>>>>>>> 10 items versus ArrayList: Chunked=1.14, ExpArray=1.02 >>>>>>>> 10 items Chunked / ExpArray = 1.12 >>>>>>>> 100 items versus ArrayList: Chunked=1.20, ExpArray=0.82 >>>>>>>> 100 items Chunked / ExpArray = 1.45 >>>>>>>> 1000 items versus ArrayList: Chunked=1.03, ExpArray=0.51 >>>>>>>> 1000 items Chunked / ExpArray = 2.02 >>>>>>>> 10000 items versus ArrayList: Chunked=0.88, ExpArray=0.49 >>>>>>>> 10000 items Chunked / ExpArray = 1.79 >>>>>>>> 100000 items versus ArrayList: Chunked=0.32, ExpArray=0.20 >>>>>>>> 100000 items Chunked / ExpArray = 1.64 >>>>>>>> >>>>>>>> and server JVM: >>>>>>>> 10 items versus ArrayList: Chunked=1.00, ExpArray=1.16 >>>>>>>> 10 items Chunked / ExpArray = 0.86 >>>>>>>> 100 items versus ArrayList: Chunked=1.29, ExpArray=0.96 >>>>>>>> 100 items Chunked / ExpArray = 1.34 >>>>>>>> 1000 items versus ArrayList: Chunked=1.16, ExpArray=0.92 >>>>>>>> 1000 items Chunked / ExpArray = 1.27 >>>>>>>> 10000 items versus ArrayList: Chunked=0.93, ExpArray=0.84 >>>>>>>> 10000 items Chunked / ExpArray = 1.12 >>>>>>>> 100000 items versus ArrayList: Chunked=0.71, ExpArray=0.65 >>>>>>>> 100000 items Chunked / ExpArray = 1.10 >>>>>>>> >>>>>>>> Interestingly insertion at the beginning of the list appears to be >>>>>>>> quicker with ExpArrayList, at least on the server JVM, whereas I would have >>>>>>>> expected them to be fairly close. >>>>>>>> Amazingly ExpArrayList is faster even than ArrayList for insertion >>>>>>>> at the beginning of large lists, which I haven't yet tried to understand. >>>>>>>> Insertion in the middle is similar. >>>>>>>> >>>>>>>> 10 items versus ArrayList: Chunked=9.82, ExpArray=3.80 >>>>>>>> 10 items Chunked / ExpArray = 2.59 >>>>>>>> 100 items versus ArrayList: Chunked=7.30, ExpArray=3.41 >>>>>>>> 100 items Chunked / ExpArray = 2.14 >>>>>>>> 1000 items versus ArrayList: Chunked=2.83, ExpArray=1.09 >>>>>>>> 1000 items Chunked / ExpArray = 2.59 >>>>>>>> 10000 items versus ArrayList: Chunked=1.56, ExpArray=0.72 >>>>>>>> 10000 items Chunked / ExpArray = 2.16 >>>>>>>> >>>>>>>> Finally, there are promising results for get() from the ExpArrayList >>>>>>>> as well (server JVM), again somehow beating ArrayList for larger lists: >>>>>>>> 10 items get versus ArrayList: Chunked=1.27, ExpArray=1.16 >>>>>>>> 10 items get Chunked / ExpArray = 1.10 >>>>>>>> 100 items get versus ArrayList: Chunked=1.45, ExpArray=1.17 >>>>>>>> 100 items get Chunked / ExpArray = 1.25 >>>>>>>> 1000 items get versus ArrayList: Chunked=1.42, ExpArray=1.07 >>>>>>>> 1000 items get Chunked / ExpArray = 1.33 >>>>>>>> 10000 items get versus ArrayList: Chunked=1.26, ExpArray=1.02 >>>>>>>> 10000 items get Chunked / ExpArray = 1.24 >>>>>>>> 100000 items get versus ArrayList: Chunked=1.05, ExpArray=0.86 >>>>>>>> 100000 items get Chunked / ExpArray = 1.22 >>>>>>>> >>>>>>>> >>>>>>>> I'm willing to explore this further but I'm not sure how desirable >>>>>>>> that is, given that Kevin's data structure appears to perform pretty well >>>>>>>> already wrt to CPU time, and better wrt to memory utilisation, and in effect >>>>>>>> this mostly changes only the function to determine which array to use, not >>>>>>>> the body of the implementation. Let me know if you would like a copy of the >>>>>>>> source code and I will find somewhere to upload it. >>>>>>>> >>>>>>>> Also, with regard to a Deque implementation, it seems that the >>>>>>>> simplest solution would be to simply have two lists, with one accepting >>>>>>>> inserts for near the beginning and being ordered in reverse whilst the other >>>>>>>> accepted inserts for near to the end. The only trick would be having the >>>>>>>> list at the beginning support iteration in reverse order cheaply, but this >>>>>>>> could easily be achieved by creating an extension of List with a >>>>>>>> reverseIterator() method. >>>>>>>> >>>>>>>> >>>>>>>> Anyway, not sure if this helped at all but fancied joining in... >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> On 14 April 2010 12:25, Joe Kearney wrote: >>>>>>>> >>>>>>>>> Hi Kevin, >>>>>>>>> >>>>>>>>> It implements List, as well as Deque. It is indeed based on >>>>>>>>> ArrayDeque, with the added operations to implement list. It does so >>>>>>>>> reasonably efficiently, moving the fewest elements possible on each >>>>>>>>> operation, that is zero for the queue operations, at most n/2 for the rest >>>>>>>>> and all of them for a backing array resize. >>>>>>>>> >>>>>>>>> The idea is to get a replacement for arraylist that performs like >>>>>>>>> arraydeque on remove(0). As a side effect, we should be able to get better >>>>>>>>> performance on other operations by requiring fewer elements to be moved. >>>>>>>>> >>>>>>>>> Thanks, >>>>>>>>> Joe >>>>>>>>> >>>>>>>>> 2010/4/14 Kevin L. Stern >>>>>>>>> >>>>>>>>> Hi Joe, >>>>>>>>>> >>>>>>>>>> I was referring to the ChunkedArrayList when I stated that add >>>>>>>>>> does not amortize to constant time when the data structure employs the >>>>>>>>>> circular list trick to achieve deque behavior; ChunkedArrayList potentially >>>>>>>>>> resizes every n^(1/2) operations. >>>>>>>>>> >>>>>>>>>> Regarding your CircularArrayList, does it differ from Java's >>>>>>>>>> ArrayDeque? I took only a cursory look at it, so please understand if I >>>>>>>>>> have missed your reason for creating CircularArrayList altogether. >>>>>>>>>> >>>>>>>>>> Regards, >>>>>>>>>> >>>>>>>>>> Kevin >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Tue, Apr 13, 2010 at 6:52 AM, Joe Kearney < >>>>>>>>>> joe.j.kearney at googlemail.com> wrote: >>>>>>>>>> >>>>>>>>>>> Hi Kevin, Martin, >>>>>>>>>>> >>>>>>>>>>> To add another discussion point, I've been writing a >>>>>>>>>>> draft/proof-of-concept of retrofitting the List interface onto ArrayDeque. >>>>>>>>>>> This works over the raw array, it doesn't use the fancier structures being >>>>>>>>>>> discussed elsewhere on this list that deal with splitting huge arrays into >>>>>>>>>>> arraylets, or that provide for O(1) insert in the middle. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> http://code.google.com/p/libjoe/source/browse/trunk/src/joe/collect/CircularArrayList.java >>>>>>>>>>> >>>>>>>>>>> I'd be interested if you have any comments in the context of this >>>>>>>>>>> discussion. The code is not entirely ready yet, a couple of tests fail >>>>>>>>>>> (6/789) because of a corner case I haven't nailed yet, but the idea is there >>>>>>>>>>> at least. I'd like to add array shrinking later, when the size dips below >>>>>>>>>>> capacity*0.4 perhaps, to avoid flickering up and down around... >>>>>>>>>>> >>>>>>>>>>> Tests show performance to be close to ArrayList for the O(1) >>>>>>>>>>> operations. Timings for indexed reads and writes showed >>>>>>>>>>> no discernible difference between implementations last time I ran the >>>>>>>>>>> tests. I don't understand at the moment why the iterator add at index >>>>>>>>>>> size/3, size/2 perform 30% slower than ArrayList on smaller lists, nor the >>>>>>>>>>> dodgy numbers for ArrayList.insert(5), I'll look at this soon. Those >>>>>>>>>>> operations that become O(1) in a circular implementation (that are >>>>>>>>>>> implemented and tested here) are faster than in ArrayList. Insert/remove in >>>>>>>>>>> the middle are somewhat faster than ArrayList because we only have to copy >>>>>>>>>>> at most half of the elements, except when resizing the array. >>>>>>>>>>> >>>>>>>>>>> Kevin, I don't fully understand your point about not amortizing >>>>>>>>>>> to O(1). Certainly that's true for insert not at head or tail. Otherwise >>>>>>>>>>> this implementation only moves array elements to the front on an array >>>>>>>>>>> resize operation which happens every O(ln n) operations at most, if we do >>>>>>>>>>> lots of adds, maybe a little more if we add array shrinking too. This is >>>>>>>>>>> the same as ArrayList. Are you just referring to the add-in-the-middle case? >>>>>>>>>>> >>>>>>>>>>> Some performance results below, code for these is in the >>>>>>>>>>> repository above too. This was the second run, after a warmup. >>>>>>>>>>> >>>>>>>>>>> Thanks, >>>>>>>>>>> Joe >>>>>>>>>>> >>>>>>>>>>> ------------------------------------------------ >>>>>>>>>>> CircularArrayList ------------------------------------------------ >>>>>>>>>>> size add get set iterAdd/3 >>>>>>>>>>> iterAdd/2 insert(5) removeRnd removeMid remove(0) >>>>>>>>>>> 10 20 67 70 125 >>>>>>>>>>> 102 90 240 191 138 >>>>>>>>>>> 100 19 67 70 166 >>>>>>>>>>> 138 94 230 194 118 >>>>>>>>>>> 1000 28 64 67 681 >>>>>>>>>>> 538 91 324 382 119 >>>>>>>>>>> 10000 30 65 67 5884 >>>>>>>>>>> 4425 94 1296 2330 124 >>>>>>>>>>> ---------------------------------------------------- ArrayList >>>>>>>>>>> ---------------------------------------------------- >>>>>>>>>>> size add get set iterAdd/3 >>>>>>>>>>> iterAdd/2 insert(5) removeRnd removeMid remove(0) >>>>>>>>>>> 10 23 68 70 100 >>>>>>>>>>> 69 32913 162 130 105 >>>>>>>>>>> 100 20 67 70 129 >>>>>>>>>>> 104 21944 169 134 135 >>>>>>>>>>> 1000 29 63 67 651 >>>>>>>>>>> 506 9602 364 333 526 >>>>>>>>>>> 10000 30 63 66 5878 >>>>>>>>>>> 4414 9947 2312 2280 4437 >>>>>>>>>>> >>>>>>>>>>> 2010/4/13 Kevin L. Stern >>>>>>>>>>> >>>>>>>>>>> Hi Martin, >>>>>>>>>>>> >>>>>>>>>>>> I had intended to address your request for absolute O(1) >>>>>>>>>>>> operations in the previous email. The approach to achieving this suggested >>>>>>>>>>>> in [Brodnik99resizablearrays] is tantamount to making ArrayList operations >>>>>>>>>>>> absolute O(1) by keeping around an array of size (3/2)*n and filling it with >>>>>>>>>>>> a constant number of entries from the main array each time add is called. >>>>>>>>>>>> Although this distributes the work done during a resize across the n >>>>>>>>>>>> operations required to enter a resize-required state, it is at the expense >>>>>>>>>>>> of additional memory usage and slower add operations. My thought is that >>>>>>>>>>>> this would be a fine approach for a real-time application that requires hard >>>>>>>>>>>> guarantees on performance but would be a liability in so many Java >>>>>>>>>>>> applications that do not require these hard guarantees. I look forward to >>>>>>>>>>>> hearing your thoughts on the matter, though. >>>>>>>>>>>> >>>>>>>>>>>> Kevin >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Tue, Apr 13, 2010 at 6:18 AM, Kevin L. Stern < >>>>>>>>>>>> kevin.l.stern at gmail.com> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi Martin, >>>>>>>>>>>>> >>>>>>>>>>>>> It's interesting to note that the old circular list trick will >>>>>>>>>>>>> not suffice to turn this data structure into a deque since we might be >>>>>>>>>>>>> copying all n elements back to the front = 0 position every n^(1/2) >>>>>>>>>>>>> operations (add wouldn't amortize to O(1)). We could use the old two stacks >>>>>>>>>>>>> trick (push elements onto one stack, flip (the bottom) half (of) the >>>>>>>>>>>>> elements to the 'other' stack when the 'other' stack becomes empty), >>>>>>>>>>>>> mentioned in [Brodnik99resizablearrays], but I find this to be a bit CS >>>>>>>>>>>>> 101. In [Brodnik99resizablearrays] the authors suggest a method for making >>>>>>>>>>>>> all blocks roughly the same size, allowing us to expand/shrink capacity at >>>>>>>>>>>>> the beginning or the end; this is the approach that I will take to create a >>>>>>>>>>>>> deque. >>>>>>>>>>>>> >>>>>>>>>>>>> The FAQ for the Sun Contributor Agreement Q3 ( >>>>>>>>>>>>> http://www.sun.com/software/opensource/contributor_agreement.jsp#sa_3) >>>>>>>>>>>>> indicates that one should check with the project to determine where the SCA >>>>>>>>>>>>> should be sent. Do you know where I would find this information? >>>>>>>>>>>>> >>>>>>>>>>>>> Kevin >>>>>>>>>>>>> >>>>>>>>>>>>> @MISC{Brodnik99resizablearrays, >>>>>>>>>>>>> author = {Andrej Brodnik and Svante Carlsson and Erik D. >>>>>>>>>>>>> Demaine and J. Ian Munro and Robert Sedgewick}, >>>>>>>>>>>>> title = {Resizable Arrays in Optimal Time and Space}, >>>>>>>>>>>>> year = {1999} >>>>>>>>>>>>> >>>>>>>>>>>>> } >>>>>>>>>>>>> >>>>>>>>>>>>> On Sun, Apr 11, 2010 at 4:17 PM, Martin Buchholz < >>>>>>>>>>>>> martinrb at google.com> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Kevin, >>>>>>>>>>>>>> >>>>>>>>>>>>>> Thanks for your continuing work on this. >>>>>>>>>>>>>> >>>>>>>>>>>>>> I like the test results, and agree with your analysis. >>>>>>>>>>>>>> I'm especially happy that you're beating >>>>>>>>>>>>>> ArrayList at some operations. >>>>>>>>>>>>>> >>>>>>>>>>>>>> I'd like to see O(1) addition at the beginning, >>>>>>>>>>>>>> implement both List and Deque (I regret >>>>>>>>>>>>>> our not having done this with ArrayDeque). >>>>>>>>>>>>>> >>>>>>>>>>>>>> An additional property that would be nice to >>>>>>>>>>>>>> have (but don't try too hard) >>>>>>>>>>>>>> is to provide some kind of real-time >>>>>>>>>>>>>> guarantees on the cost of an individual operation, >>>>>>>>>>>>>> not just amortized time. E.g. ArrayList.add >>>>>>>>>>>>>> is worst-case O(n), making it unsuitable for use >>>>>>>>>>>>>> in some real-time applications. >>>>>>>>>>>>>> >>>>>>>>>>>>>> I will help get your changes into the obvious >>>>>>>>>>>>>> software distributions. I assume you're happy >>>>>>>>>>>>>> with having this class included in any of >>>>>>>>>>>>>> Doug Lea's jsr166, guava-libraries, or the JDK itself. >>>>>>>>>>>>>> You should sign a Sun contributor agreement, >>>>>>>>>>>>>> or whatever the Oracle equivalent is, >>>>>>>>>>>>>> if you have not done so yet. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Doug Lea likes public domain, >>>>>>>>>>>>>> guava-libraries likes the Apache license. >>>>>>>>>>>>>> >>>>>>>>>>>>>> We should get various people a chance to give >>>>>>>>>>>>>> a thumbs up on the design of this class - >>>>>>>>>>>>>> Doug Lea, Josh Bloch. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Martin >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Sun, Apr 11, 2010 at 09:32, Kevin L. Stern < >>>>>>>>>>>>>> kevin.l.stern at gmail.com> wrote: >>>>>>>>>>>>>> > Hello Martin, >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > I spent some time this weekend trying to bring out bugs in >>>>>>>>>>>>>> the >>>>>>>>>>>>>> > implementation; I believe the latest version to be in decent >>>>>>>>>>>>>> shape. I have >>>>>>>>>>>>>> > also gathered some data on the performance of >>>>>>>>>>>>>> ChunkedArrayList over >>>>>>>>>>>>>> > ArrayList using the latest 1.6 JDK, which I've included >>>>>>>>>>>>>> below (note that the >>>>>>>>>>>>>> > numbers represent the time spent performing the specified >>>>>>>>>>>>>> operation with >>>>>>>>>>>>>> > ChunkedArrayList over the time spent with ArrayList, so 1.00 >>>>>>>>>>>>>> indicates >>>>>>>>>>>>>> > equivalent performance, < 1.00 indicates that >>>>>>>>>>>>>> ChunkedArrayList is less >>>>>>>>>>>>>> > costly and > 1.00 indicates that ArrayList is less costly). >>>>>>>>>>>>>> I've noticed >>>>>>>>>>>>>> > relatively significant variability in a few of the numbers >>>>>>>>>>>>>> when I switch >>>>>>>>>>>>>> > hardware; though, these data do seem to represent rough >>>>>>>>>>>>>> performance >>>>>>>>>>>>>> > expectations. For my test I generated x elements and then >>>>>>>>>>>>>> timed the process >>>>>>>>>>>>>> > of adding them to ArrayList/ChunkedArrayList, then I >>>>>>>>>>>>>> performed a get >>>>>>>>>>>>>> > operation on each for indices 0 through x-1 and finally I >>>>>>>>>>>>>> used the iterator >>>>>>>>>>>>>> > mechanism to retrieve the first through xth element (of >>>>>>>>>>>>>> course, I performed >>>>>>>>>>>>>> > each of these operations multiple times throwing away the >>>>>>>>>>>>>> timing for the >>>>>>>>>>>>>> > first few iterations to warm up the JVM). >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > Regarding the question of whether or not this belongs in >>>>>>>>>>>>>> java.util, I would >>>>>>>>>>>>>> > suggest that if it is desirable from a GC point of view to >>>>>>>>>>>>>> eliminate the >>>>>>>>>>>>>> > large backing array from ArrayList then your suggestion of >>>>>>>>>>>>>> achieving this by >>>>>>>>>>>>>> > way of a data structure that is both time and space optimal >>>>>>>>>>>>>> is a >>>>>>>>>>>>>> > particularly elegant solution as it not only guarantees that >>>>>>>>>>>>>> no backing >>>>>>>>>>>>>> > array will be larger than sqrt(n) elements but it also >>>>>>>>>>>>>> provides dynamic >>>>>>>>>>>>>> > shrinking behavior, has less maximum memory overhead than >>>>>>>>>>>>>> ArrayList, and >>>>>>>>>>>>>> > copies (asymptotically) fewer elements during a resize than >>>>>>>>>>>>>> ArrayList. Of >>>>>>>>>>>>>> > course, this data structure does not do everything better >>>>>>>>>>>>>> than ArrayList; in >>>>>>>>>>>>>> > particular, indexed access is more costly, due to the >>>>>>>>>>>>>> required decomposition >>>>>>>>>>>>>> > of the index into backing array index and offset and the >>>>>>>>>>>>>> additional memory >>>>>>>>>>>>>> > indirection, and insertion-at-an-index is more costly, due >>>>>>>>>>>>>> to the multiple >>>>>>>>>>>>>> > array copies necessary to complete the shift. That being >>>>>>>>>>>>>> said, I think that >>>>>>>>>>>>>> > the additional cost of indexed access is partially mitigated >>>>>>>>>>>>>> by the >>>>>>>>>>>>>> > availability of iterator and listIterator, whose >>>>>>>>>>>>>> implementations do not use >>>>>>>>>>>>>> > the index decomposition procedure, and the additional cost >>>>>>>>>>>>>> of >>>>>>>>>>>>>> > insertion-at-an-index is partially mitigated by the fact >>>>>>>>>>>>>> that >>>>>>>>>>>>>> > insertion-at-an-index is already an undesirable operation on >>>>>>>>>>>>>> ArrayList due >>>>>>>>>>>>>> > to its linear time complexity. >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > Kevin >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > 1000000 elements: >>>>>>>>>>>>>> > Client JVM: >>>>>>>>>>>>>> > Add to ChunkedArrayList over ArrayList: 1.30 >>>>>>>>>>>>>> > Indexed access ChunkedArrayList over ArrayList: 1.80 >>>>>>>>>>>>>> > Iterator ChunkedArrayList over ArrayList: 0.52 >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > Server JVM: >>>>>>>>>>>>>> > Add to ChunkedArrayList over ArrayList: 0.81 >>>>>>>>>>>>>> > Indexed access ChunkedArrayList over ArrayList: 2.87 >>>>>>>>>>>>>> > Iterator ChunkedArrayList over ArrayList: 1.31 >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > 100000 elements: >>>>>>>>>>>>>> > Client JVM: >>>>>>>>>>>>>> > Add to ChunkedArrayList over ArrayList: 0.96 >>>>>>>>>>>>>> > Indexed access ChunkedArrayList over ArrayList: 1.86 >>>>>>>>>>>>>> > Iterator ChunkedArrayList over ArrayList: 0.48 >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > Server JVM: >>>>>>>>>>>>>> > Add to ChunkedArrayList over ArrayList: 0.96 >>>>>>>>>>>>>> > Indexed access ChunkedArrayList over ArrayList: 1.89 >>>>>>>>>>>>>> > Iterator ChunkedArrayList over ArrayList: 2.68 >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > 10000 elements: >>>>>>>>>>>>>> > Client JVM: >>>>>>>>>>>>>> > Add to ChunkedArrayList over ArrayList: 1.04 >>>>>>>>>>>>>> > Indexed access ChunkedArrayList over ArrayList: 2.33 >>>>>>>>>>>>>> > Iterator ChunkedArrayList over ArrayList: 0.53 >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > Server JVM: >>>>>>>>>>>>>> > Add to ChunkedArrayList over ArrayList: 0.97 >>>>>>>>>>>>>> > Indexed access ChunkedArrayList over ArrayList: 2.45 >>>>>>>>>>>>>> > Iterator ChunkedArrayList over ArrayList: 2.52 >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > 1000 elements: >>>>>>>>>>>>>> > Client JVM: >>>>>>>>>>>>>> > Add to ChunkedArrayList over ArrayList: 0.99 >>>>>>>>>>>>>> > Indexed access ChunkedArrayList over ArrayList: 2.27 >>>>>>>>>>>>>> > Iterator ChunkedArrayList over ArrayList: 0.54 >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > Server JVM: >>>>>>>>>>>>>> > Add to ChunkedArrayList over ArrayList: 0.84 >>>>>>>>>>>>>> > Indexed access ChunkedArrayList over ArrayList: 1.23 >>>>>>>>>>>>>> > Iterator ChunkedArrayList over ArrayList: 1.11 >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > On Fri, Apr 9, 2010 at 7:42 PM, Martin Buchholz < >>>>>>>>>>>>>> martinrb at google.com> wrote: >>>>>>>>>>>>>> >> >>>>>>>>>>>>>> >> My feeling on whether to support O(1) at both ends >>>>>>>>>>>>>> >> is that any flavor of this that ends up in the JDK >>>>>>>>>>>>>> eventually >>>>>>>>>>>>>> >> should really do this. My idea is that we can >>>>>>>>>>>>>> >> wholeheartedly recommend this collection class >>>>>>>>>>>>>> >> for overall good behavior without any of the surprising >>>>>>>>>>>>>> >> performance traps of existing collection classes. >>>>>>>>>>>>>> >> >>>>>>>>>>>>>> >> But for the preliminary version, it makes sense to >>>>>>>>>>>>>> >> support only O(1) at one end, if it simplifies the >>>>>>>>>>>>>> >> implementation. Random access will of course >>>>>>>>>>>>>> >> be worse than ArrayList, but by how much? >>>>>>>>>>>>>> >> We can do some benchmarking and look for >>>>>>>>>>>>>> >> micro-optimizations now. >>>>>>>>>>>>>> >> >>>>>>>>>>>>>> >> Kevin, what is you own personal feeling? >>>>>>>>>>>>>> >> Is the algorithm correct, and efficient enough? >>>>>>>>>>>>>> >> Do you think your new collection belongs in java.util? >>>>>>>>>>>>>> >> >>>>>>>>>>>>>> >> Martin >>>>>>>>>>>>>> >> >>>>>>>>>>>>>> >> On Sun, Apr 4, 2010 at 04:12, Kevin L. Stern < >>>>>>>>>>>>>> kevin.l.stern at gmail.com> >>>>>>>>>>>>>> >> wrote: >>>>>>>>>>>>>> >> > The data structure is available at the second link that I >>>>>>>>>>>>>> originally >>>>>>>>>>>>>> >> > provided (once again, it is >>>>>>>>>>>>>> >> > >>>>>>>>>>>>>> >> > >>>>>>>>>>>>>> https://docs.google.com/Doc?docid=0Aabrz3MPBDdhZGdrbnEzejdfM2M3am5wM2Mz&hl=en >>>>>>>>>>>>>> ). >>>>>>>>>>>>>> >> > This does not have O(1) time insertion at the front as >>>>>>>>>>>>>> yet as it was >>>>>>>>>>>>>> >> > unclear >>>>>>>>>>>>>> >> > to me whether or not it was agreed upon: >>>>>>>>>>>>>> >> > _________________ >>>>>>>>>>>>>> >> > From: Osvaldo Doederlein >>>>>>>>>>>>>> >> > Date: Mon, Mar 29, 2010 at 10:08 AM >>>>>>>>>>>>>> >> > Subject: Re: A List implementation backed by multiple >>>>>>>>>>>>>> small arrays >>>>>>>>>>>>>> >> > rather >>>>>>>>>>>>>> >> > than the traditional single large array. >>>>>>>>>>>>>> >> > To: Martin Buchholz >>>>>>>>>>>>>> >> > Cc: "Kevin L. Stern" , >>>>>>>>>>>>>> >> > core-libs-dev at openjdk.java.net >>>>>>>>>>>>>> >> > >>>>>>>>>>>>>> >> > Initially, it would be good enough to replace only >>>>>>>>>>>>>> java.util.ArrayList >>>>>>>>>>>>>> >> > with >>>>>>>>>>>>>> >> > minimal overhead. ArrayList does not support efficient >>>>>>>>>>>>>> add-at-front or >>>>>>>>>>>>>> >> > other >>>>>>>>>>>>>> >> > enhancements of ArrayDeque; but ArrayList is still a much >>>>>>>>>>>>>> more important >>>>>>>>>>>>>> >> > and >>>>>>>>>>>>>> >> > popular collection, it's the primary "straight >>>>>>>>>>>>>> replacement for primitive >>>>>>>>>>>>>> >> > arrrays" and I guess it should continue with that role. >>>>>>>>>>>>>> >> > _________________ >>>>>>>>>>>>>> >> > >>>>>>>>>>>>>> >> > As a disclaimer, I'm still tinkering with this so I'll be >>>>>>>>>>>>>> updating the >>>>>>>>>>>>>> >> > document at the provided link as I find improvements. >>>>>>>>>>>>>> >> > >>>>>>>>>>>>>> >> > Thoughts? >>>>>>>>>>>>>> >> > >>>>>>>>>>>>>> >> > Thanks, >>>>>>>>>>>>>> >> > >>>>>>>>>>>>>> >> > Kevin >>>>>>>>>>>>>> >> > >>>>>>>>>>>>>> >> > On Thu, Apr 1, 2010 at 10:28 PM, Martin Buchholz < >>>>>>>>>>>>>> martinrb at google.com> >>>>>>>>>>>>>> >> > wrote: >>>>>>>>>>>>>> >> >> >>>>>>>>>>>>>> >> >> Hi Kevin, >>>>>>>>>>>>>> >> >> >>>>>>>>>>>>>> >> >> You're probably the only one on this list who has >>>>>>>>>>>>>> >> >> seriously read the paper. It is not surprising that >>>>>>>>>>>>>> >> >> taking a research paper into production would >>>>>>>>>>>>>> >> >> discover bugs - the research never had to undergo >>>>>>>>>>>>>> >> >> rigorous testing. (I like the Java culture of >>>>>>>>>>>>>> >> >> combining spec + implementation + test suite) >>>>>>>>>>>>>> >> >> >>>>>>>>>>>>>> >> >> I suggest you ask the authors directly about the bug. >>>>>>>>>>>>>> >> >> They would probably also be interested to hear >>>>>>>>>>>>>> >> >> about your implementation. >>>>>>>>>>>>>> >> >> >>>>>>>>>>>>>> >> >> Are you aware of Integer.numberOfLeadingZeros? >>>>>>>>>>>>>> >> >> >>>>>>>>>>>>>> >> >> >>>>>>>>>>>>>> >> >> >>>>>>>>>>>>>> http://download.java.net/jdk7/docs/api/java/lang/Integer.html#numberOfLeadingZeros(int) >>>>>>>>>>>>>> >> >> >>>>>>>>>>>>>> >> >> Martin >>>>>>>>>>>>>> >> >> >>>>>>>>>>>>>> >> >> On Wed, Mar 31, 2010 at 19:34, Kevin L. Stern < >>>>>>>>>>>>>> kevin.l.stern at gmail.com> >>>>>>>>>>>>>> >> >> wrote: >>>>>>>>>>>>>> >> >> > I'm almost convinced now that the paper is incorrect. >>>>>>>>>>>>>> The code below >>>>>>>>>>>>>> >> >> > gives >>>>>>>>>>>>>> >> >> > me the appropriate index into the index array and the >>>>>>>>>>>>>> offset into the >>>>>>>>>>>>>> >> >> > data >>>>>>>>>>>>>> >> >> > block. That being said, remember when I mentioned >>>>>>>>>>>>>> that this will >>>>>>>>>>>>>> >> >> > include a >>>>>>>>>>>>>> >> >> > bit more work to access an element than a simple bit >>>>>>>>>>>>>> shift and a bit >>>>>>>>>>>>>> >> >> > mask? >>>>>>>>>>>>>> >> >> > Well this is more than a bit more - we'll be doing >>>>>>>>>>>>>> this each time an >>>>>>>>>>>>>> >> >> > index >>>>>>>>>>>>>> >> >> > is requested. I'll spend some time trying to twiddle >>>>>>>>>>>>>> the bits to see >>>>>>>>>>>>>> >> >> > if >>>>>>>>>>>>>> >> >> > I >>>>>>>>>>>>>> >> >> > can eliminate/combine some of the operations. >>>>>>>>>>>>>> >> >> > >>>>>>>>>>>>>> >> >> > for (int r = 1; r < 33; r++) { >>>>>>>>>>>>>> >> >> > int k = lg(r); >>>>>>>>>>>>>> >> >> > int floorKO2 = k >> 1; >>>>>>>>>>>>>> >> >> > int powFloorKO2 = (1 << floorKO2); >>>>>>>>>>>>>> >> >> > int p = ((1 << floorKO2) - 1) << 1; >>>>>>>>>>>>>> >> >> > int ceilKO2; >>>>>>>>>>>>>> >> >> > if ((k & 1) == 1) { >>>>>>>>>>>>>> >> >> > ceilKO2 = floorKO2 + 1; >>>>>>>>>>>>>> >> >> > p += powFloorKO2; >>>>>>>>>>>>>> >> >> > } else { >>>>>>>>>>>>>> >> >> > ceilKO2 = floorKO2; >>>>>>>>>>>>>> >> >> > } >>>>>>>>>>>>>> >> >> > int e = r & ((1 << ceilKO2) - 1); >>>>>>>>>>>>>> >> >> > int b = (r >> ceilKO2) & (powFloorKO2 - >>>>>>>>>>>>>> 1); >>>>>>>>>>>>>> >> >> > >>>>>>>>>>>>>> >> >> > System.out.println((r - 1) + " " + (p + b) >>>>>>>>>>>>>> + " " + e); >>>>>>>>>>>>>> >> >> > } >>>>>>>>>>>>>> >> >> > >>>>>>>>>>>>>> >> >> > Kevin >>>>>>>>>>>>>> >> >> > >>>>>>>>>>>>>> >> >> > On Wed, Mar 31, 2010 at 7:08 PM, Kevin L. Stern >>>>>>>>>>>>>> >> >> > >>>>>>>>>>>>>> >> >> > wrote: >>>>>>>>>>>>>> >> >> >> >>>>>>>>>>>>>> >> >> >> I realize that 2 * (2^(k/2) - 1) only works for even >>>>>>>>>>>>>> numbered >>>>>>>>>>>>>> >> >> >> superblocks, >>>>>>>>>>>>>> >> >> >> the odd numbered superblocks need an additional term >>>>>>>>>>>>>> added (the >>>>>>>>>>>>>> >> >> >> number >>>>>>>>>>>>>> >> >> >> of >>>>>>>>>>>>>> >> >> >> data blocks in SB_[k-1]) to jive with my >>>>>>>>>>>>>> interpretation; anyhow, I >>>>>>>>>>>>>> >> >> >> also >>>>>>>>>>>>>> >> >> >> came >>>>>>>>>>>>>> >> >> >> across an alternative characterization of superblock >>>>>>>>>>>>>> in the paper >>>>>>>>>>>>>> >> >> >> which >>>>>>>>>>>>>> >> >> >> states that data blocks are grouped within a >>>>>>>>>>>>>> superblock when they >>>>>>>>>>>>>> >> >> >> are >>>>>>>>>>>>>> >> >> >> the >>>>>>>>>>>>>> >> >> >> same size - to me, though, that implies that my >>>>>>>>>>>>>> example structure >>>>>>>>>>>>>> >> >> >> below >>>>>>>>>>>>>> >> >> >> would be >>>>>>>>>>>>>> >> >> >> >>>>>>>>>>>>>> >> >> >> SB_0: [1] >>>>>>>>>>>>>> >> >> >> SB_1: [2][2][2] >>>>>>>>>>>>>> >> >> >> SB_2: [4][4][4][4][4][4] >>>>>>>>>>>>>> >> >> >> >>>>>>>>>>>>>> >> >> >> which seems to contradict my understanding of (1) >>>>>>>>>>>>>> below. I must be >>>>>>>>>>>>>> >> >> >> reading this upside down. >>>>>>>>>>>>>> >> >> >> >>>>>>>>>>>>>> >> >> >> On Wed, Mar 31, 2010 at 6:36 PM, Kevin L. Stern >>>>>>>>>>>>>> >> >> >> >>>>>>>>>>>>>> >> >> >> wrote: >>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>> >> >> >>> What am I missing here? In "Resizable arrays in >>>>>>>>>>>>>> optimal time and >>>>>>>>>>>>>> >> >> >>> space" >>>>>>>>>>>>>> >> >> >>> the authors define their data structure with the >>>>>>>>>>>>>> following >>>>>>>>>>>>>> >> >> >>> property: >>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>> >> >> >>> (1) "When superblock SB_k is fully allocated, it >>>>>>>>>>>>>> consists of >>>>>>>>>>>>>> >> >> >>> 2^(floor(k/2)) data blocks, each of size >>>>>>>>>>>>>> 2^(ceil(k/2))." >>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>> >> >> >>> Since the superblock is zero-based indexed this >>>>>>>>>>>>>> implies the >>>>>>>>>>>>>> >> >> >>> following >>>>>>>>>>>>>> >> >> >>> structure: >>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>> >> >> >>> SB_0: [1] >>>>>>>>>>>>>> >> >> >>> SB_1: [2] >>>>>>>>>>>>>> >> >> >>> SB_2: [2][2] >>>>>>>>>>>>>> >> >> >>> SB_3: [4][4] >>>>>>>>>>>>>> >> >> >>> SB_4: [4][4][4][4] >>>>>>>>>>>>>> >> >> >>> [...] >>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>> >> >> >>> Let's have a look at Algorithm 3, Locate(i), with i >>>>>>>>>>>>>> = 3: >>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>> >> >> >>> r = 100 (the binary expansion of i + 1) >>>>>>>>>>>>>> >> >> >>> k = |r| - 1 = 2 >>>>>>>>>>>>>> >> >> >>> p = 2^k - 1 = 3 >>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>> >> >> >>> What concerns me is their statement that p >>>>>>>>>>>>>> represents "the number >>>>>>>>>>>>>> >> >> >>> of >>>>>>>>>>>>>> >> >> >>> data >>>>>>>>>>>>>> >> >> >>> blocks in superblocks prior to SB_k." There are >>>>>>>>>>>>>> only two data >>>>>>>>>>>>>> >> >> >>> blocks >>>>>>>>>>>>>> >> >> >>> in >>>>>>>>>>>>>> >> >> >>> superblocks prior to SB_2, not three. Given (1) >>>>>>>>>>>>>> above, unless I'm >>>>>>>>>>>>>> >> >> >>> misinterpreting it, the number of data blocks in >>>>>>>>>>>>>> superblocks prior >>>>>>>>>>>>>> >> >> >>> to >>>>>>>>>>>>>> >> >> >>> SB_k >>>>>>>>>>>>>> >> >> >>> should be: >>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>> >> >> >>> 2 * Sum[i=0->k/2-1] 2^i = 2 * (2^(k/2) - 1) >>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>> >> >> >>> This, of course, seems to work out much better in my >>>>>>>>>>>>>> example above, >>>>>>>>>>>>>> >> >> >>> giving the correct answer to my interpretation of >>>>>>>>>>>>>> their data >>>>>>>>>>>>>> >> >> >>> structure, but >>>>>>>>>>>>>> >> >> >>> I have a hard time believing that this is their >>>>>>>>>>>>>> mistake rather than >>>>>>>>>>>>>> >> >> >>> my >>>>>>>>>>>>>> >> >> >>> misinterpretation. >>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>> >> >> >>> Thoughts? >>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>> >> >> >>> Kevin >>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>> >> >> >>> On Tue, Mar 30, 2010 at 5:20 PM, Martin Buchholz >>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>> >> >> >>> wrote: >>>>>>>>>>>>>> >> >> >>>> >>>>>>>>>>>>>> >> >> >>>> On Tue, Mar 30, 2010 at 04:25, Kevin L. Stern >>>>>>>>>>>>>> >> >> >>>> >>>>>>>>>>>>>> >> >> >>>> wrote: >>>>>>>>>>>>>> >> >> >>>> > Hi Martin, >>>>>>>>>>>>>> >> >> >>>> > >>>>>>>>>>>>>> >> >> >>>> > Thanks much for your feedback. The first >>>>>>>>>>>>>> approach that comes to >>>>>>>>>>>>>> >> >> >>>> > mind >>>>>>>>>>>>>> >> >> >>>> > to >>>>>>>>>>>>>> >> >> >>>> > implement O(1) time front as well as rear >>>>>>>>>>>>>> insertion is to create >>>>>>>>>>>>>> >> >> >>>> > a >>>>>>>>>>>>>> >> >> >>>> > cyclic >>>>>>>>>>>>>> >> >> >>>> > list structure with a front/rear pointer - to >>>>>>>>>>>>>> insert at the >>>>>>>>>>>>>> >> >> >>>> > front >>>>>>>>>>>>>> >> >> >>>> > requires >>>>>>>>>>>>>> >> >> >>>> > decrementing the front pointer (modulo the size) >>>>>>>>>>>>>> and to insert >>>>>>>>>>>>>> >> >> >>>> > at >>>>>>>>>>>>>> >> >> >>>> > the >>>>>>>>>>>>>> >> >> >>>> > rear >>>>>>>>>>>>>> >> >> >>>> > requires incrementing the rear pointer (modulo >>>>>>>>>>>>>> the size). We >>>>>>>>>>>>>> >> >> >>>> > need >>>>>>>>>>>>>> >> >> >>>> > to >>>>>>>>>>>>>> >> >> >>>> > resize >>>>>>>>>>>>>> >> >> >>>> > when the two pointers bump into each other. >>>>>>>>>>>>>> Could you explain >>>>>>>>>>>>>> >> >> >>>> > more >>>>>>>>>>>>>> >> >> >>>> > about >>>>>>>>>>>>>> >> >> >>>> > your suggestion of introducing an arraylet that >>>>>>>>>>>>>> is shared by the >>>>>>>>>>>>>> >> >> >>>> > front >>>>>>>>>>>>>> >> >> >>>> > and >>>>>>>>>>>>>> >> >> >>>> > the rear? >>>>>>>>>>>>>> >> >> >>>> >>>>>>>>>>>>>> >> >> >>>> It was a half-baked idea - I don't know if there's >>>>>>>>>>>>>> a way to turn >>>>>>>>>>>>>> >> >> >>>> it >>>>>>>>>>>>>> >> >> >>>> into >>>>>>>>>>>>>> >> >> >>>> something useful. I was thinking of the ArrayDeque >>>>>>>>>>>>>> >> >> >>>> implementation, >>>>>>>>>>>>>> >> >> >>>> where all the elements live in a single array. >>>>>>>>>>>>>> >> >> >>>> >>>>>>>>>>>>>> >> >> >>>> > It's not clear to me how that would help and/or >>>>>>>>>>>>>> be a better >>>>>>>>>>>>>> >> >> >>>> > approach than the cyclic list. Anyhow, the paper >>>>>>>>>>>>>> that you >>>>>>>>>>>>>> >> >> >>>> > reference, >>>>>>>>>>>>>> >> >> >>>> > "Resizable arrays in optimal time and space", >>>>>>>>>>>>>> gives a deque so >>>>>>>>>>>>>> >> >> >>>> > if >>>>>>>>>>>>>> >> >> >>>> > we >>>>>>>>>>>>>> >> >> >>>> > take >>>>>>>>>>>>>> >> >> >>>> > that approach then the deque is specified. >>>>>>>>>>>>>> >> >> >>>> >>>>>>>>>>>>>> >> >> >>>> Technically, ArrayList also supports the Deque >>>>>>>>>>>>>> operations - >>>>>>>>>>>>>> >> >> >>>> just not efficiently. >>>>>>>>>>>>>> >> >> >>> >>>>>>>>>>>>>> >> >> >> >>>>>>>>>>>>>> >> >> > >>>>>>>>>>>>>> >> >> > >>>>>>>>>>>>>> >> > >>>>>>>>>>>>>> >> > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dmytro_sheyko at hotmail.com Wed May 12 10:04:52 2010 From: dmytro_sheyko at hotmail.com (Dmytro Sheyko) Date: Wed, 12 May 2010 17:04:52 +0700 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: , Message-ID: Vladimir, Your changes are good for me. Additionally I have some comments/proposals regarding dealing with negative zeros. 1. Scanning for the first zero we can avoid range check (i >= left) if we have at least one negative value. --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 +++ DualPivotQuicksortS.java Wed May 12 12:10:46 2010 @@ -1705,10 +1705,15 @@ } // Find first zero element - int zeroIndex = findAnyZero(a, left, n); + int zeroIndex = 0; - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { - zeroIndex = i; + if (a[left] < 0.0f) { + zeroIndex = findAnyZero(a, left, n); + + // there is at least one negative value, so range check is not needed + for (int i = zeroIndex - 1; /*i >= left &&*/ a[i] == 0.0f; i--) { + zeroIndex = i; + } } // Turn the right number of positive zeros back into negative zeros 2. We can find the position of the first zero by counting negative values during preprocessing phase. --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 +++ DualPivotQuicksortC.java Wed May 12 12:01:24 2010 @@ -1678,7 +1678,7 @@ * Phase 1: Count negative zeros and move NaNs to end of array. */ final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f); - int numNegativeZeros = 0; + int numNegativeZeros = 0, numNegativeValues = 0; int n = right; for (int k = left; k <= n; k++) { @@ -1689,6 +1689,8 @@ } else if (ak != ak) { // i.e., ak is NaN a[k--] = a[n]; a[n--] = Float.NaN; + } else if (ak < 0.0f) { + numNegativeValues++; } } @@ -1705,7 +1707,7 @@ } // Find first zero element - int zeroIndex = findAnyZero(a, left, n); + int zeroIndex = numNegativeValues; for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { zeroIndex = i; 3. We can use binary search to find the first zero and thus avoid linear scan. --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 +++ DualPivotQuicksortF.java Wed May 12 12:03:58 2010 @@ -1705,11 +1705,7 @@ } // Find first zero element - int zeroIndex = findAnyZero(a, left, n); - - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { - zeroIndex = i; - } + int zeroIndex = findFirstZero(a, left, n); // Turn the right number of positive zeros back into negative zeros for (int i = zeroIndex, m = zeroIndex + numNegativeZeros; i < m; i++) { @@ -1718,7 +1714,7 @@ } /** - * Returns the index of some zero element in the specified range via + * Returns the index of the first zero element in the specified range via * binary search. The range is assumed to be sorted, and must contain * at least one zero. * @@ -1726,18 +1722,17 @@ * @param low the index of the first element, inclusive, to be searched * @param high the index of the last element, inclusive, to be searched */ - private static int findAnyZero(float[] a, int low, int high) { - while (true) { + private static int findFirstZero(float[] a, int low, int high) { + while (low < high) { int middle = (low + high) >>> 1; float middleValue = a[middle]; if (middleValue < 0.0f) { low = middle + 1; - } else if (middleValue > 0.0f) { - high = middle - 1; - } else { // middleValue == 0.0f - return middle; + } else { // middleValue >= 0.0f + high = middle; } + return low; } } Counting negative values appeared more expensive than any other variants. The last proposal seems to me as efficient as the current solution is in its worst case - when we have only one negative zero (in the half of array). And it shows the best result if we have many zeros. Regards, Dmytro Sheyko > From: iaroslavski at mail.ru > To: jjb at google.com; dmytro_sheyko at hotmail.com > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > Subject: Re[2]: New portion of improvements for Dual-Pivot Quicksort > Date: Sun, 9 May 2010 23:51:27 +0400 > > Josh, > Dmytro, > > I have done more thoroughly testing "great - less > 5 * seventh" vs. "less < e1 && great > e5", > and found that more symmetric code "less < e1 && great > e5" is little bit faster, ~0.5..0.7% > on both VMs. Other code has not been changed. > > Please, take the latest version in attachment. > > Vladimir > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua Bloch : > > > Vladimir, > > > > Old: > > > >298 if (less < e1 && great > e5) { > > > > New: > > > >256 if (great - less > 5 * seventh) { > > >Regards, > >Josh _________________________________________________________________ Hotmail: Powerful Free email with security by Microsoft. https://signup.live.com/signup.aspx?id=60969 -------------- next part -------------- An HTML attachment was scrubbed... URL: From iaroslavski at mail.ru Wed May 12 10:12:47 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Wed, 12 May 2010 14:12:47 +0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: Message-ID: <4BEA7F1F.6010606@mail.ru> Hello Dmytro, Could you please send new version of DPQ with your changes? Thanks, Vladimir Dmytro Sheyko wrote: > Vladimir, > > Your changes are good for me. > > Additionally I have some comments/proposals regarding dealing with > negative zeros. > > 1. Scanning for the first zero we can avoid range check (i >= left) if > we have at least one negative value. > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 2010 > @@ -1705,10 +1705,15 @@ > } > > // Find first zero element > - int zeroIndex = findAnyZero(a, left, n); > + int zeroIndex = 0; > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > - zeroIndex = i; > + if (a[left] < 0.0f) { > + zeroIndex = findAnyZero(a, left, n); > + > + // there is at least one negative value, so range check is > not needed > + for (int i = zeroIndex - 1; /*i >= left &&*/ a[i] == 0.0f; > i--) { > + zeroIndex = i; > + } > } > > // Turn the right number of positive zeros back into negative zeros > > 2. We can find the position of the first zero by counting negative > values during preprocessing phase. > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 2010 > @@ -1678,7 +1678,7 @@ > * Phase 1: Count negative zeros and move NaNs to end of array. > */ > final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f); > - int numNegativeZeros = 0; > + int numNegativeZeros = 0, numNegativeValues = 0; > int n = right; > > for (int k = left; k <= n; k++) { > @@ -1689,6 +1689,8 @@ > } else if (ak != ak) { // i.e., ak is NaN > a[k--] = a[n]; > a[n--] = Float.NaN; > + } else if (ak < 0.0f) { > + numNegativeValues++; > } > } > > @@ -1705,7 +1707,7 @@ > } > > // Find first zero element > - int zeroIndex = findAnyZero(a, left, n); > + int zeroIndex = numNegativeValues; > > for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > zeroIndex = i; > > 3. We can use binary search to find the first zero and thus avoid linear > scan. > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 2010 > @@ -1705,11 +1705,7 @@ > } > > // Find first zero element > - int zeroIndex = findAnyZero(a, left, n); > - > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > - zeroIndex = i; > - } > + int zeroIndex = findFirstZero(a, left, n); > > // Turn the right number of positive zeros back into negative zeros > for (int i = zeroIndex, m = zeroIndex + numNegativeZeros; i < > m; i++) { > @@ -1718,7 +1714,7 @@ > } > > /** > - * Returns the index of some zero element in the specified range via > + * Returns the index of the first zero element in the specified > range via > * binary search. The range is assumed to be sorted, and must contain > * at least one zero. > * > @@ -1726,18 +1722,17 @@ > * @param low the index of the first element, inclusive, to be searched > * @param high the index of the last element, inclusive, to be searched > */ > - private static int findAnyZero(float[] a, int low, int high) { > - while (true) { > + private static int findFirstZero(float[] a, int low, int high) { > + while (low < high) { > int middle = (low + high) >>> 1; > float middleValue = a[middle]; > > if (middleValue < 0.0f) { > low = middle + 1; > - } else if (middleValue > 0.0f) { > - high = middle - 1; > - } else { // middleValue == 0.0f > - return middle; > + } else { // middleValue >= 0.0f > + high = middle; > } > + return low; > } > } > > Counting negative values appeared more expensive than any other variants. > The last proposal seems to me as efficient as the current solution is in > its worst case - when we have only one negative zero (in the half of array). > And it shows the best result if we have many zeros. > > Regards, > Dmytro Sheyko > > > From: iaroslavski at mail.ru > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > Subject: Re[2]: New portion of improvements for Dual-Pivot Quicksort > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > > Josh, > > Dmytro, > > > > I have done more thoroughly testing "great - less > 5 * seventh" vs. > "less < e1 && great > e5", > > and found that more symmetric code "less < e1 && great > e5" is > little bit faster, ~0.5..0.7% > > on both VMs. Other code has not been changed. > > > > Please, take the latest version in attachment. > > > > Vladimir > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua Bloch : > > > > > Vladimir, > > > > > > Old: > > > > > >298 if (less < e1 && great > e5) { > > > > > > New: > > > > > >256 if (great - less > 5 * seventh) { > > > > >Regards, > > >Josh From dmytro_sheyko at hotmail.com Wed May 12 11:18:18 2010 From: dmytro_sheyko at hotmail.com (Dmytro Sheyko) Date: Wed, 12 May 2010 18:18:18 +0700 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: <4BEA7F1F.6010606@mail.ru> References: , , , <4BEA7F1F.6010606@mail.ru> Message-ID: Sure. > Date: Wed, 12 May 2010 14:12:47 +0400 > From: iaroslavski at mail.ru > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > To: dmytro_sheyko at hotmail.com > CC: jjb at google.com; core-libs-dev at openjdk.java.net > > Hello Dmytro, > > Could you please send new version of DPQ > with your changes? > > Thanks, > Vladimir > > Dmytro Sheyko wrote: > > Vladimir, > > > > Your changes are good for me. > > > > Additionally I have some comments/proposals regarding dealing with > > negative zeros. > > > > 1. Scanning for the first zero we can avoid range check (i >= left) if > > we have at least one negative value. > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 2010 > > @@ -1705,10 +1705,15 @@ > > } > > > > // Find first zero element > > - int zeroIndex = findAnyZero(a, left, n); > > + int zeroIndex = 0; > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > - zeroIndex = i; > > + if (a[left] < 0.0f) { > > + zeroIndex = findAnyZero(a, left, n); > > + > > + // there is at least one negative value, so range check is > > not needed > > + for (int i = zeroIndex - 1; /*i >= left &&*/ a[i] == 0.0f; > > i--) { > > + zeroIndex = i; > > + } > > } > > > > // Turn the right number of positive zeros back into negative zeros > > > > 2. We can find the position of the first zero by counting negative > > values during preprocessing phase. > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 2010 > > @@ -1678,7 +1678,7 @@ > > * Phase 1: Count negative zeros and move NaNs to end of array. > > */ > > final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f); > > - int numNegativeZeros = 0; > > + int numNegativeZeros = 0, numNegativeValues = 0; > > int n = right; > > > > for (int k = left; k <= n; k++) { > > @@ -1689,6 +1689,8 @@ > > } else if (ak != ak) { // i.e., ak is NaN > > a[k--] = a[n]; > > a[n--] = Float.NaN; > > + } else if (ak < 0.0f) { > > + numNegativeValues++; > > } > > } > > > > @@ -1705,7 +1707,7 @@ > > } > > > > // Find first zero element > > - int zeroIndex = findAnyZero(a, left, n); > > + int zeroIndex = numNegativeValues; > > > > for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > zeroIndex = i; > > > > 3. We can use binary search to find the first zero and thus avoid linear > > scan. > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 2010 > > @@ -1705,11 +1705,7 @@ > > } > > > > // Find first zero element > > - int zeroIndex = findAnyZero(a, left, n); > > - > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > - zeroIndex = i; > > - } > > + int zeroIndex = findFirstZero(a, left, n); > > > > // Turn the right number of positive zeros back into negative zeros > > for (int i = zeroIndex, m = zeroIndex + numNegativeZeros; i < > > m; i++) { > > @@ -1718,7 +1714,7 @@ > > } > > > > /** > > - * Returns the index of some zero element in the specified range via > > + * Returns the index of the first zero element in the specified > > range via > > * binary search. The range is assumed to be sorted, and must contain > > * at least one zero. > > * > > @@ -1726,18 +1722,17 @@ > > * @param low the index of the first element, inclusive, to be searched > > * @param high the index of the last element, inclusive, to be searched > > */ > > - private static int findAnyZero(float[] a, int low, int high) { > > - while (true) { > > + private static int findFirstZero(float[] a, int low, int high) { > > + while (low < high) { > > int middle = (low + high) >>> 1; > > float middleValue = a[middle]; > > > > if (middleValue < 0.0f) { > > low = middle + 1; > > - } else if (middleValue > 0.0f) { > > - high = middle - 1; > > - } else { // middleValue == 0.0f > > - return middle; > > + } else { // middleValue >= 0.0f > > + high = middle; > > } > > + return low; > > } > > } > > > > Counting negative values appeared more expensive than any other variants. > > The last proposal seems to me as efficient as the current solution is in > > its worst case - when we have only one negative zero (in the half of array). > > And it shows the best result if we have many zeros. > > > > Regards, > > Dmytro Sheyko > > > > > From: iaroslavski at mail.ru > > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > Subject: Re[2]: New portion of improvements for Dual-Pivot Quicksort > > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > > > > Josh, > > > Dmytro, > > > > > > I have done more thoroughly testing "great - less > 5 * seventh" vs. > > "less < e1 && great > e5", > > > and found that more symmetric code "less < e1 && great > e5" is > > little bit faster, ~0.5..0.7% > > > on both VMs. Other code has not been changed. > > > > > > Please, take the latest version in attachment. > > > > > > Vladimir > > > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua Bloch : > > > > > > > Vladimir, > > > > > > > > Old: > > > > > > > >298 if (less < e1 && great > e5) { > > > > > > > > New: > > > > > > > >256 if (great - less > 5 * seventh) { > > > > > > >Regards, > > > >Josh _________________________________________________________________ Hotmail: Free, trusted and rich email service. https://signup.live.com/signup.aspx?id=60969 -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: dpq.zip Type: application/x-zip-compressed Size: 20912 bytes Desc: not available URL: From iaroslavski at mail.ru Wed May 12 13:37:40 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Wed, 12 May 2010 17:37:40 +0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: Message-ID: <4BEAAF24.9020207@mail.ru> Hello Dmytro, Thank you for reviewing float/double section! I'll look at your code and run tests tomorrow and let you know results. Best regards, Vladimir Dmytro Sheyko wrote: > Vladimir, > > Your changes are good for me. > > Additionally I have some comments/proposals regarding dealing with > negative zeros. > > 1. Scanning for the first zero we can avoid range check (i >= left) if > we have at least one negative value. > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 2010 > @@ -1705,10 +1705,15 @@ > } > > // Find first zero element > - int zeroIndex = findAnyZero(a, left, n); > + int zeroIndex = 0; > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > - zeroIndex = i; > + if (a[left] < 0.0f) { > + zeroIndex = findAnyZero(a, left, n); > + > + // there is at least one negative value, so range check is > not needed > + for (int i = zeroIndex - 1; /*i >= left &&*/ a[i] == 0.0f; > i--) { > + zeroIndex = i; > + } > } > > // Turn the right number of positive zeros back into negative zeros > > 2. We can find the position of the first zero by counting negative > values during preprocessing phase. > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 2010 > @@ -1678,7 +1678,7 @@ > * Phase 1: Count negative zeros and move NaNs to end of array. > */ > final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f); > - int numNegativeZeros = 0; > + int numNegativeZeros = 0, numNegativeValues = 0; > int n = right; > > for (int k = left; k <= n; k++) { > @@ -1689,6 +1689,8 @@ > } else if (ak != ak) { // i.e., ak is NaN > a[k--] = a[n]; > a[n--] = Float.NaN; > + } else if (ak < 0.0f) { > + numNegativeValues++; > } > } > > @@ -1705,7 +1707,7 @@ > } > > // Find first zero element > - int zeroIndex = findAnyZero(a, left, n); > + int zeroIndex = numNegativeValues; > > for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > zeroIndex = i; > > 3. We can use binary search to find the first zero and thus avoid linear > scan. > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 2010 > @@ -1705,11 +1705,7 @@ > } > > // Find first zero element > - int zeroIndex = findAnyZero(a, left, n); > - > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > - zeroIndex = i; > - } > + int zeroIndex = findFirstZero(a, left, n); > > // Turn the right number of positive zeros back into negative zeros > for (int i = zeroIndex, m = zeroIndex + numNegativeZeros; i < > m; i++) { > @@ -1718,7 +1714,7 @@ > } > > /** > - * Returns the index of some zero element in the specified range via > + * Returns the index of the first zero element in the specified > range via > * binary search. The range is assumed to be sorted, and must contain > * at least one zero. > * > @@ -1726,18 +1722,17 @@ > * @param low the index of the first element, inclusive, to be searched > * @param high the index of the last element, inclusive, to be searched > */ > - private static int findAnyZero(float[] a, int low, int high) { > - while (true) { > + private static int findFirstZero(float[] a, int low, int high) { > + while (low < high) { > int middle = (low + high) >>> 1; > float middleValue = a[middle]; > > if (middleValue < 0.0f) { > low = middle + 1; > - } else if (middleValue > 0.0f) { > - high = middle - 1; > - } else { // middleValue == 0.0f > - return middle; > + } else { // middleValue >= 0.0f > + high = middle; > } > + return low; > } > } > > Counting negative values appeared more expensive than any other variants. > The last proposal seems to me as efficient as the current solution is in > its worst case - when we have only one negative zero (in the half of array). > And it shows the best result if we have many zeros. > > Regards, > Dmytro Sheyko > > > From: iaroslavski at mail.ru > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > Subject: Re[2]: New portion of improvements for Dual-Pivot Quicksort > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > > Josh, > > Dmytro, > > > > I have done more thoroughly testing "great - less > 5 * seventh" vs. > "less < e1 && great > e5", > > and found that more symmetric code "less < e1 && great > e5" is > little bit faster, ~0.5..0.7% > > on both VMs. Other code has not been changed. > > > > Please, take the latest version in attachment. > > > > Vladimir > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua Bloch : > > > > > Vladimir, > > > > > > Old: > > > > > >298 if (less < e1 && great > e5) { > > > > > > New: > > > > > >256 if (great - less > 5 * seventh) { > > > > >Regards, > > >Josh From mandy.chung at oracle.com Wed May 12 21:59:02 2010 From: mandy.chung at oracle.com (mandy.chung at oracle.com) Date: Wed, 12 May 2010 21:59:02 +0000 Subject: hg: jdk7/tl/jdk: 6951661: Eliminate jvmstat dependency on sun.management.counter Message-ID: <20100512215934.B77B244564@hg.openjdk.java.net> Changeset: 05c9ff89bcdc Author: mchung Date: 2010-05-12 14:41 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/05c9ff89bcdc 6951661: Eliminate jvmstat dependency on sun.management.counter Summary: jvmstat keeps its own copy of Units and Variability class Reviewed-by: alanb ! src/share/classes/sun/jvmstat/monitor/AbstractMonitor.java ! src/share/classes/sun/jvmstat/monitor/Monitor.java + src/share/classes/sun/jvmstat/monitor/Units.java + src/share/classes/sun/jvmstat/monitor/Variability.java ! src/share/classes/sun/jvmstat/perfdata/monitor/PerfByteArrayMonitor.java ! src/share/classes/sun/jvmstat/perfdata/monitor/PerfIntegerMonitor.java ! src/share/classes/sun/jvmstat/perfdata/monitor/PerfLongMonitor.java ! src/share/classes/sun/jvmstat/perfdata/monitor/PerfStringConstantMonitor.java ! src/share/classes/sun/jvmstat/perfdata/monitor/PerfStringMonitor.java ! src/share/classes/sun/jvmstat/perfdata/monitor/PerfStringVariableMonitor.java ! src/share/classes/sun/jvmstat/perfdata/monitor/v1_0/PerfDataBuffer.java ! src/share/classes/sun/jvmstat/perfdata/monitor/v2_0/PerfDataBuffer.java ! src/share/classes/sun/tools/jstat/ExpressionResolver.java ! src/share/classes/sun/tools/jstat/JStatLogger.java ! src/share/classes/sun/tools/jstat/Jstat.java From xueming.shen at oracle.com Wed May 12 22:51:58 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Wed, 12 May 2010 15:51:58 -0700 Subject: 4813885: RFE: GZIPOutputStream should implement flush using Z_SYNC_FLUSH Message-ID: <4BEB310E.5090602@oracle.com> Martin, Would you please help review the change for 4813885: RFE: GZIPOutputStream should implement flush using Z_SYNC_FLUSH http://cr.openjdk.java.net/~sherman/4813885/webrev It appears people want to have the same flush option in GZIPOutputStream as the one we provided in DeflaterOutputStream for #4206909 a while ago, the webrev for 4206909 is at http://cr.openjdk.java.net/~sherman/4206909/webrev Thanks, -Sherman From David.Holmes at oracle.com Thu May 13 00:31:16 2010 From: David.Holmes at oracle.com (David Holmes) Date: Thu, 13 May 2010 10:31:16 +1000 Subject: Bugs in java.util.ArrayList, java.util.Hashtable and java.io.ByteArrayOutputStream In-Reply-To: <4BC82FFF.20502@oracle.com> References: <1704b7a21003031741m734545f1gb0170ed5fa6f6d68@mail.gmail.com> <1ccfd1c11003050104u61e776apc5fe2e5ec08e3dc0@mail.gmail.com> <1704b7a21003050248k1e893cedmd14f26cbecd45896@mail.gmail.com> <1ccfd1c11003081810u54fb22e6k25230f4eb5ca1b18@mail.gmail.com> <4B9633EA.8070101@sun.com> <4BC82FFF.20502@oracle.com> Message-ID: <4BEB4854.7000403@oracle.com> Chris, Martin, The changes to AbstractStringBuilder violate the specification for ensureCapacity: it has to grow from N to 2N+2. The new code in: http://hg.openjdk.java.net/jdk7/tl-gate/jdk/rev/ec45423a4700 void expandCapacity(int minimumCapacity) { - int newCapacity = (value.length + 1) * 2; + int newCapacity = value.length * 2; Has dropped the +2 part. This is causing test failures. David ----- Chris Hegarty said the following on 04/16/10 19:38: > > Martin Buchholz wrote: >> Hi Chris, >> >> I recently discovered another place to handle huge arrays better - in >> AbstractCollection. >> I've put those changes into >> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize2/ >> I propose to qfold these into the original changes for this bug >> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize/ >> which have not yet been committed. > > Good catch Martin, these additional changes look good. > > -Chris. > >> >> Martin >> >> On Tue, Mar 9, 2010 at 04:41, Christopher Hegarty -Sun Microsystems >> Ireland wrote: >>> Sorry Martin, I appear to have missed your original request to file this >>> bug. I since filed the following: >>> >>> 6933217: Huge arrays handled poorly in core libraries >>> >>> The changes you are proposing seem reasonable to me. >>> >>> -Chris. >>> >>> Martin Buchholz wrote: >>>> [Chris or Alan, please review and file a bug] >>>> >>>> OK, guys, >>>> >>>> Here's a patch: >>>> >>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize/ >>>> >>>> Martin >>>> >>>> On Fri, Mar 5, 2010 at 02:48, Kevin L. Stern >>>> wrote: >>>>> Hi Martin, >>>>> >>>>> Thank you for your reply. If I may, PriorityQueue appears to >>>>> employ the >>>>> simple strategy that I suggested above in its grow method: >>>>> >>>>> int newCapacity = ((oldCapacity < 64)? >>>>> ((oldCapacity + 1) * 2): >>>>> ((oldCapacity / 2) * 3)); >>>>> if (newCapacity < 0) // overflow >>>>> newCapacity = Integer.MAX_VALUE; >>>>> >>>>> It might be desirable to set a common strategy for capacity >>>>> increase for >>>>> all >>>>> collections. >>>>> >>>>> Regards, >>>>> >>>>> Kevin >>>>> >>>>> On Fri, Mar 5, 2010 at 3:04 AM, Martin Buchholz >>>>> wrote: >>>>>> Hi Kevin, >>>>>> >>>>>> As you've noticed, creating objects within a factor of two of >>>>>> their natural limits is a good way to expose lurking bugs. >>>>>> >>>>>> I'm the one responsible for the algorithm in ArrayList. >>>>>> I'm a bit embarrassed, looking at that code today. >>>>>> We could set the array size to Integer.MAX_VALUE, >>>>>> but then you might hit an independent buglet in hotspot >>>>>> that you cannot allocate an array with Integer.MAX_VALUE >>>>>> elements, but Integer.MAX_VALUE - 5 (or so) works. >>>>>> >>>>>> It occurs to me that increasing the size by 50% is better done by >>>>>> int newCapacity = oldCapacity + (oldCapacity >> 1) + 1; >>>>>> >>>>>> I agree with the plan of setting the capacity to something near >>>>>> MAX_VALUE on overflow, and throw OutOfMemoryError on next resize. >>>>>> >>>>>> These bugs are not known. >>>>>> Chris Hegarty, could you file a bug for us? >>>>>> >>>>>> Martin >>>>>> >>>>>> On Wed, Mar 3, 2010 at 17:41, Kevin L. Stern >>>>>> >>>>>> wrote: >>>>>>> Greetings, >>>>>>> >>>>>>> I've noticed bugs in java.util.ArrayList, java.util.Hashtable and >>>>>>> java.io.ByteArrayOutputStream which arise when the capacities of the >>>>>>> data >>>>>>> structures reach a particular threshold. More below. >>>>>>> >>>>>>> When the capacity of an ArrayList reaches (2/3)*Integer.MAX_VALUE >>>>>>> its >>>>>>> size >>>>>>> reaches its capacity and an add or an insert operation is >>>>>>> invoked, the >>>>>>> capacity is increased by only one element. Notice that in the >>>>>>> following >>>>>>> excerpt from ArrayList.ensureCapacity the new capacity is set to >>>>>>> (3/2) >>>>>>> * >>>>>>> oldCapacity + 1 unless this value would not suffice to >>>>>>> accommodate the >>>>>>> required capacity in which case it is set to the required >>>>>>> capacity. If >>>>>>> the >>>>>>> current capacity is at least (2/3)*Integer.MAX_VALUE, then >>>>>>> (oldCapacity >>>>>>> * >>>>>>> 3)/2 + 1 overflows and resolves to a negative number resulting in >>>>>>> the >>>>>>> new >>>>>>> capacity being set to the required capacity. The major >>>>>>> consequence of >>>>>>> this >>>>>>> is that each subsequent add/insert operation results in a full >>>>>>> resize >>>>>>> of >>>>>>> the >>>>>>> ArrayList causing performance to degrade significantly. >>>>>>> >>>>>>> int newCapacity = (oldCapacity * 3)/2 + 1; >>>>>>> if (newCapacity < minCapacity) >>>>>>> newCapacity = minCapacity; >>>>>>> >>>>>>> Hashtable breaks entirely when the size of its backing array reaches >>>>>>> (1/2) * >>>>>>> Integer.MAX_VALUE and a rehash is necessary as is evident from the >>>>>>> following >>>>>>> excerpt from rehash. Notice that rehash will attempt to create an >>>>>>> array >>>>>>> of >>>>>>> negative size if the size of the backing array reaches (1/2) * >>>>>>> Integer.MAX_VALUE since oldCapacity * 2 + 1 overflows and >>>>>>> resolves to a >>>>>>> negative number. >>>>>>> >>>>>>> int newCapacity = oldCapacity * 2 + 1; >>>>>>> HashtableEntry newTable[] = new HashtableEntry[newCapacity]; >>>>>>> >>>>>>> When the capacity of the backing array in a ByteArrayOutputStream >>>>>>> reaches >>>>>>> (1/2) * Integer.MAX_VALUE its size reaches its capacity and a write >>>>>>> operation is invoked, the capacity of the backing array is increased >>>>>>> only by >>>>>>> the required number of elements. Notice that in the following >>>>>>> excerpt >>>>>>> from >>>>>>> ByteArrayOutputStream.write(int) the new backing array capacity >>>>>>> is set >>>>>>> to 2 >>>>>>> * buf.length unless this value would not suffice to accommodate the >>>>>>> required >>>>>>> capacity in which case it is set to the required capacity. If the >>>>>>> current >>>>>>> backing array capacity is at least (1/2) * Integer.MAX_VALUE + 1, >>>>>>> then >>>>>>> buf.length << 1 overflows and resolves to a negative number >>>>>>> resulting >>>>>>> in >>>>>>> the >>>>>>> new capacity being set to the required capacity. The major >>>>>>> consequence >>>>>>> of >>>>>>> this, like with ArrayList, is that each subsequent write operation >>>>>>> results >>>>>>> in a full resize of the ByteArrayOutputStream causing performance to >>>>>>> degrade >>>>>>> significantly. >>>>>>> >>>>>>> int newcount = count + 1; >>>>>>> if (newcount > buf.length) { >>>>>>> buf = Arrays.copyOf(buf, Math.max(buf.length << 1, >>>>>>> newcount)); >>>>>>> } >>>>>>> >>>>>>> It is interesting to note that any statements about the amortized >>>>>>> time >>>>>>> complexity of add/insert operations, such as the one in the >>>>>>> ArrayList >>>>>>> javadoc, are invalidated by the performance related bugs. One >>>>>>> solution >>>>>>> to >>>>>>> the above situations is to set the new capacity of the backing >>>>>>> array to >>>>>>> Integer.MAX_VALUE when the initial size calculation results in a >>>>>>> negative >>>>>>> number during a resize. >>>>>>> >>>>>>> Apologies if these bugs are already known. >>>>>>> >>>>>>> Regards, >>>>>>> >>>>>>> Kevin >>>>>>> From kelly.ohair at oracle.com Thu May 13 00:52:58 2010 From: kelly.ohair at oracle.com (Kelly O'Hair) Date: Wed, 12 May 2010 17:52:58 -0700 Subject: Bugs in java.util.ArrayList, java.util.Hashtable and java.io.ByteArrayOutputStream In-Reply-To: <4BEB4854.7000403@oracle.com> References: <1704b7a21003031741m734545f1gb0170ed5fa6f6d68@mail.gmail.com> <1ccfd1c11003050104u61e776apc5fe2e5ec08e3dc0@mail.gmail.com> <1704b7a21003050248k1e893cedmd14f26cbecd45896@mail.gmail.com> <1ccfd1c11003081810u54fb22e6k25230f4eb5ca1b18@mail.gmail.com> <4B9633EA.8070101@sun.com> <4BC82FFF.20502@oracle.com> <4BEB4854.7000403@oracle.com> Message-ID: If it helps, I found an open test that should demonstrate it: http://www.sourceware.org/cgi-bin/cvsweb.cgi/mauve/gnu/testlet/java/lang/StringBuffer/StringBufferTest.java?rev=1.7&content-type=text/x-cvsweb-markup&cvsroot=mauve -kto On May 12, 2010, at 5:31 PM, David Holmes wrote: > Chris, Martin, > > The changes to AbstractStringBuilder violate the specification for > ensureCapacity: it has to grow from N to 2N+2. The new code in: > > http://hg.openjdk.java.net/jdk7/tl-gate/jdk/rev/ec45423a4700 > > void expandCapacity(int minimumCapacity) { > - int newCapacity = (value.length + 1) * 2; > + int newCapacity = value.length * 2; > > Has dropped the +2 part. > > This is causing test failures. > > David > ----- > > Chris Hegarty said the following on 04/16/10 19:38: >> Martin Buchholz wrote: >>> Hi Chris, >>> >>> I recently discovered another place to handle huge arrays better - >>> in >>> AbstractCollection. >>> I've put those changes into >>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize2/ >>> I propose to qfold these into the original changes for this bug >>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize/ >>> which have not yet been committed. >> Good catch Martin, these additional changes look good. >> -Chris. >>> >>> Martin >>> >>> On Tue, Mar 9, 2010 at 04:41, Christopher Hegarty -Sun Microsystems >>> Ireland wrote: >>>> Sorry Martin, I appear to have missed your original request to >>>> file this >>>> bug. I since filed the following: >>>> >>>> 6933217: Huge arrays handled poorly in core libraries >>>> >>>> The changes you are proposing seem reasonable to me. >>>> >>>> -Chris. >>>> >>>> Martin Buchholz wrote: >>>>> [Chris or Alan, please review and file a bug] >>>>> >>>>> OK, guys, >>>>> >>>>> Here's a patch: >>>>> >>>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize/ >>>>> >>>>> Martin >>>>> >>>>> On Fri, Mar 5, 2010 at 02:48, Kevin L. Stern >>>> > >>>>> wrote: >>>>>> Hi Martin, >>>>>> >>>>>> Thank you for your reply. If I may, PriorityQueue appears to >>>>>> employ the >>>>>> simple strategy that I suggested above in its grow method: >>>>>> >>>>>> int newCapacity = ((oldCapacity < 64)? >>>>>> ((oldCapacity + 1) * 2): >>>>>> ((oldCapacity / 2) * 3)); >>>>>> if (newCapacity < 0) // overflow >>>>>> newCapacity = Integer.MAX_VALUE; >>>>>> >>>>>> It might be desirable to set a common strategy for capacity >>>>>> increase for >>>>>> all >>>>>> collections. >>>>>> >>>>>> Regards, >>>>>> >>>>>> Kevin >>>>>> >>>>>> On Fri, Mar 5, 2010 at 3:04 AM, Martin Buchholz >>>>> > >>>>>> wrote: >>>>>>> Hi Kevin, >>>>>>> >>>>>>> As you've noticed, creating objects within a factor of two of >>>>>>> their natural limits is a good way to expose lurking bugs. >>>>>>> >>>>>>> I'm the one responsible for the algorithm in ArrayList. >>>>>>> I'm a bit embarrassed, looking at that code today. >>>>>>> We could set the array size to Integer.MAX_VALUE, >>>>>>> but then you might hit an independent buglet in hotspot >>>>>>> that you cannot allocate an array with Integer.MAX_VALUE >>>>>>> elements, but Integer.MAX_VALUE - 5 (or so) works. >>>>>>> >>>>>>> It occurs to me that increasing the size by 50% is better done >>>>>>> by >>>>>>> int newCapacity = oldCapacity + (oldCapacity >> 1) + 1; >>>>>>> >>>>>>> I agree with the plan of setting the capacity to something near >>>>>>> MAX_VALUE on overflow, and throw OutOfMemoryError on next >>>>>>> resize. >>>>>>> >>>>>>> These bugs are not known. >>>>>>> Chris Hegarty, could you file a bug for us? >>>>>>> >>>>>>> Martin >>>>>>> >>>>>>> On Wed, Mar 3, 2010 at 17:41, Kevin L. Stern >>>>>> > >>>>>>> wrote: >>>>>>>> Greetings, >>>>>>>> >>>>>>>> I've noticed bugs in java.util.ArrayList, java.util.Hashtable >>>>>>>> and >>>>>>>> java.io.ByteArrayOutputStream which arise when the capacities >>>>>>>> of the >>>>>>>> data >>>>>>>> structures reach a particular threshold. More below. >>>>>>>> >>>>>>>> When the capacity of an ArrayList reaches >>>>>>>> (2/3)*Integer.MAX_VALUE its >>>>>>>> size >>>>>>>> reaches its capacity and an add or an insert operation is >>>>>>>> invoked, the >>>>>>>> capacity is increased by only one element. Notice that in the >>>>>>>> following >>>>>>>> excerpt from ArrayList.ensureCapacity the new capacity is set >>>>>>>> to (3/2) >>>>>>>> * >>>>>>>> oldCapacity + 1 unless this value would not suffice to >>>>>>>> accommodate the >>>>>>>> required capacity in which case it is set to the required >>>>>>>> capacity. If >>>>>>>> the >>>>>>>> current capacity is at least (2/3)*Integer.MAX_VALUE, then >>>>>>>> (oldCapacity >>>>>>>> * >>>>>>>> 3)/2 + 1 overflows and resolves to a negative number >>>>>>>> resulting in the >>>>>>>> new >>>>>>>> capacity being set to the required capacity. The major >>>>>>>> consequence of >>>>>>>> this >>>>>>>> is that each subsequent add/insert operation results in a >>>>>>>> full resize >>>>>>>> of >>>>>>>> the >>>>>>>> ArrayList causing performance to degrade significantly. >>>>>>>> >>>>>>>> int newCapacity = (oldCapacity * 3)/2 + 1; >>>>>>>> if (newCapacity < minCapacity) >>>>>>>> newCapacity = minCapacity; >>>>>>>> >>>>>>>> Hashtable breaks entirely when the size of its backing array >>>>>>>> reaches >>>>>>>> (1/2) * >>>>>>>> Integer.MAX_VALUE and a rehash is necessary as is evident >>>>>>>> from the >>>>>>>> following >>>>>>>> excerpt from rehash. Notice that rehash will attempt to >>>>>>>> create an >>>>>>>> array >>>>>>>> of >>>>>>>> negative size if the size of the backing array reaches (1/2) * >>>>>>>> Integer.MAX_VALUE since oldCapacity * 2 + 1 overflows and >>>>>>>> resolves to a >>>>>>>> negative number. >>>>>>>> >>>>>>>> int newCapacity = oldCapacity * 2 + 1; >>>>>>>> HashtableEntry newTable[] = new HashtableEntry[newCapacity]; >>>>>>>> >>>>>>>> When the capacity of the backing array in a >>>>>>>> ByteArrayOutputStream >>>>>>>> reaches >>>>>>>> (1/2) * Integer.MAX_VALUE its size reaches its capacity and a >>>>>>>> write >>>>>>>> operation is invoked, the capacity of the backing array is >>>>>>>> increased >>>>>>>> only by >>>>>>>> the required number of elements. Notice that in the >>>>>>>> following excerpt >>>>>>>> from >>>>>>>> ByteArrayOutputStream.write(int) the new backing array >>>>>>>> capacity is set >>>>>>>> to 2 >>>>>>>> * buf.length unless this value would not suffice to >>>>>>>> accommodate the >>>>>>>> required >>>>>>>> capacity in which case it is set to the required capacity. >>>>>>>> If the >>>>>>>> current >>>>>>>> backing array capacity is at least (1/2) * Integer.MAX_VALUE >>>>>>>> + 1, then >>>>>>>> buf.length << 1 overflows and resolves to a negative number >>>>>>>> resulting >>>>>>>> in >>>>>>>> the >>>>>>>> new capacity being set to the required capacity. The major >>>>>>>> consequence >>>>>>>> of >>>>>>>> this, like with ArrayList, is that each subsequent write >>>>>>>> operation >>>>>>>> results >>>>>>>> in a full resize of the ByteArrayOutputStream causing >>>>>>>> performance to >>>>>>>> degrade >>>>>>>> significantly. >>>>>>>> >>>>>>>> int newcount = count + 1; >>>>>>>> if (newcount > buf.length) { >>>>>>>> buf = Arrays.copyOf(buf, Math.max(buf.length << 1, >>>>>>>> newcount)); >>>>>>>> } >>>>>>>> >>>>>>>> It is interesting to note that any statements about the >>>>>>>> amortized time >>>>>>>> complexity of add/insert operations, such as the one in the >>>>>>>> ArrayList >>>>>>>> javadoc, are invalidated by the performance related bugs. >>>>>>>> One solution >>>>>>>> to >>>>>>>> the above situations is to set the new capacity of the >>>>>>>> backing array to >>>>>>>> Integer.MAX_VALUE when the initial size calculation results >>>>>>>> in a >>>>>>>> negative >>>>>>>> number during a resize. >>>>>>>> >>>>>>>> Apologies if these bugs are already known. >>>>>>>> >>>>>>>> Regards, >>>>>>>> >>>>>>>> Kevin >>>>>>>> From martinrb at google.com Thu May 13 01:23:45 2010 From: martinrb at google.com (Martin Buchholz) Date: Wed, 12 May 2010 18:23:45 -0700 Subject: Bugs in java.util.ArrayList, java.util.Hashtable and java.io.ByteArrayOutputStream In-Reply-To: <4BEB4854.7000403@oracle.com> References: <1704b7a21003031741m734545f1gb0170ed5fa6f6d68@mail.gmail.com> <1ccfd1c11003050104u61e776apc5fe2e5ec08e3dc0@mail.gmail.com> <1704b7a21003050248k1e893cedmd14f26cbecd45896@mail.gmail.com> <1ccfd1c11003081810u54fb22e6k25230f4eb5ca1b18@mail.gmail.com> <4B9633EA.8070101@sun.com> <4BC82FFF.20502@oracle.com> <4BEB4854.7000403@oracle.com> Message-ID: Alright, I'm convinced this is a bug. Please file one in bugtraq (or expunge from tl in the unlikely event that would be permitted). It appears we very carefully specified the capacity manipulation behavior, but didn't have any jtreg tests for it. Do y'all run the Mauve tests? (Probably a good idea) Martin On Wed, May 12, 2010 at 17:31, David Holmes wrote: > Chris, Martin, > > The changes to AbstractStringBuilder violate the specification for > ensureCapacity: it has to grow from N to 2N+2. The new code in: > > http://hg.openjdk.java.net/jdk7/tl-gate/jdk/rev/ec45423a4700 > > ?void expandCapacity(int minimumCapacity) { > - int newCapacity = (value.length + 1) * 2; > + int newCapacity = value.length * 2; > > Has dropped the +2 part. > > This is causing test failures. > > David > ----- > > Chris Hegarty said the following on 04/16/10 19:38: >> >> Martin Buchholz wrote: >>> >>> Hi Chris, >>> >>> I recently discovered another place to handle huge arrays better - in >>> AbstractCollection. >>> I've put those changes into >>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize2/ >>> I propose to qfold these into the original changes for this bug >>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize/ >>> which have not yet been committed. >> >> Good catch Martin, these additional changes look good. >> >> -Chris. >> >>> >>> Martin >>> >>> On Tue, Mar 9, 2010 at 04:41, Christopher Hegarty -Sun Microsystems >>> Ireland wrote: >>>> >>>> Sorry Martin, I appear to have missed your original request to file this >>>> bug. I since filed the following: >>>> >>>> ?6933217: Huge arrays handled poorly in core libraries >>>> >>>> The changes you are proposing seem reasonable to me. >>>> >>>> -Chris. >>>> >>>> Martin Buchholz wrote: >>>>> >>>>> [Chris or Alan, please review and file a bug] >>>>> >>>>> OK, guys, >>>>> >>>>> Here's a patch: >>>>> >>>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize/ >>>>> >>>>> Martin >>>>> >>>>> On Fri, Mar 5, 2010 at 02:48, Kevin L. Stern >>>>> wrote: >>>>>> >>>>>> Hi Martin, >>>>>> >>>>>> Thank you for your reply. ?If I may, PriorityQueue appears to employ >>>>>> the >>>>>> simple strategy that I suggested above in its grow method: >>>>>> >>>>>> ? ? ? int newCapacity = ((oldCapacity < 64)? >>>>>> ? ? ? ? ? ? ? ? ? ? ? ? ?((oldCapacity + 1) * 2): >>>>>> ? ? ? ? ? ? ? ? ? ? ? ? ?((oldCapacity / 2) * 3)); >>>>>> ? ? ? if (newCapacity < 0) // overflow >>>>>> ? ? ? ? ? newCapacity = Integer.MAX_VALUE; >>>>>> >>>>>> It might be desirable to set a common strategy for capacity increase >>>>>> for >>>>>> all >>>>>> collections. >>>>>> >>>>>> Regards, >>>>>> >>>>>> Kevin >>>>>> >>>>>> On Fri, Mar 5, 2010 at 3:04 AM, Martin Buchholz >>>>>> wrote: >>>>>>> >>>>>>> Hi Kevin, >>>>>>> >>>>>>> As you've noticed, creating objects within a factor of two of >>>>>>> their natural limits is a good way to expose lurking bugs. >>>>>>> >>>>>>> I'm the one responsible for the algorithm in ArrayList. >>>>>>> I'm a bit embarrassed, looking at that code today. >>>>>>> We could set the array size to Integer.MAX_VALUE, >>>>>>> but then you might hit an independent buglet in hotspot >>>>>>> that you cannot allocate an array with Integer.MAX_VALUE >>>>>>> elements, but Integer.MAX_VALUE - 5 (or so) works. >>>>>>> >>>>>>> It occurs to me that increasing the size by 50% is better done by >>>>>>> int newCapacity = oldCapacity + (oldCapacity >> 1) + 1; >>>>>>> >>>>>>> I agree with the plan of setting the capacity to something near >>>>>>> MAX_VALUE on overflow, and throw OutOfMemoryError on next resize. >>>>>>> >>>>>>> These bugs are not known. >>>>>>> Chris Hegarty, could you file a bug for us? >>>>>>> >>>>>>> Martin >>>>>>> >>>>>>> On Wed, Mar 3, 2010 at 17:41, Kevin L. Stern >>>>>>> >>>>>>> wrote: >>>>>>>> >>>>>>>> Greetings, >>>>>>>> >>>>>>>> I've noticed bugs in java.util.ArrayList, java.util.Hashtable and >>>>>>>> java.io.ByteArrayOutputStream which arise when the capacities of the >>>>>>>> data >>>>>>>> structures reach a particular threshold. ?More below. >>>>>>>> >>>>>>>> When the capacity of an ArrayList reaches (2/3)*Integer.MAX_VALUE >>>>>>>> its >>>>>>>> size >>>>>>>> reaches its capacity and an add or an insert operation is invoked, >>>>>>>> the >>>>>>>> capacity is increased by only one element. ?Notice that in the >>>>>>>> following >>>>>>>> excerpt from ArrayList.ensureCapacity the new capacity is set to >>>>>>>> (3/2) >>>>>>>> * >>>>>>>> oldCapacity + 1 unless this value would not suffice to accommodate >>>>>>>> the >>>>>>>> required capacity in which case it is set to the required capacity. >>>>>>>> ?If >>>>>>>> the >>>>>>>> current capacity is at least (2/3)*Integer.MAX_VALUE, then >>>>>>>> (oldCapacity >>>>>>>> * >>>>>>>> 3)/2 + 1 overflows and resolves to a negative number resulting in >>>>>>>> the >>>>>>>> new >>>>>>>> capacity being set to the required capacity. ?The major consequence >>>>>>>> of >>>>>>>> this >>>>>>>> is that each subsequent add/insert operation results in a full >>>>>>>> resize >>>>>>>> of >>>>>>>> the >>>>>>>> ArrayList causing performance to degrade significantly. >>>>>>>> >>>>>>>> ? ? ? int newCapacity = (oldCapacity * 3)/2 + 1; >>>>>>>> ? ? ? ? ? if (newCapacity < minCapacity) >>>>>>>> ? ? ? newCapacity = minCapacity; >>>>>>>> >>>>>>>> Hashtable breaks entirely when the size of its backing array reaches >>>>>>>> (1/2) * >>>>>>>> Integer.MAX_VALUE and a rehash is necessary as is evident from the >>>>>>>> following >>>>>>>> excerpt from rehash. ?Notice that rehash will attempt to create an >>>>>>>> array >>>>>>>> of >>>>>>>> negative size if the size of the backing array reaches (1/2) * >>>>>>>> Integer.MAX_VALUE since oldCapacity * 2 + 1 overflows and resolves >>>>>>>> to a >>>>>>>> negative number. >>>>>>>> >>>>>>>> ? int newCapacity = oldCapacity * 2 + 1; >>>>>>>> ? HashtableEntry newTable[] = new HashtableEntry[newCapacity]; >>>>>>>> >>>>>>>> When the capacity of the backing array in a ByteArrayOutputStream >>>>>>>> reaches >>>>>>>> (1/2) * Integer.MAX_VALUE its size reaches its capacity and a write >>>>>>>> operation is invoked, the capacity of the backing array is increased >>>>>>>> only by >>>>>>>> the required number of elements. ?Notice that in the following >>>>>>>> excerpt >>>>>>>> from >>>>>>>> ByteArrayOutputStream.write(int) the new backing array capacity is >>>>>>>> set >>>>>>>> to 2 >>>>>>>> * buf.length unless this value would not suffice to accommodate the >>>>>>>> required >>>>>>>> capacity in which case it is set to the required capacity. ?If the >>>>>>>> current >>>>>>>> backing array capacity is at least (1/2) * Integer.MAX_VALUE + 1, >>>>>>>> then >>>>>>>> buf.length << 1 overflows and resolves to a negative number >>>>>>>> resulting >>>>>>>> in >>>>>>>> the >>>>>>>> new capacity being set to the required capacity. ?The major >>>>>>>> consequence >>>>>>>> of >>>>>>>> this, like with ArrayList, is that each subsequent write operation >>>>>>>> results >>>>>>>> in a full resize of the ByteArrayOutputStream causing performance to >>>>>>>> degrade >>>>>>>> significantly. >>>>>>>> >>>>>>>> ? int newcount = count + 1; >>>>>>>> ? if (newcount > buf.length) { >>>>>>>> ? ? ? ? ? buf = Arrays.copyOf(buf, Math.max(buf.length << 1, >>>>>>>> newcount)); >>>>>>>> ? } >>>>>>>> >>>>>>>> It is interesting to note that any statements about the amortized >>>>>>>> time >>>>>>>> complexity of add/insert operations, such as the one in the >>>>>>>> ArrayList >>>>>>>> javadoc, are invalidated by the performance related bugs. ?One >>>>>>>> solution >>>>>>>> to >>>>>>>> the above situations is to set the new capacity of the backing array >>>>>>>> to >>>>>>>> Integer.MAX_VALUE when the initial size calculation results in a >>>>>>>> negative >>>>>>>> number during a resize. >>>>>>>> >>>>>>>> Apologies if these bugs are already known. >>>>>>>> >>>>>>>> Regards, >>>>>>>> >>>>>>>> Kevin >>>>>>>> > From martinrb at google.com Thu May 13 01:38:10 2010 From: martinrb at google.com (Martin Buchholz) Date: Wed, 12 May 2010 18:38:10 -0700 Subject: Bugs in java.util.ArrayList, java.util.Hashtable and java.io.ByteArrayOutputStream In-Reply-To: References: <1704b7a21003031741m734545f1gb0170ed5fa6f6d68@mail.gmail.com> <1ccfd1c11003050104u61e776apc5fe2e5ec08e3dc0@mail.gmail.com> <1704b7a21003050248k1e893cedmd14f26cbecd45896@mail.gmail.com> <1ccfd1c11003081810u54fb22e6k25230f4eb5ca1b18@mail.gmail.com> <4B9633EA.8070101@sun.com> <4BC82FFF.20502@oracle.com> <4BEB4854.7000403@oracle.com> Message-ID: Webrev at http://cr.openjdk.java.net/~martin/webrevs/openjdk7/StringBuffer-capacity/StringBuffer-capacity.patch Martin On Wed, May 12, 2010 at 18:23, Martin Buchholz wrote: > Alright, I'm convinced this is a bug. ?Please file one in bugtraq > (or expunge from tl in the unlikely event that would be permitted). > It appears we very carefully specified the capacity manipulation behavior, > but didn't have any jtreg tests for it. > Do y'all run the Mauve tests? ?(Probably a good idea) > > Martin > > On Wed, May 12, 2010 at 17:31, David Holmes wrote: >> Chris, Martin, >> >> The changes to AbstractStringBuilder violate the specification for >> ensureCapacity: it has to grow from N to 2N+2. The new code in: >> >> http://hg.openjdk.java.net/jdk7/tl-gate/jdk/rev/ec45423a4700 >> >> ?void expandCapacity(int minimumCapacity) { >> - int newCapacity = (value.length + 1) * 2; >> + int newCapacity = value.length * 2; >> >> Has dropped the +2 part. >> >> This is causing test failures. >> >> David >> ----- >> >> Chris Hegarty said the following on 04/16/10 19:38: >>> >>> Martin Buchholz wrote: >>>> >>>> Hi Chris, >>>> >>>> I recently discovered another place to handle huge arrays better - in >>>> AbstractCollection. >>>> I've put those changes into >>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize2/ >>>> I propose to qfold these into the original changes for this bug >>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize/ >>>> which have not yet been committed. >>> >>> Good catch Martin, these additional changes look good. >>> >>> -Chris. >>> >>>> >>>> Martin >>>> >>>> On Tue, Mar 9, 2010 at 04:41, Christopher Hegarty -Sun Microsystems >>>> Ireland wrote: >>>>> >>>>> Sorry Martin, I appear to have missed your original request to file this >>>>> bug. I since filed the following: >>>>> >>>>> ?6933217: Huge arrays handled poorly in core libraries >>>>> >>>>> The changes you are proposing seem reasonable to me. >>>>> >>>>> -Chris. >>>>> >>>>> Martin Buchholz wrote: >>>>>> >>>>>> [Chris or Alan, please review and file a bug] >>>>>> >>>>>> OK, guys, >>>>>> >>>>>> Here's a patch: >>>>>> >>>>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize/ >>>>>> >>>>>> Martin >>>>>> >>>>>> On Fri, Mar 5, 2010 at 02:48, Kevin L. Stern >>>>>> wrote: >>>>>>> >>>>>>> Hi Martin, >>>>>>> >>>>>>> Thank you for your reply. ?If I may, PriorityQueue appears to employ >>>>>>> the >>>>>>> simple strategy that I suggested above in its grow method: >>>>>>> >>>>>>> ? ? ? int newCapacity = ((oldCapacity < 64)? >>>>>>> ? ? ? ? ? ? ? ? ? ? ? ? ?((oldCapacity + 1) * 2): >>>>>>> ? ? ? ? ? ? ? ? ? ? ? ? ?((oldCapacity / 2) * 3)); >>>>>>> ? ? ? if (newCapacity < 0) // overflow >>>>>>> ? ? ? ? ? newCapacity = Integer.MAX_VALUE; >>>>>>> >>>>>>> It might be desirable to set a common strategy for capacity increase >>>>>>> for >>>>>>> all >>>>>>> collections. >>>>>>> >>>>>>> Regards, >>>>>>> >>>>>>> Kevin >>>>>>> >>>>>>> On Fri, Mar 5, 2010 at 3:04 AM, Martin Buchholz >>>>>>> wrote: >>>>>>>> >>>>>>>> Hi Kevin, >>>>>>>> >>>>>>>> As you've noticed, creating objects within a factor of two of >>>>>>>> their natural limits is a good way to expose lurking bugs. >>>>>>>> >>>>>>>> I'm the one responsible for the algorithm in ArrayList. >>>>>>>> I'm a bit embarrassed, looking at that code today. >>>>>>>> We could set the array size to Integer.MAX_VALUE, >>>>>>>> but then you might hit an independent buglet in hotspot >>>>>>>> that you cannot allocate an array with Integer.MAX_VALUE >>>>>>>> elements, but Integer.MAX_VALUE - 5 (or so) works. >>>>>>>> >>>>>>>> It occurs to me that increasing the size by 50% is better done by >>>>>>>> int newCapacity = oldCapacity + (oldCapacity >> 1) + 1; >>>>>>>> >>>>>>>> I agree with the plan of setting the capacity to something near >>>>>>>> MAX_VALUE on overflow, and throw OutOfMemoryError on next resize. >>>>>>>> >>>>>>>> These bugs are not known. >>>>>>>> Chris Hegarty, could you file a bug for us? >>>>>>>> >>>>>>>> Martin >>>>>>>> >>>>>>>> On Wed, Mar 3, 2010 at 17:41, Kevin L. Stern >>>>>>>> >>>>>>>> wrote: >>>>>>>>> >>>>>>>>> Greetings, >>>>>>>>> >>>>>>>>> I've noticed bugs in java.util.ArrayList, java.util.Hashtable and >>>>>>>>> java.io.ByteArrayOutputStream which arise when the capacities of the >>>>>>>>> data >>>>>>>>> structures reach a particular threshold. ?More below. >>>>>>>>> >>>>>>>>> When the capacity of an ArrayList reaches (2/3)*Integer.MAX_VALUE >>>>>>>>> its >>>>>>>>> size >>>>>>>>> reaches its capacity and an add or an insert operation is invoked, >>>>>>>>> the >>>>>>>>> capacity is increased by only one element. ?Notice that in the >>>>>>>>> following >>>>>>>>> excerpt from ArrayList.ensureCapacity the new capacity is set to >>>>>>>>> (3/2) >>>>>>>>> * >>>>>>>>> oldCapacity + 1 unless this value would not suffice to accommodate >>>>>>>>> the >>>>>>>>> required capacity in which case it is set to the required capacity. >>>>>>>>> ?If >>>>>>>>> the >>>>>>>>> current capacity is at least (2/3)*Integer.MAX_VALUE, then >>>>>>>>> (oldCapacity >>>>>>>>> * >>>>>>>>> 3)/2 + 1 overflows and resolves to a negative number resulting in >>>>>>>>> the >>>>>>>>> new >>>>>>>>> capacity being set to the required capacity. ?The major consequence >>>>>>>>> of >>>>>>>>> this >>>>>>>>> is that each subsequent add/insert operation results in a full >>>>>>>>> resize >>>>>>>>> of >>>>>>>>> the >>>>>>>>> ArrayList causing performance to degrade significantly. >>>>>>>>> >>>>>>>>> ? ? ? int newCapacity = (oldCapacity * 3)/2 + 1; >>>>>>>>> ? ? ? ? ? if (newCapacity < minCapacity) >>>>>>>>> ? ? ? newCapacity = minCapacity; >>>>>>>>> >>>>>>>>> Hashtable breaks entirely when the size of its backing array reaches >>>>>>>>> (1/2) * >>>>>>>>> Integer.MAX_VALUE and a rehash is necessary as is evident from the >>>>>>>>> following >>>>>>>>> excerpt from rehash. ?Notice that rehash will attempt to create an >>>>>>>>> array >>>>>>>>> of >>>>>>>>> negative size if the size of the backing array reaches (1/2) * >>>>>>>>> Integer.MAX_VALUE since oldCapacity * 2 + 1 overflows and resolves >>>>>>>>> to a >>>>>>>>> negative number. >>>>>>>>> >>>>>>>>> ? int newCapacity = oldCapacity * 2 + 1; >>>>>>>>> ? HashtableEntry newTable[] = new HashtableEntry[newCapacity]; >>>>>>>>> >>>>>>>>> When the capacity of the backing array in a ByteArrayOutputStream >>>>>>>>> reaches >>>>>>>>> (1/2) * Integer.MAX_VALUE its size reaches its capacity and a write >>>>>>>>> operation is invoked, the capacity of the backing array is increased >>>>>>>>> only by >>>>>>>>> the required number of elements. ?Notice that in the following >>>>>>>>> excerpt >>>>>>>>> from >>>>>>>>> ByteArrayOutputStream.write(int) the new backing array capacity is >>>>>>>>> set >>>>>>>>> to 2 >>>>>>>>> * buf.length unless this value would not suffice to accommodate the >>>>>>>>> required >>>>>>>>> capacity in which case it is set to the required capacity. ?If the >>>>>>>>> current >>>>>>>>> backing array capacity is at least (1/2) * Integer.MAX_VALUE + 1, >>>>>>>>> then >>>>>>>>> buf.length << 1 overflows and resolves to a negative number >>>>>>>>> resulting >>>>>>>>> in >>>>>>>>> the >>>>>>>>> new capacity being set to the required capacity. ?The major >>>>>>>>> consequence >>>>>>>>> of >>>>>>>>> this, like with ArrayList, is that each subsequent write operation >>>>>>>>> results >>>>>>>>> in a full resize of the ByteArrayOutputStream causing performance to >>>>>>>>> degrade >>>>>>>>> significantly. >>>>>>>>> >>>>>>>>> ? int newcount = count + 1; >>>>>>>>> ? if (newcount > buf.length) { >>>>>>>>> ? ? ? ? ? buf = Arrays.copyOf(buf, Math.max(buf.length << 1, >>>>>>>>> newcount)); >>>>>>>>> ? } >>>>>>>>> >>>>>>>>> It is interesting to note that any statements about the amortized >>>>>>>>> time >>>>>>>>> complexity of add/insert operations, such as the one in the >>>>>>>>> ArrayList >>>>>>>>> javadoc, are invalidated by the performance related bugs. ?One >>>>>>>>> solution >>>>>>>>> to >>>>>>>>> the above situations is to set the new capacity of the backing array >>>>>>>>> to >>>>>>>>> Integer.MAX_VALUE when the initial size calculation results in a >>>>>>>>> negative >>>>>>>>> number during a resize. >>>>>>>>> >>>>>>>>> Apologies if these bugs are already known. >>>>>>>>> >>>>>>>>> Regards, >>>>>>>>> >>>>>>>>> Kevin >>>>>>>>> >> > From David.Holmes at oracle.com Thu May 13 01:59:43 2010 From: David.Holmes at oracle.com (David Holmes) Date: Thu, 13 May 2010 11:59:43 +1000 Subject: Bugs in java.util.ArrayList, java.util.Hashtable and java.io.ByteArrayOutputStream In-Reply-To: References: <1704b7a21003031741m734545f1gb0170ed5fa6f6d68@mail.gmail.com> <1ccfd1c11003050104u61e776apc5fe2e5ec08e3dc0@mail.gmail.com> <1704b7a21003050248k1e893cedmd14f26cbecd45896@mail.gmail.com> <1ccfd1c11003081810u54fb22e6k25230f4eb5ca1b18@mail.gmail.com> <4B9633EA.8070101@sun.com> <4BC82FFF.20502@oracle.com> <4BEB4854.7000403@oracle.com> Message-ID: <4BEB5D0F.1000200@oracle.com> Hi Martin, Bugtraq is offline so I can't file a CR right now. The was caught by Mauve tests. Kelly sent a link to the mailing list but I don't think he's a member so it's probably held up for approval. Martin Buchholz said the following on 05/13/10 11:38: > Webrev at > > http://cr.openjdk.java.net/~martin/webrevs/openjdk7/StringBuffer-capacity/StringBuffer-capacity.patch Fix looks fine. Took me a few tries to confirm the test logic :) Thanks, David ----- > Martin > > On Wed, May 12, 2010 at 18:23, Martin Buchholz wrote: >> Alright, I'm convinced this is a bug. Please file one in bugtraq >> (or expunge from tl in the unlikely event that would be permitted). >> It appears we very carefully specified the capacity manipulation behavior, >> but didn't have any jtreg tests for it. >> Do y'all run the Mauve tests? (Probably a good idea) >> >> Martin >> >> On Wed, May 12, 2010 at 17:31, David Holmes wrote: >>> Chris, Martin, >>> >>> The changes to AbstractStringBuilder violate the specification for >>> ensureCapacity: it has to grow from N to 2N+2. The new code in: >>> >>> http://hg.openjdk.java.net/jdk7/tl-gate/jdk/rev/ec45423a4700 >>> >>> void expandCapacity(int minimumCapacity) { >>> - int newCapacity = (value.length + 1) * 2; >>> + int newCapacity = value.length * 2; >>> >>> Has dropped the +2 part. >>> >>> This is causing test failures. >>> >>> David >>> ----- >>> >>> Chris Hegarty said the following on 04/16/10 19:38: >>>> Martin Buchholz wrote: >>>>> Hi Chris, >>>>> >>>>> I recently discovered another place to handle huge arrays better - in >>>>> AbstractCollection. >>>>> I've put those changes into >>>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize2/ >>>>> I propose to qfold these into the original changes for this bug >>>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize/ >>>>> which have not yet been committed. >>>> Good catch Martin, these additional changes look good. >>>> >>>> -Chris. >>>> >>>>> Martin >>>>> >>>>> On Tue, Mar 9, 2010 at 04:41, Christopher Hegarty -Sun Microsystems >>>>> Ireland wrote: >>>>>> Sorry Martin, I appear to have missed your original request to file this >>>>>> bug. I since filed the following: >>>>>> >>>>>> 6933217: Huge arrays handled poorly in core libraries >>>>>> >>>>>> The changes you are proposing seem reasonable to me. >>>>>> >>>>>> -Chris. >>>>>> >>>>>> Martin Buchholz wrote: >>>>>>> [Chris or Alan, please review and file a bug] >>>>>>> >>>>>>> OK, guys, >>>>>>> >>>>>>> Here's a patch: >>>>>>> >>>>>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize/ >>>>>>> >>>>>>> Martin >>>>>>> >>>>>>> On Fri, Mar 5, 2010 at 02:48, Kevin L. Stern >>>>>>> wrote: >>>>>>>> Hi Martin, >>>>>>>> >>>>>>>> Thank you for your reply. If I may, PriorityQueue appears to employ >>>>>>>> the >>>>>>>> simple strategy that I suggested above in its grow method: >>>>>>>> >>>>>>>> int newCapacity = ((oldCapacity < 64)? >>>>>>>> ((oldCapacity + 1) * 2): >>>>>>>> ((oldCapacity / 2) * 3)); >>>>>>>> if (newCapacity < 0) // overflow >>>>>>>> newCapacity = Integer.MAX_VALUE; >>>>>>>> >>>>>>>> It might be desirable to set a common strategy for capacity increase >>>>>>>> for >>>>>>>> all >>>>>>>> collections. >>>>>>>> >>>>>>>> Regards, >>>>>>>> >>>>>>>> Kevin >>>>>>>> >>>>>>>> On Fri, Mar 5, 2010 at 3:04 AM, Martin Buchholz >>>>>>>> wrote: >>>>>>>>> Hi Kevin, >>>>>>>>> >>>>>>>>> As you've noticed, creating objects within a factor of two of >>>>>>>>> their natural limits is a good way to expose lurking bugs. >>>>>>>>> >>>>>>>>> I'm the one responsible for the algorithm in ArrayList. >>>>>>>>> I'm a bit embarrassed, looking at that code today. >>>>>>>>> We could set the array size to Integer.MAX_VALUE, >>>>>>>>> but then you might hit an independent buglet in hotspot >>>>>>>>> that you cannot allocate an array with Integer.MAX_VALUE >>>>>>>>> elements, but Integer.MAX_VALUE - 5 (or so) works. >>>>>>>>> >>>>>>>>> It occurs to me that increasing the size by 50% is better done by >>>>>>>>> int newCapacity = oldCapacity + (oldCapacity >> 1) + 1; >>>>>>>>> >>>>>>>>> I agree with the plan of setting the capacity to something near >>>>>>>>> MAX_VALUE on overflow, and throw OutOfMemoryError on next resize. >>>>>>>>> >>>>>>>>> These bugs are not known. >>>>>>>>> Chris Hegarty, could you file a bug for us? >>>>>>>>> >>>>>>>>> Martin >>>>>>>>> >>>>>>>>> On Wed, Mar 3, 2010 at 17:41, Kevin L. Stern >>>>>>>>> >>>>>>>>> wrote: >>>>>>>>>> Greetings, >>>>>>>>>> >>>>>>>>>> I've noticed bugs in java.util.ArrayList, java.util.Hashtable and >>>>>>>>>> java.io.ByteArrayOutputStream which arise when the capacities of the >>>>>>>>>> data >>>>>>>>>> structures reach a particular threshold. More below. >>>>>>>>>> >>>>>>>>>> When the capacity of an ArrayList reaches (2/3)*Integer.MAX_VALUE >>>>>>>>>> its >>>>>>>>>> size >>>>>>>>>> reaches its capacity and an add or an insert operation is invoked, >>>>>>>>>> the >>>>>>>>>> capacity is increased by only one element. Notice that in the >>>>>>>>>> following >>>>>>>>>> excerpt from ArrayList.ensureCapacity the new capacity is set to >>>>>>>>>> (3/2) >>>>>>>>>> * >>>>>>>>>> oldCapacity + 1 unless this value would not suffice to accommodate >>>>>>>>>> the >>>>>>>>>> required capacity in which case it is set to the required capacity. >>>>>>>>>> If >>>>>>>>>> the >>>>>>>>>> current capacity is at least (2/3)*Integer.MAX_VALUE, then >>>>>>>>>> (oldCapacity >>>>>>>>>> * >>>>>>>>>> 3)/2 + 1 overflows and resolves to a negative number resulting in >>>>>>>>>> the >>>>>>>>>> new >>>>>>>>>> capacity being set to the required capacity. The major consequence >>>>>>>>>> of >>>>>>>>>> this >>>>>>>>>> is that each subsequent add/insert operation results in a full >>>>>>>>>> resize >>>>>>>>>> of >>>>>>>>>> the >>>>>>>>>> ArrayList causing performance to degrade significantly. >>>>>>>>>> >>>>>>>>>> int newCapacity = (oldCapacity * 3)/2 + 1; >>>>>>>>>> if (newCapacity < minCapacity) >>>>>>>>>> newCapacity = minCapacity; >>>>>>>>>> >>>>>>>>>> Hashtable breaks entirely when the size of its backing array reaches >>>>>>>>>> (1/2) * >>>>>>>>>> Integer.MAX_VALUE and a rehash is necessary as is evident from the >>>>>>>>>> following >>>>>>>>>> excerpt from rehash. Notice that rehash will attempt to create an >>>>>>>>>> array >>>>>>>>>> of >>>>>>>>>> negative size if the size of the backing array reaches (1/2) * >>>>>>>>>> Integer.MAX_VALUE since oldCapacity * 2 + 1 overflows and resolves >>>>>>>>>> to a >>>>>>>>>> negative number. >>>>>>>>>> >>>>>>>>>> int newCapacity = oldCapacity * 2 + 1; >>>>>>>>>> HashtableEntry newTable[] = new HashtableEntry[newCapacity]; >>>>>>>>>> >>>>>>>>>> When the capacity of the backing array in a ByteArrayOutputStream >>>>>>>>>> reaches >>>>>>>>>> (1/2) * Integer.MAX_VALUE its size reaches its capacity and a write >>>>>>>>>> operation is invoked, the capacity of the backing array is increased >>>>>>>>>> only by >>>>>>>>>> the required number of elements. Notice that in the following >>>>>>>>>> excerpt >>>>>>>>>> from >>>>>>>>>> ByteArrayOutputStream.write(int) the new backing array capacity is >>>>>>>>>> set >>>>>>>>>> to 2 >>>>>>>>>> * buf.length unless this value would not suffice to accommodate the >>>>>>>>>> required >>>>>>>>>> capacity in which case it is set to the required capacity. If the >>>>>>>>>> current >>>>>>>>>> backing array capacity is at least (1/2) * Integer.MAX_VALUE + 1, >>>>>>>>>> then >>>>>>>>>> buf.length << 1 overflows and resolves to a negative number >>>>>>>>>> resulting >>>>>>>>>> in >>>>>>>>>> the >>>>>>>>>> new capacity being set to the required capacity. The major >>>>>>>>>> consequence >>>>>>>>>> of >>>>>>>>>> this, like with ArrayList, is that each subsequent write operation >>>>>>>>>> results >>>>>>>>>> in a full resize of the ByteArrayOutputStream causing performance to >>>>>>>>>> degrade >>>>>>>>>> significantly. >>>>>>>>>> >>>>>>>>>> int newcount = count + 1; >>>>>>>>>> if (newcount > buf.length) { >>>>>>>>>> buf = Arrays.copyOf(buf, Math.max(buf.length << 1, >>>>>>>>>> newcount)); >>>>>>>>>> } >>>>>>>>>> >>>>>>>>>> It is interesting to note that any statements about the amortized >>>>>>>>>> time >>>>>>>>>> complexity of add/insert operations, such as the one in the >>>>>>>>>> ArrayList >>>>>>>>>> javadoc, are invalidated by the performance related bugs. One >>>>>>>>>> solution >>>>>>>>>> to >>>>>>>>>> the above situations is to set the new capacity of the backing array >>>>>>>>>> to >>>>>>>>>> Integer.MAX_VALUE when the initial size calculation results in a >>>>>>>>>> negative >>>>>>>>>> number during a resize. >>>>>>>>>> >>>>>>>>>> Apologies if these bugs are already known. >>>>>>>>>> >>>>>>>>>> Regards, >>>>>>>>>> >>>>>>>>>> Kevin >>>>>>>>>> From kelly.ohair at oracle.com Thu May 13 04:36:26 2010 From: kelly.ohair at oracle.com (kelly.ohair at oracle.com) Date: Thu, 13 May 2010 04:36:26 +0000 Subject: hg: jdk7/tl/jdk: 6943915: Adjust jdk/test/Makefile to deal with .dll and .so libraries needing execute permissions Message-ID: <20100513043638.D5A0144607@hg.openjdk.java.net> Changeset: 2d54e4cae441 Author: ohair Date: 2010-05-12 21:35 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/2d54e4cae441 6943915: Adjust jdk/test/Makefile to deal with .dll and .so libraries needing execute permissions Summary: And adjustments to test problem list. Reviewed-by: jjg ! test/Makefile ! test/ProblemList.txt ! test/java/lang/ProcessBuilder/Basic.java ! test/java/lang/Runtime/exec/ExecWithDir.java From martinrb at google.com Thu May 13 05:51:38 2010 From: martinrb at google.com (Martin Buchholz) Date: Wed, 12 May 2010 22:51:38 -0700 Subject: 4813885: RFE: GZIPOutputStream should implement flush using Z_SYNC_FLUSH In-Reply-To: <4BEB310E.5090602@oracle.com> References: <4BEB310E.5090602@oracle.com> Message-ID: zlib 1.2.5 is out! Quite notably, there are now more flush modes and the comment claiming that Z_PARTIAL_FLUSH will be removed has been removed! As I recall saying in a previous email, we should support Z_PARTIAL_FLUSH at least because the ssh protocol requires it. I think the flush parameter should be an int. ---- invocatin => invocation + * if {@code true} invocatin of the inherited Martin On Wed, May 12, 2010 at 15:51, Xueming Shen wrote: > Martin, > > Would you please help review the change for > > 4813885: RFE: GZIPOutputStream should implement flush using Z_SYNC_FLUSH > > http://cr.openjdk.java.net/~sherman/4813885/webrev > > It appears people want to have the same flush option in GZIPOutputStream as > the > one we provided in DeflaterOutputStream for #4206909 a while ago, the webrev > for > 4206909 is at > > http://cr.openjdk.java.net/~sherman/4206909/webrev > > Thanks, > -Sherman > From xueming.shen at oracle.com Thu May 13 06:46:57 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Wed, 12 May 2010 23:46:57 -0700 Subject: 4813885: RFE: GZIPOutputStream should implement flush using Z_SYNC_FLUSH In-Reply-To: References: <4BEB310E.5090602@oracle.com> Message-ID: <4BEBA061.4000206@oracle.com> Thanks for the review. The Z_SYNC_FLUSH is supposed to fully replace the Z_PARTIAL_FLUSH. We concluded last round that Z_SYNC_FLUSH is enough for the "high-level" DOS, as well as the GZIPOS, use Deflater directly if more needed. I hope you are not suggesting we go back to redo the flush to int. Took a quick look at 1.2.5, don't see anything make it attractive for us to "upgrade" again. Sherman Martin Buchholz wrote: > zlib 1.2.5 is out! > > Quite notably, there are now more flush modes > and the comment claiming that Z_PARTIAL_FLUSH > will be removed has been removed! > > As I recall saying in a previous email, > we should support Z_PARTIAL_FLUSH at least > because the ssh protocol requires it. > I think the flush parameter should be an int. > > ---- > > invocatin => invocation > > + * if {@code true} invocatin of the inherited > > Martin > > On Wed, May 12, 2010 at 15:51, Xueming Shen wrote: > >> Martin, >> >> Would you please help review the change for >> >> 4813885: RFE: GZIPOutputStream should implement flush using Z_SYNC_FLUSH >> >> http://cr.openjdk.java.net/~sherman/4813885/webrev >> >> It appears people want to have the same flush option in GZIPOutputStream as >> the >> one we provided in DeflaterOutputStream for #4206909 a while ago, the webrev >> for >> 4206909 is at >> >> http://cr.openjdk.java.net/~sherman/4206909/webrev >> >> Thanks, >> -Sherman >> >> From martinrb at google.com Thu May 13 06:58:37 2010 From: martinrb at google.com (Martin Buchholz) Date: Wed, 12 May 2010 23:58:37 -0700 Subject: 4813885: RFE: GZIPOutputStream should implement flush using Z_SYNC_FLUSH In-Reply-To: <4BEBA061.4000206@oracle.com> References: <4BEB310E.5090602@oracle.com> <4BEBA061.4000206@oracle.com> Message-ID: On Wed, May 12, 2010 at 23:46, Xueming Shen wrote: > Thanks for the review. > > The Z_SYNC_FLUSH is supposed to fully replace the Z_PARTIAL_FLUSH. > > We concluded last round that Z_SYNC_FLUSH is enough for the "high-level" > DOS, as well as the GZIPOS, use Deflater directly if ?more needed. I hope > you > are not suggesting we go back to redo the flush to int. Maybe we should. http://www.jcraft.com/jzlib/ """ To implement this functionality, the Z_PARTIAL_FLUSH mode of zlib must be used, however JDK does not permit us to do so. It seems that this problem has been well known and some people have already reported to JavaSoft's BugParade(for example, BugId:4255743), but any positive response has not been returned from JavaSoft, so this problem will not be solved forever. This is our motivation to hack JZlib. """ > Took a quick look at 1.2.5, don't see anything make it attractive for us to > "upgrade" again. I rather liked their marketing: # Fixed bugs in adler32_combine(), compressBound(), and deflateBound() # Wholesale replacement of gz* functions with faster versions # As part of that, added gzbuffer(), gzoffset(), gzclose_r(), and gzclose_w() functions # Faster Z_HUFFMAN_ONLY and Z_RLE compression for images and other specialized compression # Added flush options Z_BLOCK to deflate() and Z_TREES to inflate() for finer control # Added inflateReset2() and inflateMark() functions, the latter to aid in random access applications # Added LFS (Large File Summit) support for 64-bit file offsets and many other portability improvements Martin > Sherman > > Martin Buchholz wrote: >> >> zlib 1.2.5 is out! >> >> Quite notably, there are now more flush modes >> and the comment claiming that Z_PARTIAL_FLUSH >> will be removed has been removed! >> >> As I recall saying in a previous email, >> we should support Z_PARTIAL_FLUSH at least >> because the ssh protocol requires it. >> I think the flush parameter should be an int. >> >> ---- >> >> invocatin => invocation >> >> + ? ? * ? ? ? ?if {@code true} invocatin of the inherited >> >> Martin >> >> On Wed, May 12, 2010 at 15:51, Xueming Shen >> wrote: >> >>> >>> Martin, >>> >>> Would you please help review the change for >>> >>> 4813885: RFE: GZIPOutputStream should implement flush using Z_SYNC_FLUSH >>> >>> http://cr.openjdk.java.net/~sherman/4813885/webrev >>> >>> It appears people want to have the same flush option in GZIPOutputStream >>> as >>> the >>> one we provided in DeflaterOutputStream for #4206909 a while ago, the >>> webrev >>> for >>> 4206909 is at >>> >>> http://cr.openjdk.java.net/~sherman/4206909/webrev >>> >>> Thanks, >>> -Sherman >>> >>> > > From xueming.shen at ORACLE.COM Thu May 13 07:11:30 2010 From: xueming.shen at ORACLE.COM (Xueming Shen) Date: Thu, 13 May 2010 00:11:30 -0700 Subject: 4813885: RFE: GZIPOutputStream should implement flush using Z_SYNC_FLUSH In-Reply-To: References: <4BEB310E.5090602@oracle.com> <4BEBA061.4000206@oracle.com> Message-ID: <4BEBA622.2050303@oracle.com> Martin Buchholz wrote: > On Wed, May 12, 2010 at 23:46, Xueming Shen wrote: > >> Thanks for the review. >> >> The Z_SYNC_FLUSH is supposed to fully replace the Z_PARTIAL_FLUSH. >> >> We concluded last round that Z_SYNC_FLUSH is enough for the "high-level" >> DOS, as well as the GZIPOS, use Deflater directly if more needed. I hope >> you >> are not suggesting we go back to redo the flush to int. >> > > Maybe we should. > > http://www.jcraft.com/jzlib/ > > """ > To implement this functionality, the Z_PARTIAL_FLUSH mode of zlib must > be used, however JDK does not permit us to do so. It seems that this > problem has been well known and some people have already reported to > JavaSoft's BugParade(for example, BugId:4255743), but any positive > response has not been returned from JavaSoft, so this problem will not > be solved forever. This is our motivation to hack JZlib. > """ > > I thought I had closed this one (#4255743) as the dup of #4206909. This is actually why we did 4206909 and now doing #4813885. With the fix for #4206909, you no longer need jzlib:-) Yes, we use Z_SYNC_FLUSH, not Z_PARTIAL_FLUSH because the later is going away, replaced by Z_SYNC_FLUSH. They are the same thing. So with #4206909 and #4813885 you can now sync_flush the GZIPOutputStream and DeflaterOutputStream, as needed by the "functionality" mentioned in jzlib. Sherman From ptisnovs at redhat.com Thu May 13 08:22:36 2010 From: ptisnovs at redhat.com (ptisnovs at redhat.com) Date: Thu, 13 May 2010 08:22:36 +0000 Subject: hg: jdk7/tl/jdk: 6951887: Wrong redirection useage in test sun/nio/cs/Test4200310.sh Message-ID: <20100513082249.26E8944658@hg.openjdk.java.net> Changeset: f6b72c9023f4 Author: ptisnovs Date: 2010-05-13 10:11 +0200 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/f6b72c9023f4 6951887: Wrong redirection useage in test sun/nio/cs/Test4200310.sh Summary: Testcase correction. Reviewed-by: sherman ! test/sun/nio/cs/Test4200310.sh From iaroslavski at mail.ru Thu May 13 17:34:54 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Thu, 13 May 2010 21:34:54 +0400 Subject: =?koi8-r?Q?Re[4]=3A_New_portion_of_improvements_for_Dual-Pivot_Quicksort?= In-Reply-To: References: Message-ID: Dmytro, I've tested your suggested variants, and found that case "C" (very interesting approach to find first position of zero by counting negative elements) works slower than original or two other cases. Implementations "F" and "S" are very close to each other and little bit faster than original. I prefer case "F": it is shorter and more clear. Do you agree? I'll prepare updated DualPivotQuicksort file and send it tomorrow. Thank you, Vladimir Wed, 12 May 2010 17:04:52 +0700 ?????? ?? Dmytro Sheyko : > Vladimir, > > Your changes are good for me. > > Additionally I have some comments/proposals regarding dealing with negative zeros. > > 1. Scanning for the first zero we can avoid range check (i >= left) if we have at least one negative value. > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 2010 > @@ -1705,10 +1705,15 @@ > } > > // Find first zero element > - int zeroIndex = findAnyZero(a, left, n); > + int zeroIndex = 0; > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > - zeroIndex = i; > + if (a[left] < 0.0f) { > + zeroIndex = findAnyZero(a, left, n); > + > + // there is at least one negative value, so range check is not needed > + for (int i = zeroIndex - 1; /*i >= left &&*/ a[i] == 0.0f; i--) { > + zeroIndex = i; > + } > } > > // Turn the right number of positive zeros back into negative zeros > > 2. We can find the position of the first zero by counting negative values during preprocessing phase. > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 2010 > @@ -1678,7 +1678,7 @@ > * Phase 1: Count negative zeros and move NaNs to end of array. > */ > final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f); > - int numNegativeZeros = 0; > + int numNegativeZeros = 0, numNegativeValues = 0; > int n = right; > > for (int k = left; k <= n; k++) { > @@ -1689,6 +1689,8 @@ > } else if (ak != ak) { // i.e., ak is NaN > a[k--] = a[n]; > a[n--] = Float.NaN; > + } else if (ak < 0.0f) { > + numNegativeValues++; > } > } > > @@ -1705,7 +1707,7 @@ > } > > // Find first zero element > - int zeroIndex = findAnyZero(a, left, n); > + int zeroIndex = numNegativeValues; > > for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > zeroIndex = i; > > 3. We can use binary search to find the first zero and thus avoid linear scan. > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 2010 > @@ -1705,11 +1705,7 @@ > } > > // Find first zero element > - int zeroIndex = findAnyZero(a, left, n); > - > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > - zeroIndex = i; > - } > + int zeroIndex = findFirstZero(a, left, n); > > // Turn the right number of positive zeros back into negative zeros > for (int i = zeroIndex, m = zeroIndex + numNegativeZeros; i < m; i++) { > @@ -1718,7 +1714,7 @@ > } > > /** > - * Returns the index of some zero element in the specified range via > + * Returns the index of the first zero element in the specified range via > * binary search. The range is assumed to be sorted, and must contain > * at least one zero. > * > @@ -1726,18 +1722,17 @@ > * @param low the index of the first element, inclusive, to be searched > * @param high the index of the last element, inclusive, to be searched > */ > - private static int findAnyZero(float[] a, int low, int high) { > - while (true) { > + private static int findFirstZero(float[] a, int low, int high) { > + while (low < high) { > int middle = (low + high) >>> 1; > float middleValue = a[middle]; > > if (middleValue < 0.0f) { > low = middle + 1; > - } else if (middleValue > 0.0f) { > - high = middle - 1; > - } else { // middleValue == 0.0f > - return middle; > + } else { // middleValue >= 0.0f > + high = middle; > } > + return low; > } > } > > Counting negative values appeared more expensive than any other variants. > The last proposal seems to me as efficient as the current solution is in its worst case - when we have only one negative zero (in the half of array). > And it shows the best result if we have many zeros. > > Regards, > Dmytro Sheyko > > > From: iaroslavski at mail.ru > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > Subject: Re[2]: New portion of improvements for Dual-Pivot Quicksort > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > > Josh, > > Dmytro, > > > > I have done more thoroughly testing "great - less > 5 * seventh" vs. "less < e1 && great > e5", > > and found that more symmetric code "less < e1 && great > e5" is little bit faster, ~0.5..0.7% > > on both VMs. Other code has not been changed. > > > > Please, take the latest version in attachment. > > > > Vladimir > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua Bloch : > > > > > Vladimir, > > > > > > Old: > > > > > >298 if (less < e1 && great > e5) { > > > > > > New: > > > > > >256 if (great - less > 5 * seventh) { > > > > >Regards, > > >Josh From dmytro_sheyko at hotmail.com Thu May 13 18:48:11 2010 From: dmytro_sheyko at hotmail.com (Dmytro Sheyko) Date: Fri, 14 May 2010 01:48:11 +0700 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: , Message-ID: Yes. I prefer F (Find First zero using binary search) over C (Count negatives) and S (Smart Scan for zero). > From: iaroslavski at mail.ru > To: dmytro_sheyko at hotmail.com > CC: jjb at google.com; core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > Subject: Re[4]: New portion of improvements for Dual-Pivot Quicksort > Date: Thu, 13 May 2010 21:34:54 +0400 > > Dmytro, > > I've tested your suggested variants, and found that case "C" > (very interesting approach to find first position of zero > by counting negative elements) works slower than original > or two other cases. > > Implementations "F" and "S" are very close to each other > and little bit faster than original. I prefer case "F": > it is shorter and more clear. Do you agree? > > I'll prepare updated DualPivotQuicksort file and send it > tomorrow. > > Thank you, > Vladimir > > Wed, 12 May 2010 17:04:52 +0700 ?????? ?? Dmytro Sheyko : > > > Vladimir, > > > > Your changes are good for me. > > > > Additionally I have some comments/proposals regarding dealing with negative zeros. > > > > 1. Scanning for the first zero we can avoid range check (i >= left) if we have at least one negative value. > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 2010 > > @@ -1705,10 +1705,15 @@ > > } > > > > // Find first zero element > > - int zeroIndex = findAnyZero(a, left, n); > > + int zeroIndex = 0; > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > - zeroIndex = i; > > + if (a[left] < 0.0f) { > > + zeroIndex = findAnyZero(a, left, n); > > + > > + // there is at least one negative value, so range check is not needed > > + for (int i = zeroIndex - 1; /*i >= left &&*/ a[i] == 0.0f; i--) { > > + zeroIndex = i; > > + } > > } > > > > // Turn the right number of positive zeros back into negative zeros > > > > 2. We can find the position of the first zero by counting negative values during preprocessing phase. > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 2010 > > @@ -1678,7 +1678,7 @@ > > * Phase 1: Count negative zeros and move NaNs to end of array. > > */ > > final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f); > > - int numNegativeZeros = 0; > > + int numNegativeZeros = 0, numNegativeValues = 0; > > int n = right; > > > > for (int k = left; k <= n; k++) { > > @@ -1689,6 +1689,8 @@ > > } else if (ak != ak) { // i.e., ak is NaN > > a[k--] = a[n]; > > a[n--] = Float.NaN; > > + } else if (ak < 0.0f) { > > + numNegativeValues++; > > } > > } > > > > @@ -1705,7 +1707,7 @@ > > } > > > > // Find first zero element > > - int zeroIndex = findAnyZero(a, left, n); > > + int zeroIndex = numNegativeValues; > > > > for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > zeroIndex = i; > > > > 3. We can use binary search to find the first zero and thus avoid linear scan. > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 2010 > > @@ -1705,11 +1705,7 @@ > > } > > > > // Find first zero element > > - int zeroIndex = findAnyZero(a, left, n); > > - > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > - zeroIndex = i; > > - } > > + int zeroIndex = findFirstZero(a, left, n); > > > > // Turn the right number of positive zeros back into negative zeros > > for (int i = zeroIndex, m = zeroIndex + numNegativeZeros; i < m; i++) { > > @@ -1718,7 +1714,7 @@ > > } > > > > /** > > - * Returns the index of some zero element in the specified range via > > + * Returns the index of the first zero element in the specified range via > > * binary search. The range is assumed to be sorted, and must contain > > * at least one zero. > > * > > @@ -1726,18 +1722,17 @@ > > * @param low the index of the first element, inclusive, to be searched > > * @param high the index of the last element, inclusive, to be searched > > */ > > - private static int findAnyZero(float[] a, int low, int high) { > > - while (true) { > > + private static int findFirstZero(float[] a, int low, int high) { > > + while (low < high) { > > int middle = (low + high) >>> 1; > > float middleValue = a[middle]; > > > > if (middleValue < 0.0f) { > > low = middle + 1; > > - } else if (middleValue > 0.0f) { > > - high = middle - 1; > > - } else { // middleValue == 0.0f > > - return middle; > > + } else { // middleValue >= 0.0f > > + high = middle; > > } > > + return low; > > } > > } > > > > Counting negative values appeared more expensive than any other variants. > > The last proposal seems to me as efficient as the current solution is in its worst case - when we have only one negative zero (in the half of array). > > And it shows the best result if we have many zeros. > > > > Regards, > > Dmytro Sheyko > > > > > From: iaroslavski at mail.ru > > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > Subject: Re[2]: New portion of improvements for Dual-Pivot Quicksort > > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > > > > Josh, > > > Dmytro, > > > > > > I have done more thoroughly testing "great - less > 5 * seventh" vs. "less < e1 && great > e5", > > > and found that more symmetric code "less < e1 && great > e5" is little bit faster, ~0.5..0.7% > > > on both VMs. Other code has not been changed. > > > > > > Please, take the latest version in attachment. > > > > > > Vladimir > > > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua Bloch : > > > > > > > Vladimir, > > > > > > > > Old: > > > > > > > >298 if (less < e1 && great > e5) { > > > > > > > > New: > > > > > > > >256 if (great - less > 5 * seventh) { > > > > > > >Regards, > > > >Josh _________________________________________________________________ Hotmail: Trusted email with Microsoft?s powerful SPAM protection. https://signup.live.com/signup.aspx?id=60969 -------------- next part -------------- An HTML attachment was scrubbed... URL: From David.Holmes at oracle.com Thu May 13 22:46:09 2010 From: David.Holmes at oracle.com (David Holmes) Date: Fri, 14 May 2010 08:46:09 +1000 Subject: Bugs in java.util.ArrayList, java.util.Hashtable and java.io.ByteArrayOutputStream In-Reply-To: <4BEB5D0F.1000200@oracle.com> References: <1704b7a21003031741m734545f1gb0170ed5fa6f6d68@mail.gmail.com> <1ccfd1c11003050104u61e776apc5fe2e5ec08e3dc0@mail.gmail.com> <1704b7a21003050248k1e893cedmd14f26cbecd45896@mail.gmail.com> <1ccfd1c11003081810u54fb22e6k25230f4eb5ca1b18@mail.gmail.com> <4B9633EA.8070101@sun.com> <4BC82FFF.20502@oracle.com> <4BEB4854.7000403@oracle.com> <4BEB5D0F.1000200@oracle.com> Message-ID: <4BEC8131.6030208@oracle.com> CR: 6952330 Fix for 6933217 broke contract of StringBuffer.ensureCapacity Thanks, David David Holmes said the following on 05/13/10 11:59: > Hi Martin, > > Bugtraq is offline so I can't file a CR right now. > > The was caught by Mauve tests. Kelly sent a link to the mailing list but > I don't think he's a member so it's probably held up for approval. > > Martin Buchholz said the following on 05/13/10 11:38: >> Webrev at >> >> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/StringBuffer-capacity/StringBuffer-capacity.patch >> > > Fix looks fine. Took me a few tries to confirm the test logic :) > > Thanks, > David > ----- > > >> Martin >> >> On Wed, May 12, 2010 at 18:23, Martin Buchholz >> wrote: >>> Alright, I'm convinced this is a bug. Please file one in bugtraq >>> (or expunge from tl in the unlikely event that would be permitted). >>> It appears we very carefully specified the capacity manipulation >>> behavior, >>> but didn't have any jtreg tests for it. >>> Do y'all run the Mauve tests? (Probably a good idea) >>> >>> Martin >>> >>> On Wed, May 12, 2010 at 17:31, David Holmes >>> wrote: >>>> Chris, Martin, >>>> >>>> The changes to AbstractStringBuilder violate the specification for >>>> ensureCapacity: it has to grow from N to 2N+2. The new code in: >>>> >>>> http://hg.openjdk.java.net/jdk7/tl-gate/jdk/rev/ec45423a4700 >>>> >>>> void expandCapacity(int minimumCapacity) { >>>> - int newCapacity = (value.length + 1) * 2; >>>> + int newCapacity = value.length * 2; >>>> >>>> Has dropped the +2 part. >>>> >>>> This is causing test failures. >>>> >>>> David >>>> ----- >>>> >>>> Chris Hegarty said the following on 04/16/10 19:38: >>>>> Martin Buchholz wrote: >>>>>> Hi Chris, >>>>>> >>>>>> I recently discovered another place to handle huge arrays better - in >>>>>> AbstractCollection. >>>>>> I've put those changes into >>>>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize2/ >>>>>> I propose to qfold these into the original changes for this bug >>>>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize/ >>>>>> which have not yet been committed. >>>>> Good catch Martin, these additional changes look good. >>>>> >>>>> -Chris. >>>>> >>>>>> Martin >>>>>> >>>>>> On Tue, Mar 9, 2010 at 04:41, Christopher Hegarty -Sun Microsystems >>>>>> Ireland wrote: >>>>>>> Sorry Martin, I appear to have missed your original request to >>>>>>> file this >>>>>>> bug. I since filed the following: >>>>>>> >>>>>>> 6933217: Huge arrays handled poorly in core libraries >>>>>>> >>>>>>> The changes you are proposing seem reasonable to me. >>>>>>> >>>>>>> -Chris. >>>>>>> >>>>>>> Martin Buchholz wrote: >>>>>>>> [Chris or Alan, please review and file a bug] >>>>>>>> >>>>>>>> OK, guys, >>>>>>>> >>>>>>>> Here's a patch: >>>>>>>> >>>>>>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize/ >>>>>>>> >>>>>>>> Martin >>>>>>>> >>>>>>>> On Fri, Mar 5, 2010 at 02:48, Kevin L. Stern >>>>>>>> >>>>>>>> wrote: >>>>>>>>> Hi Martin, >>>>>>>>> >>>>>>>>> Thank you for your reply. If I may, PriorityQueue appears to >>>>>>>>> employ >>>>>>>>> the >>>>>>>>> simple strategy that I suggested above in its grow method: >>>>>>>>> >>>>>>>>> int newCapacity = ((oldCapacity < 64)? >>>>>>>>> ((oldCapacity + 1) * 2): >>>>>>>>> ((oldCapacity / 2) * 3)); >>>>>>>>> if (newCapacity < 0) // overflow >>>>>>>>> newCapacity = Integer.MAX_VALUE; >>>>>>>>> >>>>>>>>> It might be desirable to set a common strategy for capacity >>>>>>>>> increase >>>>>>>>> for >>>>>>>>> all >>>>>>>>> collections. >>>>>>>>> >>>>>>>>> Regards, >>>>>>>>> >>>>>>>>> Kevin >>>>>>>>> >>>>>>>>> On Fri, Mar 5, 2010 at 3:04 AM, Martin Buchholz >>>>>>>>> >>>>>>>>> wrote: >>>>>>>>>> Hi Kevin, >>>>>>>>>> >>>>>>>>>> As you've noticed, creating objects within a factor of two of >>>>>>>>>> their natural limits is a good way to expose lurking bugs. >>>>>>>>>> >>>>>>>>>> I'm the one responsible for the algorithm in ArrayList. >>>>>>>>>> I'm a bit embarrassed, looking at that code today. >>>>>>>>>> We could set the array size to Integer.MAX_VALUE, >>>>>>>>>> but then you might hit an independent buglet in hotspot >>>>>>>>>> that you cannot allocate an array with Integer.MAX_VALUE >>>>>>>>>> elements, but Integer.MAX_VALUE - 5 (or so) works. >>>>>>>>>> >>>>>>>>>> It occurs to me that increasing the size by 50% is better done by >>>>>>>>>> int newCapacity = oldCapacity + (oldCapacity >> 1) + 1; >>>>>>>>>> >>>>>>>>>> I agree with the plan of setting the capacity to something near >>>>>>>>>> MAX_VALUE on overflow, and throw OutOfMemoryError on next resize. >>>>>>>>>> >>>>>>>>>> These bugs are not known. >>>>>>>>>> Chris Hegarty, could you file a bug for us? >>>>>>>>>> >>>>>>>>>> Martin >>>>>>>>>> >>>>>>>>>> On Wed, Mar 3, 2010 at 17:41, Kevin L. Stern >>>>>>>>>> >>>>>>>>>> wrote: >>>>>>>>>>> Greetings, >>>>>>>>>>> >>>>>>>>>>> I've noticed bugs in java.util.ArrayList, java.util.Hashtable >>>>>>>>>>> and >>>>>>>>>>> java.io.ByteArrayOutputStream which arise when the capacities >>>>>>>>>>> of the >>>>>>>>>>> data >>>>>>>>>>> structures reach a particular threshold. More below. >>>>>>>>>>> >>>>>>>>>>> When the capacity of an ArrayList reaches >>>>>>>>>>> (2/3)*Integer.MAX_VALUE >>>>>>>>>>> its >>>>>>>>>>> size >>>>>>>>>>> reaches its capacity and an add or an insert operation is >>>>>>>>>>> invoked, >>>>>>>>>>> the >>>>>>>>>>> capacity is increased by only one element. Notice that in the >>>>>>>>>>> following >>>>>>>>>>> excerpt from ArrayList.ensureCapacity the new capacity is set to >>>>>>>>>>> (3/2) >>>>>>>>>>> * >>>>>>>>>>> oldCapacity + 1 unless this value would not suffice to >>>>>>>>>>> accommodate >>>>>>>>>>> the >>>>>>>>>>> required capacity in which case it is set to the required >>>>>>>>>>> capacity. >>>>>>>>>>> If >>>>>>>>>>> the >>>>>>>>>>> current capacity is at least (2/3)*Integer.MAX_VALUE, then >>>>>>>>>>> (oldCapacity >>>>>>>>>>> * >>>>>>>>>>> 3)/2 + 1 overflows and resolves to a negative number >>>>>>>>>>> resulting in >>>>>>>>>>> the >>>>>>>>>>> new >>>>>>>>>>> capacity being set to the required capacity. The major >>>>>>>>>>> consequence >>>>>>>>>>> of >>>>>>>>>>> this >>>>>>>>>>> is that each subsequent add/insert operation results in a full >>>>>>>>>>> resize >>>>>>>>>>> of >>>>>>>>>>> the >>>>>>>>>>> ArrayList causing performance to degrade significantly. >>>>>>>>>>> >>>>>>>>>>> int newCapacity = (oldCapacity * 3)/2 + 1; >>>>>>>>>>> if (newCapacity < minCapacity) >>>>>>>>>>> newCapacity = minCapacity; >>>>>>>>>>> >>>>>>>>>>> Hashtable breaks entirely when the size of its backing array >>>>>>>>>>> reaches >>>>>>>>>>> (1/2) * >>>>>>>>>>> Integer.MAX_VALUE and a rehash is necessary as is evident >>>>>>>>>>> from the >>>>>>>>>>> following >>>>>>>>>>> excerpt from rehash. Notice that rehash will attempt to >>>>>>>>>>> create an >>>>>>>>>>> array >>>>>>>>>>> of >>>>>>>>>>> negative size if the size of the backing array reaches (1/2) * >>>>>>>>>>> Integer.MAX_VALUE since oldCapacity * 2 + 1 overflows and >>>>>>>>>>> resolves >>>>>>>>>>> to a >>>>>>>>>>> negative number. >>>>>>>>>>> >>>>>>>>>>> int newCapacity = oldCapacity * 2 + 1; >>>>>>>>>>> HashtableEntry newTable[] = new HashtableEntry[newCapacity]; >>>>>>>>>>> >>>>>>>>>>> When the capacity of the backing array in a >>>>>>>>>>> ByteArrayOutputStream >>>>>>>>>>> reaches >>>>>>>>>>> (1/2) * Integer.MAX_VALUE its size reaches its capacity and a >>>>>>>>>>> write >>>>>>>>>>> operation is invoked, the capacity of the backing array is >>>>>>>>>>> increased >>>>>>>>>>> only by >>>>>>>>>>> the required number of elements. Notice that in the following >>>>>>>>>>> excerpt >>>>>>>>>>> from >>>>>>>>>>> ByteArrayOutputStream.write(int) the new backing array >>>>>>>>>>> capacity is >>>>>>>>>>> set >>>>>>>>>>> to 2 >>>>>>>>>>> * buf.length unless this value would not suffice to >>>>>>>>>>> accommodate the >>>>>>>>>>> required >>>>>>>>>>> capacity in which case it is set to the required capacity. >>>>>>>>>>> If the >>>>>>>>>>> current >>>>>>>>>>> backing array capacity is at least (1/2) * Integer.MAX_VALUE >>>>>>>>>>> + 1, >>>>>>>>>>> then >>>>>>>>>>> buf.length << 1 overflows and resolves to a negative number >>>>>>>>>>> resulting >>>>>>>>>>> in >>>>>>>>>>> the >>>>>>>>>>> new capacity being set to the required capacity. The major >>>>>>>>>>> consequence >>>>>>>>>>> of >>>>>>>>>>> this, like with ArrayList, is that each subsequent write >>>>>>>>>>> operation >>>>>>>>>>> results >>>>>>>>>>> in a full resize of the ByteArrayOutputStream causing >>>>>>>>>>> performance to >>>>>>>>>>> degrade >>>>>>>>>>> significantly. >>>>>>>>>>> >>>>>>>>>>> int newcount = count + 1; >>>>>>>>>>> if (newcount > buf.length) { >>>>>>>>>>> buf = Arrays.copyOf(buf, Math.max(buf.length << 1, >>>>>>>>>>> newcount)); >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> It is interesting to note that any statements about the >>>>>>>>>>> amortized >>>>>>>>>>> time >>>>>>>>>>> complexity of add/insert operations, such as the one in the >>>>>>>>>>> ArrayList >>>>>>>>>>> javadoc, are invalidated by the performance related bugs. One >>>>>>>>>>> solution >>>>>>>>>>> to >>>>>>>>>>> the above situations is to set the new capacity of the >>>>>>>>>>> backing array >>>>>>>>>>> to >>>>>>>>>>> Integer.MAX_VALUE when the initial size calculation results in a >>>>>>>>>>> negative >>>>>>>>>>> number during a resize. >>>>>>>>>>> >>>>>>>>>>> Apologies if these bugs are already known. >>>>>>>>>>> >>>>>>>>>>> Regards, >>>>>>>>>>> >>>>>>>>>>> Kevin >>>>>>>>>>> From paul.hohensee at Sun.COM Tue May 11 00:00:52 2010 From: paul.hohensee at Sun.COM (Paul Hohensee) Date: Mon, 10 May 2010 20:00:52 -0400 Subject: signal chaining and self defence In-Reply-To: <4BE54B85.7040000@fh-landshut.de> References: <4BE54B85.7040000@fh-landshut.de> Message-ID: <4BE89E34.3000308@sun.com> A partial answer: one of the Hotspot engineers says "I think the short answer is that chaining requires LD_PRELOAD to override the signal entry points. Otherwise we [Hotspot] wouldn't see the calls that change the signal handlers. If the Java command itself linked against jsig that would work too I think. I believe that's the only way to solve the problem he is seeing in an automatic fashion. Depending on how the driver library gets loaded they might be able to build their own signal handler trampolines to work around it and correct the signal handlers after it gets loaded." Regards, Paul On 5/8/10 7:31 AM, Michael Bien wrote: > Hello everyone, > > i am one of the maintainers of JOGL and wrote JOCL > (http://jogamp.org/) and we are currently facing some signal handling > issues caused by the nvidia and amd drivers. > (I got the hint to post to this list since there is no better alias > for this kind of topics) > > e.g. the nvidia OpenCL driver uses at least the following handlers: > Warning: SIGSEGV handler expected:libjvm.so+0x5d8cf0 > found:libnvidia-compiler.so+0x1865e0 > Warning: SIGILL handler expected:libjvm.so+0x5d8cf0 > found:libnvidia-compiler.so+0x1865e0 > Warning: SIGFPE handler expected:libjvm.so+0x5d8cf0 > found:libnvidia-compiler.so+0x1865e0 > Warning: SIGBUS handler expected:libjvm.so+0x5d8cf0 > found:libnvidia-compiler.so+0x1865e0 > Warning: SIGXFSZ handler expected:libjvm.so+0x5d8cf0 > found:libnvidia-compiler.so+0x1865e0 > (-Xcheck:jni) > > which basically makes the jvm unusable on Linux and leads to > segmentation faults (in the driver, I suppose the driver catches jvm > signals). > > LD_PRELOAD > (http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/signals.html#gbzbl) > works perfectly but it is not allowed for webstart + applets... > > do you have any advice how we could workaround this issue? The perfect > solution would be a "-XX:enableSignalChaining" flag which we could set > via jnlp. Since the webstart JVM is out of process anyway (since u10 > or so) this would probably work. > > Why isn't signal chaining enabled by default on linux and solaris? It > looks like a good self-defence mechanism for me :) > > best regards, > Michael Bien > > --- > > http://michael-bien.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From jonathan.gibbons at oracle.com Thu May 13 18:31:35 2010 From: jonathan.gibbons at oracle.com (jonathan.gibbons at oracle.com) Date: Thu, 13 May 2010 18:31:35 +0000 Subject: hg: jdk7/tl/langtools: 6952188: update timeout for langtools jtreg tests on JPRT Message-ID: <20100513183137.9846144722@hg.openjdk.java.net> Changeset: ebf09be0222c Author: jjg Date: 2010-05-13 11:30 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/ebf09be0222c 6952188: update timeout for langtools jtreg tests on JPRT Reviewed-by: ohair ! test/Makefile From xueming.shen at oracle.com Fri May 14 03:03:38 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Thu, 13 May 2010 20:03:38 -0700 Subject: Typo in ZipException an -> a Message-ID: <4BECBD8A.6040406@oracle.com> A trivial doc typo. http://cr.openjdk.java.net/~sherman/6951064/webrev Thanks, -Sherman From martinrb at google.com Fri May 14 03:55:37 2010 From: martinrb at google.com (Martin Buchholz) Date: Thu, 13 May 2010 20:55:37 -0700 Subject: Typo in ZipException an -> a In-Reply-To: <4BECBD8A.6040406@oracle.com> References: <4BECBD8A.6040406@oracle.com> Message-ID: Looks good to me! On Thu, May 13, 2010 at 20:03, Xueming Shen wrote: > A trivial doc typo. > > http://cr.openjdk.java.net/~sherman/6951064/webrev > > Thanks, > -Sherman > From xueming.shen at oracle.com Fri May 14 04:46:07 2010 From: xueming.shen at oracle.com (xueming.shen at oracle.com) Date: Fri, 14 May 2010 04:46:07 +0000 Subject: hg: jdk7/tl/jdk: 6951064: Typo in javadoc for ZipException ctors Message-ID: <20100514044620.3B3A1447DB@hg.openjdk.java.net> Changeset: aa1b15bdbf2b Author: sherman Date: 2010-05-13 21:30 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/aa1b15bdbf2b 6951064: Typo in javadoc for ZipException ctors Summary: fixed the doc typo Reviewed-by: martin ! src/share/classes/java/util/zip/ZipException.java From martinrb at google.com Fri May 14 04:59:50 2010 From: martinrb at google.com (martinrb at google.com) Date: Fri, 14 May 2010 04:59:50 +0000 Subject: hg: jdk7/tl/jdk: 6952330: Fix for 6933217 broke contract of StringBuffer.ensureCapacity Message-ID: <20100514050003.2D274447DC@hg.openjdk.java.net> Changeset: e85e03ef61c1 Author: martin Date: 2010-05-13 21:56 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/e85e03ef61c1 6952330: Fix for 6933217 broke contract of StringBuffer.ensureCapacity Summary: make sure to grow with size => size * 2 + 2 Reviewed-by: dholmes, chegar, ohair ! src/share/classes/java/lang/AbstractStringBuilder.java + test/java/lang/StringBuffer/Capacity.java From martinrb at google.com Fri May 14 05:09:49 2010 From: martinrb at google.com (Martin Buchholz) Date: Thu, 13 May 2010 22:09:49 -0700 Subject: Bugs in java.util.ArrayList, java.util.Hashtable and java.io.ByteArrayOutputStream In-Reply-To: <4BEC8131.6030208@oracle.com> References: <1704b7a21003031741m734545f1gb0170ed5fa6f6d68@mail.gmail.com> <1ccfd1c11003081810u54fb22e6k25230f4eb5ca1b18@mail.gmail.com> <4B9633EA.8070101@sun.com> <4BC82FFF.20502@oracle.com> <4BEB4854.7000403@oracle.com> <4BEB5D0F.1000200@oracle.com> <4BEC8131.6030208@oracle.com> Message-ID: OK, I committed the fix for this. I also added some gratuitous tests to the new test case. Martin On Thu, May 13, 2010 at 15:46, David Holmes wrote: > CR: 6952330 Fix for 6933217 broke contract of StringBuffer.ensureCapacity > > Thanks, > David > > David Holmes said the following on 05/13/10 11:59: >> >> Hi Martin, >> >> Bugtraq is offline so I can't file a CR right now. >> >> The was caught by Mauve tests. Kelly sent a link to the mailing list but I >> don't think he's a member so it's probably held up for approval. >> >> Martin Buchholz said the following on 05/13/10 11:38: >>> >>> Webrev at >>> >>> >>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/StringBuffer-capacity/StringBuffer-capacity.patch >> >> Fix looks fine. Took me a few tries to confirm the test logic :) >> >> Thanks, >> David >> ----- >> >> >>> Martin >>> >>> On Wed, May 12, 2010 at 18:23, Martin Buchholz >>> wrote: >>>> >>>> Alright, I'm convinced this is a bug. ?Please file one in bugtraq >>>> (or expunge from tl in the unlikely event that would be permitted). >>>> It appears we very carefully specified the capacity manipulation >>>> behavior, >>>> but didn't have any jtreg tests for it. >>>> Do y'all run the Mauve tests? ?(Probably a good idea) >>>> >>>> Martin >>>> >>>> On Wed, May 12, 2010 at 17:31, David Holmes >>>> wrote: >>>>> >>>>> Chris, Martin, >>>>> >>>>> The changes to AbstractStringBuilder violate the specification for >>>>> ensureCapacity: it has to grow from N to 2N+2. The new code in: >>>>> >>>>> http://hg.openjdk.java.net/jdk7/tl-gate/jdk/rev/ec45423a4700 >>>>> >>>>> ?void expandCapacity(int minimumCapacity) { >>>>> - int newCapacity = (value.length + 1) * 2; >>>>> + int newCapacity = value.length * 2; >>>>> >>>>> Has dropped the +2 part. >>>>> >>>>> This is causing test failures. >>>>> >>>>> David >>>>> ----- >>>>> >>>>> Chris Hegarty said the following on 04/16/10 19:38: >>>>>> >>>>>> Martin Buchholz wrote: >>>>>>> >>>>>>> Hi Chris, >>>>>>> >>>>>>> I recently discovered another place to handle huge arrays better - in >>>>>>> AbstractCollection. >>>>>>> I've put those changes into >>>>>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize2/ >>>>>>> I propose to qfold these into the original changes for this bug >>>>>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize/ >>>>>>> which have not yet been committed. >>>>>> >>>>>> Good catch Martin, these additional changes look good. >>>>>> >>>>>> -Chris. >>>>>> >>>>>>> Martin >>>>>>> >>>>>>> On Tue, Mar 9, 2010 at 04:41, Christopher Hegarty -Sun Microsystems >>>>>>> Ireland wrote: >>>>>>>> >>>>>>>> Sorry Martin, I appear to have missed your original request to file >>>>>>>> this >>>>>>>> bug. I since filed the following: >>>>>>>> >>>>>>>> ?6933217: Huge arrays handled poorly in core libraries >>>>>>>> >>>>>>>> The changes you are proposing seem reasonable to me. >>>>>>>> >>>>>>>> -Chris. >>>>>>>> >>>>>>>> Martin Buchholz wrote: >>>>>>>>> >>>>>>>>> [Chris or Alan, please review and file a bug] >>>>>>>>> >>>>>>>>> OK, guys, >>>>>>>>> >>>>>>>>> Here's a patch: >>>>>>>>> >>>>>>>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/ArrayResize/ >>>>>>>>> >>>>>>>>> Martin >>>>>>>>> >>>>>>>>> On Fri, Mar 5, 2010 at 02:48, Kevin L. Stern >>>>>>>>> >>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>> Hi Martin, >>>>>>>>>> >>>>>>>>>> Thank you for your reply. ?If I may, PriorityQueue appears to >>>>>>>>>> employ >>>>>>>>>> the >>>>>>>>>> simple strategy that I suggested above in its grow method: >>>>>>>>>> >>>>>>>>>> ? ? ?int newCapacity = ((oldCapacity < 64)? >>>>>>>>>> ? ? ? ? ? ? ? ? ? ? ? ? ((oldCapacity + 1) * 2): >>>>>>>>>> ? ? ? ? ? ? ? ? ? ? ? ? ((oldCapacity / 2) * 3)); >>>>>>>>>> ? ? ?if (newCapacity < 0) // overflow >>>>>>>>>> ? ? ? ? ?newCapacity = Integer.MAX_VALUE; >>>>>>>>>> >>>>>>>>>> It might be desirable to set a common strategy for capacity >>>>>>>>>> increase >>>>>>>>>> for >>>>>>>>>> all >>>>>>>>>> collections. >>>>>>>>>> >>>>>>>>>> Regards, >>>>>>>>>> >>>>>>>>>> Kevin >>>>>>>>>> >>>>>>>>>> On Fri, Mar 5, 2010 at 3:04 AM, Martin Buchholz >>>>>>>>>> >>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>> Hi Kevin, >>>>>>>>>>> >>>>>>>>>>> As you've noticed, creating objects within a factor of two of >>>>>>>>>>> their natural limits is a good way to expose lurking bugs. >>>>>>>>>>> >>>>>>>>>>> I'm the one responsible for the algorithm in ArrayList. >>>>>>>>>>> I'm a bit embarrassed, looking at that code today. >>>>>>>>>>> We could set the array size to Integer.MAX_VALUE, >>>>>>>>>>> but then you might hit an independent buglet in hotspot >>>>>>>>>>> that you cannot allocate an array with Integer.MAX_VALUE >>>>>>>>>>> elements, but Integer.MAX_VALUE - 5 (or so) works. >>>>>>>>>>> >>>>>>>>>>> It occurs to me that increasing the size by 50% is better done by >>>>>>>>>>> int newCapacity = oldCapacity + (oldCapacity >> 1) + 1; >>>>>>>>>>> >>>>>>>>>>> I agree with the plan of setting the capacity to something near >>>>>>>>>>> MAX_VALUE on overflow, and throw OutOfMemoryError on next resize. >>>>>>>>>>> >>>>>>>>>>> These bugs are not known. >>>>>>>>>>> Chris Hegarty, could you file a bug for us? >>>>>>>>>>> >>>>>>>>>>> Martin >>>>>>>>>>> >>>>>>>>>>> On Wed, Mar 3, 2010 at 17:41, Kevin L. Stern >>>>>>>>>>> >>>>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>> Greetings, >>>>>>>>>>>> >>>>>>>>>>>> I've noticed bugs in java.util.ArrayList, java.util.Hashtable >>>>>>>>>>>> and >>>>>>>>>>>> java.io.ByteArrayOutputStream which arise when the capacities of >>>>>>>>>>>> the >>>>>>>>>>>> data >>>>>>>>>>>> structures reach a particular threshold. ?More below. >>>>>>>>>>>> >>>>>>>>>>>> When the capacity of an ArrayList reaches >>>>>>>>>>>> (2/3)*Integer.MAX_VALUE >>>>>>>>>>>> its >>>>>>>>>>>> size >>>>>>>>>>>> reaches its capacity and an add or an insert operation is >>>>>>>>>>>> invoked, >>>>>>>>>>>> the >>>>>>>>>>>> capacity is increased by only one element. ?Notice that in the >>>>>>>>>>>> following >>>>>>>>>>>> excerpt from ArrayList.ensureCapacity the new capacity is set to >>>>>>>>>>>> (3/2) >>>>>>>>>>>> * >>>>>>>>>>>> oldCapacity + 1 unless this value would not suffice to >>>>>>>>>>>> accommodate >>>>>>>>>>>> the >>>>>>>>>>>> required capacity in which case it is set to the required >>>>>>>>>>>> capacity. >>>>>>>>>>>> ?If >>>>>>>>>>>> the >>>>>>>>>>>> current capacity is at least (2/3)*Integer.MAX_VALUE, then >>>>>>>>>>>> (oldCapacity >>>>>>>>>>>> * >>>>>>>>>>>> 3)/2 + 1 overflows and resolves to a negative number resulting >>>>>>>>>>>> in >>>>>>>>>>>> the >>>>>>>>>>>> new >>>>>>>>>>>> capacity being set to the required capacity. ?The major >>>>>>>>>>>> consequence >>>>>>>>>>>> of >>>>>>>>>>>> this >>>>>>>>>>>> is that each subsequent add/insert operation results in a full >>>>>>>>>>>> resize >>>>>>>>>>>> of >>>>>>>>>>>> the >>>>>>>>>>>> ArrayList causing performance to degrade significantly. >>>>>>>>>>>> >>>>>>>>>>>> ? ? ?int newCapacity = (oldCapacity * 3)/2 + 1; >>>>>>>>>>>> ? ? ? ? ?if (newCapacity < minCapacity) >>>>>>>>>>>> ? ? ?newCapacity = minCapacity; >>>>>>>>>>>> >>>>>>>>>>>> Hashtable breaks entirely when the size of its backing array >>>>>>>>>>>> reaches >>>>>>>>>>>> (1/2) * >>>>>>>>>>>> Integer.MAX_VALUE and a rehash is necessary as is evident from >>>>>>>>>>>> the >>>>>>>>>>>> following >>>>>>>>>>>> excerpt from rehash. ?Notice that rehash will attempt to create >>>>>>>>>>>> an >>>>>>>>>>>> array >>>>>>>>>>>> of >>>>>>>>>>>> negative size if the size of the backing array reaches (1/2) * >>>>>>>>>>>> Integer.MAX_VALUE since oldCapacity * 2 + 1 overflows and >>>>>>>>>>>> resolves >>>>>>>>>>>> to a >>>>>>>>>>>> negative number. >>>>>>>>>>>> >>>>>>>>>>>> ?int newCapacity = oldCapacity * 2 + 1; >>>>>>>>>>>> ?HashtableEntry newTable[] = new HashtableEntry[newCapacity]; >>>>>>>>>>>> >>>>>>>>>>>> When the capacity of the backing array in a >>>>>>>>>>>> ByteArrayOutputStream >>>>>>>>>>>> reaches >>>>>>>>>>>> (1/2) * Integer.MAX_VALUE its size reaches its capacity and a >>>>>>>>>>>> write >>>>>>>>>>>> operation is invoked, the capacity of the backing array is >>>>>>>>>>>> increased >>>>>>>>>>>> only by >>>>>>>>>>>> the required number of elements. ?Notice that in the following >>>>>>>>>>>> excerpt >>>>>>>>>>>> from >>>>>>>>>>>> ByteArrayOutputStream.write(int) the new backing array capacity >>>>>>>>>>>> is >>>>>>>>>>>> set >>>>>>>>>>>> to 2 >>>>>>>>>>>> * buf.length unless this value would not suffice to accommodate >>>>>>>>>>>> the >>>>>>>>>>>> required >>>>>>>>>>>> capacity in which case it is set to the required capacity. ?If >>>>>>>>>>>> the >>>>>>>>>>>> current >>>>>>>>>>>> backing array capacity is at least (1/2) * Integer.MAX_VALUE + >>>>>>>>>>>> 1, >>>>>>>>>>>> then >>>>>>>>>>>> buf.length << 1 overflows and resolves to a negative number >>>>>>>>>>>> resulting >>>>>>>>>>>> in >>>>>>>>>>>> the >>>>>>>>>>>> new capacity being set to the required capacity. ?The major >>>>>>>>>>>> consequence >>>>>>>>>>>> of >>>>>>>>>>>> this, like with ArrayList, is that each subsequent write >>>>>>>>>>>> operation >>>>>>>>>>>> results >>>>>>>>>>>> in a full resize of the ByteArrayOutputStream causing >>>>>>>>>>>> performance to >>>>>>>>>>>> degrade >>>>>>>>>>>> significantly. >>>>>>>>>>>> >>>>>>>>>>>> ?int newcount = count + 1; >>>>>>>>>>>> ?if (newcount > buf.length) { >>>>>>>>>>>> ? ? ? ? ?buf = Arrays.copyOf(buf, Math.max(buf.length << 1, >>>>>>>>>>>> newcount)); >>>>>>>>>>>> ?} >>>>>>>>>>>> >>>>>>>>>>>> It is interesting to note that any statements about the >>>>>>>>>>>> amortized >>>>>>>>>>>> time >>>>>>>>>>>> complexity of add/insert operations, such as the one in the >>>>>>>>>>>> ArrayList >>>>>>>>>>>> javadoc, are invalidated by the performance related bugs. ?One >>>>>>>>>>>> solution >>>>>>>>>>>> to >>>>>>>>>>>> the above situations is to set the new capacity of the backing >>>>>>>>>>>> array >>>>>>>>>>>> to >>>>>>>>>>>> Integer.MAX_VALUE when the initial size calculation results in a >>>>>>>>>>>> negative >>>>>>>>>>>> number during a resize. >>>>>>>>>>>> >>>>>>>>>>>> Apologies if these bugs are already known. >>>>>>>>>>>> >>>>>>>>>>>> Regards, >>>>>>>>>>>> >>>>>>>>>>>> Kevin >>>>>>>>>>>> > From xueming.shen at oracle.com Fri May 14 15:31:31 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 14 May 2010 08:31:31 -0700 Subject: RFC links on java.util.zip's class API Message-ID: <4BED6CD3.9010504@oracle.com> Hi The links to http://www.isi.edu/in-notes/rfc195[012].txt on java.util.zip's class API seem broken (for a while?). I don't know if this is a temporary or permanent removal of the rfc stuff on isi site. Should we consider move the links to somewhere more "stable"? how about http://www.ietf.org/rfc/rfc195[012].txt. -Sherman http://java.sun.com/javase/6/docs/api/ http://download.java.net/jdk7/docs/api/ http://www.isi.edu/in-notes/rfc1950.txt http://www.isi.edu/in-notes/rfc1951.txt http://www.isi.edu/in-notes/rfc1952.txt From martinrb at google.com Fri May 14 17:59:32 2010 From: martinrb at google.com (Martin Buchholz) Date: Fri, 14 May 2010 10:59:32 -0700 Subject: RFC links on java.util.zip's class API In-Reply-To: <4BED6CD3.9010504@oracle.com> References: <4BED6CD3.9010504@oracle.com> Message-ID: On Fri, May 14, 2010 at 08:31, Xueming Shen wrote: > Hi > > The links to http://www.isi.edu/in-notes/rfc195[012].txt on java.util.zip's > class API > seem broken (for a while?). I don't know if this is a temporary or permanent > removal > of the rfc stuff on isi site. Should we consider move the links to somewhere > more > "stable"? how about http://www.ietf.org/rfc/rfc195[012].txt. I agree. It seems crazy to be using isi.edu as a long term rfc reference. I had never heard of isi.edu before. Their home page claims: ISI Recognized for Key Role in Internet Development but that does not appear to include continuing to maintain their rfc document archive!? Martin > -Sherman > > http://java.sun.com/javase/6/docs/api/ > http://download.java.net/jdk7/docs/api/ > http://www.isi.edu/in-notes/rfc1950.txt > http://www.isi.edu/in-notes/rfc1951.txt > http://www.isi.edu/in-notes/rfc1952.txt > > From xueming.shen at oracle.com Fri May 14 18:43:03 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 14 May 2010 11:43:03 -0700 Subject: RFC links on java.util.zip's class API In-Reply-To: References: <4BED6CD3.9010504@oracle.com> Message-ID: <4BED99B7.6010600@oracle.com> OK, please help review. 6952701: Use http://www.ietf.org/rfc for those rfc links in java.util.zip's package doc http://cr.openjdk.java.net/~sherman/6952701/webrev -Sherman Martin Buchholz wrote: > On Fri, May 14, 2010 at 08:31, Xueming Shen wrote: > >> Hi >> >> The links to http://www.isi.edu/in-notes/rfc195[012].txt on java.util.zip's >> class API >> seem broken (for a while?). I don't know if this is a temporary or permanent >> removal >> of the rfc stuff on isi site. Should we consider move the links to somewhere >> more >> "stable"? how about http://www.ietf.org/rfc/rfc195[012].txt. >> > > I agree. It seems crazy to be using isi.edu as a long term rfc reference. > > I had never heard of isi.edu before. > > Their home page claims: > ISI Recognized for Key Role in Internet Development > but that does not appear to include > continuing to maintain their rfc document archive!? > > Martin > > >> -Sherman >> >> http://java.sun.com/javase/6/docs/api/ >> http://download.java.net/jdk7/docs/api/ >> http://www.isi.edu/in-notes/rfc1950.txt >> http://www.isi.edu/in-notes/rfc1951.txt >> http://www.isi.edu/in-notes/rfc1952.txt >> >> >> From martinrb at google.com Fri May 14 18:53:19 2010 From: martinrb at google.com (Martin Buchholz) Date: Fri, 14 May 2010 11:53:19 -0700 Subject: RFC links on java.util.zip's class API In-Reply-To: <4BED99B7.6010600@oracle.com> References: <4BED6CD3.9010504@oracle.com> <4BED99B7.6010600@oracle.com> Message-ID: There's 23 occurrences of isi.edu under jdk/src. Could we do an even more global global-replace? $ rg -w isi.edu | wc -l 23 Martin On Fri, May 14, 2010 at 11:43, Xueming Shen wrote: > OK, please help review. > > 6952701: Use http://www.ietf.org/rfc for those rfc links in java.util.zip's > package doc > > http://cr.openjdk.java.net/~sherman/6952701/webrev > > -Sherman > > Martin Buchholz wrote: >> >> On Fri, May 14, 2010 at 08:31, Xueming Shen >> wrote: >> >>> >>> Hi >>> >>> The links to http://www.isi.edu/in-notes/rfc195[012].txt on >>> java.util.zip's >>> class API >>> seem broken (for a while?). I don't know if this is a temporary or >>> permanent >>> removal >>> of the rfc stuff on isi site. Should we consider move the links to >>> somewhere >>> more >>> "stable"? how about http://www.ietf.org/rfc/rfc195[012].txt. >>> >> >> I agree. ?It seems crazy to be using isi.edu as a long term rfc reference. >> >> I had never heard of isi.edu before. >> >> Their home page claims: >> ? ? ? ?ISI Recognized for Key Role in Internet Development >> but that does not appear to include >> continuing to maintain their rfc document archive!? >> >> Martin >> >> >>> >>> -Sherman >>> >>> http://java.sun.com/javase/6/docs/api/ >>> http://download.java.net/jdk7/docs/api/ >>> http://www.isi.edu/in-notes/rfc1950.txt >>> http://www.isi.edu/in-notes/rfc1951.txt >>> http://www.isi.edu/in-notes/rfc1952.txt >>> >>> >>> > > From xueming.shen at oracle.com Fri May 14 19:39:29 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 14 May 2010 12:39:29 -0700 Subject: RFC links on java.util.zip's class API In-Reply-To: References: <4BED6CD3.9010504@oracle.com> <4BED99B7.6010600@oracle.com> Message-ID: <4BEDA6F1.9060905@oracle.com> webrev has been updated to update the isi.edu reference to ietf (and one iana) for public APIs. The references in src/share/classes/com/sun are not touched, including 2 apache drop-in xml code. Should be enough for today's exercise:-) Sherman Martin Buchholz wrote: > There's 23 occurrences of isi.edu under jdk/src. > Could we do an even more global global-replace? > > $ rg -w isi.edu | wc -l > 23 > > Martin > > On Fri, May 14, 2010 at 11:43, Xueming Shen wrote: > >> OK, please help review. >> >> 6952701: Use http://www.ietf.org/rfc for those rfc links in java.util.zip's >> package doc >> >> http://cr.openjdk.java.net/~sherman/6952701/webrev >> >> -Sherman >> >> Martin Buchholz wrote: >> >>> On Fri, May 14, 2010 at 08:31, Xueming Shen >>> wrote: >>> >>> >>>> Hi >>>> >>>> The links to http://www.isi.edu/in-notes/rfc195[012].txt on >>>> java.util.zip's >>>> class API >>>> seem broken (for a while?). I don't know if this is a temporary or >>>> permanent >>>> removal >>>> of the rfc stuff on isi site. Should we consider move the links to >>>> somewhere >>>> more >>>> "stable"? how about http://www.ietf.org/rfc/rfc195[012].txt. >>>> >>>> >>> I agree. It seems crazy to be using isi.edu as a long term rfc reference. >>> >>> I had never heard of isi.edu before. >>> >>> Their home page claims: >>> ISI Recognized for Key Role in Internet Development >>> but that does not appear to include >>> continuing to maintain their rfc document archive!? >>> >>> Martin >>> >>> >>> >>>> -Sherman >>>> >>>> http://java.sun.com/javase/6/docs/api/ >>>> http://download.java.net/jdk7/docs/api/ >>>> http://www.isi.edu/in-notes/rfc1950.txt >>>> http://www.isi.edu/in-notes/rfc1951.txt >>>> http://www.isi.edu/in-notes/rfc1952.txt >>>> >>>> >>>> >>>> >> From iaroslavski at mail.ru Fri May 14 19:54:06 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Fri, 14 May 2010 23:54:06 +0400 Subject: =?koi8-r?Q?Re[6]=3A_New_portion_of_improvements_for_Dual-Pivot_Quicksort?= In-Reply-To: References: Message-ID: Hello, I've updated the class, please, review the changes. Vladimir Fri, 14 May 2010 01:48:11 +0700 ?????? ?? Dmytro Sheyko : > Yes. I prefer F (Find First zero using binary search) over C (Count negatives) and S (Smart Scan for zero). > > > From: iaroslavski at mail.ru > > To: dmytro_sheyko at hotmail.com > > CC: jjb at google.com; core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > Subject: Re[4]: New portion of improvements for Dual-Pivot Quicksort > > Date: Thu, 13 May 2010 21:34:54 +0400 > > > > Dmytro, > > > > I've tested your suggested variants, and found that case "C" > > (very interesting approach to find first position of zero > > by counting negative elements) works slower than original > > or two other cases. > > > > Implementations "F" and "S" are very close to each other > > and little bit faster than original. I prefer case "F": > > it is shorter and more clear. Do you agree? > > > > I'll prepare updated DualPivotQuicksort file and send it > > tomorrow. > > > > Thank you, > > Vladimir > > > > Wed, 12 May 2010 17:04:52 +0700 ?????? ?? Dmytro Sheyko : > > > > > Vladimir, > > > > > > Your changes are good for me. > > > > > > Additionally I have some comments/proposals regarding dealing with negative zeros. > > > > > > 1. Scanning for the first zero we can avoid range check (i >= left) if we have at least one negative value. > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 2010 > > > @@ -1705,10 +1705,15 @@ > > > } > > > > > > // Find first zero element > > > - int zeroIndex = findAnyZero(a, left, n); > > > + int zeroIndex = 0; > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > > - zeroIndex = i; > > > + if (a[left] < 0.0f) { > > > + zeroIndex = findAnyZero(a, left, n); > > > + > > > + // there is at least one negative value, so range check is not needed > > > + for (int i = zeroIndex - 1; /*i >= left &&*/ a[i] == 0.0f; i--) { > > > + zeroIndex = i; > > > + } > > > } > > > > > > // Turn the right number of positive zeros back into negative zeros > > > > > > 2. We can find the position of the first zero by counting negative values during preprocessing phase. > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 2010 > > > @@ -1678,7 +1678,7 @@ > > > * Phase 1: Count negative zeros and move NaNs to end of array. > > > */ > > > final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f); > > > - int numNegativeZeros = 0; > > > + int numNegativeZeros = 0, numNegativeValues = 0; > > > int n = right; > > > > > > for (int k = left; k <= n; k++) { > > > @@ -1689,6 +1689,8 @@ > > > } else if (ak != ak) { // i.e., ak is NaN > > > a[k--] = a[n]; > > > a[n--] = Float.NaN; > > > + } else if (ak < 0.0f) { > > > + numNegativeValues++; > > > } > > > } > > > > > > @@ -1705,7 +1707,7 @@ > > > } > > > > > > // Find first zero element > > > - int zeroIndex = findAnyZero(a, left, n); > > > + int zeroIndex = numNegativeValues; > > > > > > for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > > zeroIndex = i; > > > > > > 3. We can use binary search to find the first zero and thus avoid linear scan. > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 2010 > > > @@ -1705,11 +1705,7 @@ > > > } > > > > > > // Find first zero element > > > - int zeroIndex = findAnyZero(a, left, n); > > > - > > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > > - zeroIndex = i; > > > - } > > > + int zeroIndex = findFirstZero(a, left, n); > > > > > > // Turn the right number of positive zeros back into negative zeros > > > for (int i = zeroIndex, m = zeroIndex + numNegativeZeros; i < m; i++) { > > > @@ -1718,7 +1714,7 @@ > > > } > > > > > > /** > > > - * Returns the index of some zero element in the specified range via > > > + * Returns the index of the first zero element in the specified range via > > > * binary search. The range is assumed to be sorted, and must contain > > > * at least one zero. > > > * > > > @@ -1726,18 +1722,17 @@ > > > * @param low the index of the first element, inclusive, to be searched > > > * @param high the index of the last element, inclusive, to be searched > > > */ > > > - private static int findAnyZero(float[] a, int low, int high) { > > > - while (true) { > > > + private static int findFirstZero(float[] a, int low, int high) { > > > + while (low < high) { > > > int middle = (low + high) >>> 1; > > > float middleValue = a[middle]; > > > > > > if (middleValue < 0.0f) { > > > low = middle + 1; > > > - } else if (middleValue > 0.0f) { > > > - high = middle - 1; > > > - } else { // middleValue == 0.0f > > > - return middle; > > > + } else { // middleValue >= 0.0f > > > + high = middle; > > > } > > > + return low; > > > } > > > } > > > > > > Counting negative values appeared more expensive than any other variants. > > > The last proposal seems to me as efficient as the current solution is in its worst case - when we have only one negative zero (in the half of array). > > > And it shows the best result if we have many zeros. > > > > > > Regards, > > > Dmytro Sheyko > > > > > > > From: iaroslavski at mail.ru > > > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > > Subject: Re[2]: New portion of improvements for Dual-Pivot Quicksort > > > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > > > > > > Josh, > > > > Dmytro, > > > > > > > > I have done more thoroughly testing "great - less > 5 * seventh" vs. "less < e1 && great > e5", > > > > and found that more symmetric code "less < e1 && great > e5" is little bit faster, ~0.5..0.7% > > > > on both VMs. Other code has not been changed. > > > > > > > > Please, take the latest version in attachment. > > > > > > > > Vladimir > > > > > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua Bloch : > > > > > > > > > Vladimir, > > > > > > > > > > Old: > > > > > > > > > >298 if (less < e1 && great > e5) { > > > > > > > > > > New: > > > > > > > > > >256 if (great - less > 5 * seventh) { > > > > > > > > >Regards, > > > > >Josh -------------- next part -------------- A non-text attachment was scrubbed... Name: DualPivotQuicksort.java Type: application/octet-stream Size: 100533 bytes Desc: not available URL: From martinrb at google.com Fri May 14 20:13:05 2010 From: martinrb at google.com (Martin Buchholz) Date: Fri, 14 May 2010 13:13:05 -0700 Subject: RFC links on java.util.zip's class API In-Reply-To: <4BEDA6F1.9060905@oracle.com> References: <4BED6CD3.9010504@oracle.com> <4BED99B7.6010600@oracle.com> <4BEDA6F1.9060905@oracle.com> Message-ID: On Fri, May 14, 2010 at 12:39, Xueming Shen wrote: > > webrev has been updated to update the isi.edu reference to ietf (and one > iana) for public APIs. > > The references in src/share/classes/com/sun are not touched, including 2 > apache drop-in xml code. > > Should be enough for today's exercise:-) Agreed and approved! From xueming.shen at oracle.com Fri May 14 20:32:44 2010 From: xueming.shen at oracle.com (xueming.shen at oracle.com) Date: Fri, 14 May 2010 20:32:44 +0000 Subject: hg: jdk7/tl/jdk: 6952701: Use http://www.ietf.org/rfc for rfc references in jdk public APIs Message-ID: <20100514203257.7709B44934@hg.openjdk.java.net> Changeset: ac74c3b96e49 Author: sherman Date: 2010-05-14 13:30 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/ac74c3b96e49 6952701: Use http://www.ietf.org/rfc for rfc references in jdk public APIs Summary: replace www.isi.edu/in-notes with www.ietf.org/rfc Reviewed-by: martin ! src/share/classes/java/util/zip/package.html ! src/share/classes/javax/naming/event/EventDirContext.java ! src/share/classes/javax/naming/ldap/Control.java ! src/share/classes/javax/naming/ldap/ControlFactory.java ! src/share/classes/javax/naming/ldap/ExtendedRequest.java ! src/share/classes/javax/naming/ldap/ExtendedResponse.java ! src/share/classes/javax/naming/ldap/UnsolicitedNotification.java ! src/share/classes/javax/naming/ldap/UnsolicitedNotificationListener.java ! src/share/classes/javax/print/DocFlavor.java From xueming.shen at oracle.com Fri May 14 20:48:51 2010 From: xueming.shen at oracle.com (xueming.shen at oracle.com) Date: Fri, 14 May 2010 20:48:51 +0000 Subject: hg: jdk7/tl/jdk: 4263582: RFE: GZIPInputStream throws IOException on non-gzipped data Message-ID: <20100514204904.2070A44937@hg.openjdk.java.net> Changeset: 2fb3d7dbaa32 Author: sherman Date: 2010-05-14 13:46 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/2fb3d7dbaa32 4263582: RFE: GZIPInputStream throws IOException on non-gzipped data Summary: throw ZipException instead of IOException Reviewed-by: martin ! src/share/classes/java/util/zip/GZIPInputStream.java From xueming.shen at oracle.com Fri May 14 23:18:47 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 14 May 2010 16:18:47 -0700 Subject: http://javaweb.sfbay.sun.com/~sherman/6332094/ Message-ID: <4BEDDA57.2030804@oracle.com> It appears the backport to 6u of the optimization we did in #6332094 breaks someone's code. Obviously the ZipInputStream works fine with >4G zipfile even without the ZIP64 format support as long as the individual zip entries inside is smaller than the 4G limit, so the sequential reading in jar's old implementation just works "fine" with the >4G zip. But the optimization we put in to use ZipFile instead causes the regression because it needs the access to the 64bit central directory table if the zip is > 4G. While it is arguable if a > 4G zipfile without the ZIP64 extension table is a "correctly" formatted zip file or in fact that jar can never create a > 4G zip file before we added the ZIP64 support, regression is a regression:-( I believe you also backport the same thing into 6open. -Sherman From martinrb at google.com Sat May 15 02:02:56 2010 From: martinrb at google.com (Martin Buchholz) Date: Fri, 14 May 2010 19:02:56 -0700 Subject: http://javaweb.sfbay.sun.com/~sherman/6332094/ In-Reply-To: <4BEDDA57.2030804@oracle.com> References: <4BEDDA57.2030804@oracle.com> Message-ID: Well, the obvious thing to do is to use ZipFile, and if something goes wrong, back off and try the old implementation with ZipInputStream in addition. If the JDK has ZIP64 support, what goes wrong? Martin On Fri, May 14, 2010 at 16:18, Xueming Shen wrote: > > It appears the backport to 6u of the optimization we did in #6332094 breaks > someone's code. > > Obviously the ZipInputStream works fine with >4G zipfile even without the > ZIP64 format support > as long as the individual zip entries inside is smaller than the 4G limit, > so the sequential reading in jar's > old implementation just works "fine" with the >4G zip. But the optimization > we put in to use ZipFile > instead causes the regression because it needs the access to the 64bit > central directory table if the > zip is > 4G. While it is arguable if a > 4G zipfile without the ZIP64 > extension table is a "correctly" > formatted zip file or in fact that jar can never create a > 4G zip file > before we added the ZIP64 > support, regression is a regression:-( > > I believe you also backport the same thing into 6open. > > -Sherman > From xueming.shen at oracle.com Sat May 15 02:24:05 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 14 May 2010 19:24:05 -0700 Subject: http://javaweb.sfbay.sun.com/~sherman/6332094/ In-Reply-To: References: <4BEDDA57.2030804@oracle.com> Message-ID: <4BEE05C5.2070003@oracle.com> Martin Buchholz wrote: > Well, the obvious thing to do is to use ZipFile, > and if something goes wrong, > back off and try the old implementation with > ZipInputStream in addition. > > I will add a check like if (fname != null && new File(fname).length() < 0x100000000L) go ZipFile; else go ZipInputStream > If the JDK has ZIP64 support, > what goes wrong? > > Nothing goes wrong with ZIP64, but we don't have that in 6u (yet) -Sherman > Martin > > On Fri, May 14, 2010 at 16:18, Xueming Shen wrote: > >> It appears the backport to 6u of the optimization we did in #6332094 breaks >> someone's code. >> >> Obviously the ZipInputStream works fine with >4G zipfile even without the >> ZIP64 format support >> as long as the individual zip entries inside is smaller than the 4G limit, >> so the sequential reading in jar's >> old implementation just works "fine" with the >4G zip. But the optimization >> we put in to use ZipFile >> instead causes the regression because it needs the access to the 64bit >> central directory table if the >> zip is > 4G. While it is arguable if a > 4G zipfile without the ZIP64 >> extension table is a "correctly" >> formatted zip file or in fact that jar can never create a > 4G zip file >> before we added the ZIP64 >> support, regression is a regression:-( >> >> I believe you also backport the same thing into 6open. >> >> -Sherman >> >> From martinrb at google.com Sat May 15 05:59:26 2010 From: martinrb at google.com (Martin Buchholz) Date: Fri, 14 May 2010 22:59:26 -0700 Subject: http://javaweb.sfbay.sun.com/~sherman/6332094/ In-Reply-To: <4BEE05C5.2070003@oracle.com> References: <4BEDDA57.2030804@oracle.com> <4BEE05C5.2070003@oracle.com> Message-ID: On Fri, May 14, 2010 at 19:24, Xueming Shen wrote: > Martin Buchholz wrote: >> >> Well, the obvious thing to do is to use ZipFile, >> and if something goes wrong, >> back off and try the old implementation with >> ZipInputStream in addition. >> >> > > I will add a check like > > if (fname != null && new File(fname).length() < 0x100000000L) > ? go ZipFile; > else > ? go ZipInputStream Sounds good. hmmm.... If the input zip file is actually a ZIP64 file for some other reason (for example to get >64k entries), then ZipInputStream will still succeed, while ZipFile will probably fail, in which case the fallback algorithm might be more robust. But I am happy with any action on your part, including doing nothing. > >> If the JDK has ZIP64 support, >> what goes wrong? >> >> > > Nothing goes wrong with ZIP64, but we don't have that in 6u (yet) Oh, right. And a backport of ZIP64 support probably isn't worth the risk and effort. Martin > -Sherman > > >> Martin >> >> On Fri, May 14, 2010 at 16:18, Xueming Shen >> wrote: >> >>> >>> It appears the backport to 6u of the optimization we did in #6332094 >>> breaks >>> someone's code. >>> >>> Obviously the ZipInputStream works fine with >4G zipfile even without the >>> ZIP64 format support >>> as long as the individual zip entries inside is smaller than the 4G >>> limit, >>> so the sequential reading in jar's >>> old implementation just works "fine" with the >4G zip. But the >>> optimization >>> we put in to use ZipFile >>> instead causes the regression because it needs the access to the 64bit >>> central directory table if the >>> zip is > 4G. While it is arguable if a > 4G zipfile without the ZIP64 >>> extension table is a "correctly" >>> formatted zip file or in fact that jar can never create a > 4G zip file >>> before we added the ZIP64 >>> support, regression is a regression:-( >>> >>> I believe you also backport the same thing into 6open. >>> >>> -Sherman >>> >>> > > From xueming.shen at oracle.com Sat May 15 06:53:39 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 14 May 2010 23:53:39 -0700 Subject: http://javaweb.sfbay.sun.com/~sherman/6332094/ In-Reply-To: References: <4BEDDA57.2030804@oracle.com> <4BEE05C5.2070003@oracle.com> Message-ID: <4BEE44F3.3030806@oracle.com> OK, Thanks! btw, did you ask this before? http://cr.openjdk.java.net/~sherman/6581715/webrev/ -Sherman Martin Buchholz wrote: > On Fri, May 14, 2010 at 19:24, Xueming Shen wrote: > >> Martin Buchholz wrote: >> >>> Well, the obvious thing to do is to use ZipFile, >>> and if something goes wrong, >>> back off and try the old implementation with >>> ZipInputStream in addition. >>> >>> >>> >> I will add a check like >> >> if (fname != null && new File(fname).length() < 0x100000000L) >> go ZipFile; >> else >> go ZipInputStream >> > > Sounds good. > > hmmm.... > If the input zip file is actually a ZIP64 file for some other reason > (for example to get >64k entries), then ZipInputStream > will still succeed, while ZipFile will probably fail, > in which case the fallback algorithm might be more robust. > > But I am happy with any action on your part, > including doing nothing. > > >>> If the JDK has ZIP64 support, >>> what goes wrong? >>> >>> >>> >> Nothing goes wrong with ZIP64, but we don't have that in 6u (yet) >> > > Oh, right. And a backport of ZIP64 support probably isn't > worth the risk and effort. > > Martin > > >> -Sherman >> >> >> >>> Martin >>> >>> On Fri, May 14, 2010 at 16:18, Xueming Shen >>> wrote: >>> >>> >>>> It appears the backport to 6u of the optimization we did in #6332094 >>>> breaks >>>> someone's code. >>>> >>>> Obviously the ZipInputStream works fine with >4G zipfile even without the >>>> ZIP64 format support >>>> as long as the individual zip entries inside is smaller than the 4G >>>> limit, >>>> so the sequential reading in jar's >>>> old implementation just works "fine" with the >4G zip. But the >>>> optimization >>>> we put in to use ZipFile >>>> instead causes the regression because it needs the access to the 64bit >>>> central directory table if the >>>> zip is > 4G. While it is arguable if a > 4G zipfile without the ZIP64 >>>> extension table is a "correctly" >>>> formatted zip file or in fact that jar can never create a > 4G zip file >>>> before we added the ZIP64 >>>> support, regression is a regression:-( >>>> >>>> I believe you also backport the same thing into 6open. >>>> >>>> -Sherman >>>> >>>> >>>> >> From martinrb at google.com Sun May 16 06:57:25 2010 From: martinrb at google.com (Martin Buchholz) Date: Sat, 15 May 2010 23:57:25 -0700 Subject: http://javaweb.sfbay.sun.com/~sherman/6332094/ In-Reply-To: <4BEE44F3.3030806@oracle.com> References: <4BEDDA57.2030804@oracle.com> <4BEE05C5.2070003@oracle.com> <4BEE44F3.3030806@oracle.com> Message-ID: On Fri, May 14, 2010 at 23:53, Xueming Shen wrote: > OK, Thanks! > > btw, did you ask this before? > > http://cr.openjdk.java.net/~sherman/6581715/webrev/ I think I did. All JDK classes returning an Enumeration should be retrofitted to implement Iterable. Looks good. --- There are a few more places where you can remove ZipFile.this. 507 ",\n jzfile = " + ZipFile.this.jzfile + 508 ",\n total = " + ZipFile.this.total + 509 ",\n name = " + ZipFile.this.name + Martin > -Sherman > > Martin Buchholz wrote: >> >> On Fri, May 14, 2010 at 19:24, Xueming Shen >> wrote: >> >>> >>> Martin Buchholz wrote: >>> >>>> >>>> Well, the obvious thing to do is to use ZipFile, >>>> and if something goes wrong, >>>> back off and try the old implementation with >>>> ZipInputStream in addition. >>>> >>>> >>>> >>> >>> I will add a check like >>> >>> if (fname != null && new File(fname).length() < 0x100000000L) >>> ?go ZipFile; >>> else >>> ?go ZipInputStream >>> >> >> Sounds good. >> >> hmmm.... >> If the input zip file is actually a ZIP64 file for some other reason >> (for example to get >64k entries), then ZipInputStream >> will still succeed, while ZipFile will probably fail, >> in which case the fallback algorithm might be more robust. >> >> But I am happy with any action on your part, >> including doing nothing. >> >> >>>> >>>> If the JDK has ZIP64 support, >>>> what goes wrong? >>>> >>>> >>>> >>> >>> Nothing goes wrong with ZIP64, but we don't have that in 6u (yet) >>> >> >> Oh, right. ?And a backport of ZIP64 support probably isn't >> worth the risk and effort. >> >> Martin >> >> >>> >>> -Sherman >>> >>> >>> >>>> >>>> Martin >>>> >>>> On Fri, May 14, 2010 at 16:18, Xueming Shen >>>> wrote: >>>> >>>> >>>>> >>>>> It appears the backport to 6u of the optimization we did in #6332094 >>>>> breaks >>>>> someone's code. >>>>> >>>>> Obviously the ZipInputStream works fine with >4G zipfile even without >>>>> the >>>>> ZIP64 format support >>>>> as long as the individual zip entries inside is smaller than the 4G >>>>> limit, >>>>> so the sequential reading in jar's >>>>> old implementation just works "fine" with the >4G zip. But the >>>>> optimization >>>>> we put in to use ZipFile >>>>> instead causes the regression because it needs the access to the 64bit >>>>> central directory table if the >>>>> zip is > 4G. While it is arguable if a > 4G zipfile without the ZIP64 >>>>> extension table is a "correctly" >>>>> formatted zip file or in fact that jar can never create a > 4G zip file >>>>> before we added the ZIP64 >>>>> support, regression is a regression:-( >>>>> >>>>> I believe you also backport the same thing into 6open. >>>>> >>>>> -Sherman >>>>> >>>>> >>>>> >>> >>> > > From xueming.shen at oracle.com Sun May 16 07:30:08 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Sun, 16 May 2010 00:30:08 -0700 Subject: http://javaweb.sfbay.sun.com/~sherman/6332094/ In-Reply-To: References: <4BEDDA57.2030804@oracle.com> <4BEE05C5.2070003@oracle.com> <4BEE44F3.3030806@oracle.com> Message-ID: <4BEF9F00.5050802@oracle.com> Thanks for the review. webrev has been updated accordingly. Do CCC next week. -Sherman Martin Buchholz wrote: > On Fri, May 14, 2010 at 23:53, Xueming Shen wrote: > >> OK, Thanks! >> >> btw, did you ask this before? >> >> http://cr.openjdk.java.net/~sherman/6581715/webrev/ >> > > I think I did. All JDK classes returning an Enumeration > should be retrofitted to implement Iterable. > > Looks good. > > --- > > There are a few more places where you can remove > ZipFile.this. > > 507 ",\n jzfile = " + ZipFile.this.jzfile + > 508 ",\n total = " + ZipFile.this.total + > 509 ",\n name = " + ZipFile.this.name + > > > Martin > > >> -Sherman >> >> Martin Buchholz wrote: >> >>> On Fri, May 14, 2010 at 19:24, Xueming Shen >>> wrote: >>> >>> >>>> Martin Buchholz wrote: >>>> >>>> >>>>> Well, the obvious thing to do is to use ZipFile, >>>>> and if something goes wrong, >>>>> back off and try the old implementation with >>>>> ZipInputStream in addition. >>>>> >>>>> >>>>> >>>>> >>>> I will add a check like >>>> >>>> if (fname != null && new File(fname).length() < 0x100000000L) >>>> go ZipFile; >>>> else >>>> go ZipInputStream >>>> >>>> >>> Sounds good. >>> >>> hmmm.... >>> If the input zip file is actually a ZIP64 file for some other reason >>> (for example to get >64k entries), then ZipInputStream >>> will still succeed, while ZipFile will probably fail, >>> in which case the fallback algorithm might be more robust. >>> >>> But I am happy with any action on your part, >>> including doing nothing. >>> >>> >>> >>>>> If the JDK has ZIP64 support, >>>>> what goes wrong? >>>>> >>>>> >>>>> >>>>> >>>> Nothing goes wrong with ZIP64, but we don't have that in 6u (yet) >>>> >>>> >>> Oh, right. And a backport of ZIP64 support probably isn't >>> worth the risk and effort. >>> >>> Martin >>> >>> >>> >>>> -Sherman >>>> >>>> >>>> >>>> >>>>> Martin >>>>> >>>>> On Fri, May 14, 2010 at 16:18, Xueming Shen >>>>> wrote: >>>>> >>>>> >>>>> >>>>>> It appears the backport to 6u of the optimization we did in #6332094 >>>>>> breaks >>>>>> someone's code. >>>>>> >>>>>> Obviously the ZipInputStream works fine with >4G zipfile even without >>>>>> the >>>>>> ZIP64 format support >>>>>> as long as the individual zip entries inside is smaller than the 4G >>>>>> limit, >>>>>> so the sequential reading in jar's >>>>>> old implementation just works "fine" with the >4G zip. But the >>>>>> optimization >>>>>> we put in to use ZipFile >>>>>> instead causes the regression because it needs the access to the 64bit >>>>>> central directory table if the >>>>>> zip is > 4G. While it is arguable if a > 4G zipfile without the ZIP64 >>>>>> extension table is a "correctly" >>>>>> formatted zip file or in fact that jar can never create a > 4G zip file >>>>>> before we added the ZIP64 >>>>>> support, regression is a regression:-( >>>>>> >>>>>> I believe you also backport the same thing into 6open. >>>>>> >>>>>> -Sherman >>>>>> >>>>>> >>>>>> >>>>>> >>>> >> From xueming.shen at oracle.com Mon May 17 04:28:53 2010 From: xueming.shen at oracle.com (xueming.shen at oracle.com) Date: Mon, 17 May 2010 04:28:53 +0000 Subject: hg: jdk7/tl/jdk: 4465490: Suspicious about double-check locking idiom being used in the code Message-ID: <20100517042916.52EE944D8E@hg.openjdk.java.net> Changeset: 91bcd8fc04f2 Author: sherman Date: 2010-05-16 21:22 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/91bcd8fc04f2 4465490: Suspicious about double-check locking idiom being used in the code Summary: to use volatile for the double-checked object Reviewed-by: weijun ! src/share/classes/java/util/jar/JarVerifier.java From dmytro_sheyko at hotmail.com Mon May 17 13:19:22 2010 From: dmytro_sheyko at hotmail.com (Dmytro Sheyko) Date: Mon, 17 May 2010 20:19:22 +0700 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: , Message-ID: Hello, More ideas. 1. We can use Double.doubleToRawLongBits instead of Double.doubleToLongBits and Float.floatToRawIntBits instead of Float.floatToIntBits. No need to handle NaN's because they all are placed to the end of array. 2. Note that Double.doubleToRawLongBits(+0.0) == 0L and Double.doubleToRawLongBits(-0.0) == Long.MIN_VALUE and Float.floatToRawIntBits(+0.0) == 0 and Float.floatToRawIntBits(-0.0) == Integer.MIN_VALUE. Comparing with is zero usually more efficient (or at least not worse) than with other values. Thus such pattern if (ak == 0.0f && NEGATIVE_ZERO == Float.floatToIntBits(ak)) can be replaced with if (ak == 0.0f && Float.floatToIntBits(ak) < 0) 3. It would be more efficient to count negative zeros after sorting. General sorting algorithm puts both negative and positive zeros together (but maybe not in right order). Therefore we have to process less elements because usually we have less zeros than other numbers. Thanks, Dmytro Sheyko > From: iaroslavski at mail.ru > To: dmytro_sheyko at hotmail.com; jjb at google.com > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > Subject: Re[6]: New portion of improvements for Dual-Pivot Quicksort > Date: Fri, 14 May 2010 23:54:06 +0400 > > Hello, > > I've updated the class, please, review the changes. > > Vladimir > > Fri, 14 May 2010 01:48:11 +0700 ?????? ?? Dmytro Sheyko : > > > Yes. I prefer F (Find First zero using binary search) over C (Count negatives) and S (Smart Scan for zero). > > > > > From: iaroslavski at mail.ru > > > To: dmytro_sheyko at hotmail.com > > > CC: jjb at google.com; core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > Subject: Re[4]: New portion of improvements for Dual-Pivot Quicksort > > > Date: Thu, 13 May 2010 21:34:54 +0400 > > > > > > Dmytro, > > > > > > I've tested your suggested variants, and found that case "C" > > > (very interesting approach to find first position of zero > > > by counting negative elements) works slower than original > > > or two other cases. > > > > > > Implementations "F" and "S" are very close to each other > > > and little bit faster than original. I prefer case "F": > > > it is shorter and more clear. Do you agree? > > > > > > I'll prepare updated DualPivotQuicksort file and send it > > > tomorrow. > > > > > > Thank you, > > > Vladimir > > > > > > Wed, 12 May 2010 17:04:52 +0700 ?????? ?? Dmytro Sheyko : > > > > > > > Vladimir, > > > > > > > > Your changes are good for me. > > > > > > > > Additionally I have some comments/proposals regarding dealing with negative zeros. > > > > > > > > 1. Scanning for the first zero we can avoid range check (i >= left) if we have at least one negative value. > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 2010 > > > > @@ -1705,10 +1705,15 @@ > > > > } > > > > > > > > // Find first zero element > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > + int zeroIndex = 0; > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > > > - zeroIndex = i; > > > > + if (a[left] < 0.0f) { > > > > + zeroIndex = findAnyZero(a, left, n); > > > > + > > > > + // there is at least one negative value, so range check is not needed > > > > + for (int i = zeroIndex - 1; /*i >= left &&*/ a[i] == 0.0f; i--) { > > > > + zeroIndex = i; > > > > + } > > > > } > > > > > > > > // Turn the right number of positive zeros back into negative zeros > > > > > > > > 2. We can find the position of the first zero by counting negative values during preprocessing phase. > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 2010 > > > > @@ -1678,7 +1678,7 @@ > > > > * Phase 1: Count negative zeros and move NaNs to end of array. > > > > */ > > > > final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f); > > > > - int numNegativeZeros = 0; > > > > + int numNegativeZeros = 0, numNegativeValues = 0; > > > > int n = right; > > > > > > > > for (int k = left; k <= n; k++) { > > > > @@ -1689,6 +1689,8 @@ > > > > } else if (ak != ak) { // i.e., ak is NaN > > > > a[k--] = a[n]; > > > > a[n--] = Float.NaN; > > > > + } else if (ak < 0.0f) { > > > > + numNegativeValues++; > > > > } > > > > } > > > > > > > > @@ -1705,7 +1707,7 @@ > > > > } > > > > > > > > // Find first zero element > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > + int zeroIndex = numNegativeValues; > > > > > > > > for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > > > zeroIndex = i; > > > > > > > > 3. We can use binary search to find the first zero and thus avoid linear scan. > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 2010 > > > > @@ -1705,11 +1705,7 @@ > > > > } > > > > > > > > // Find first zero element > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > - > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > > > - zeroIndex = i; > > > > - } > > > > + int zeroIndex = findFirstZero(a, left, n); > > > > > > > > // Turn the right number of positive zeros back into negative zeros > > > > for (int i = zeroIndex, m = zeroIndex + numNegativeZeros; i < m; i++) { > > > > @@ -1718,7 +1714,7 @@ > > > > } > > > > > > > > /** > > > > - * Returns the index of some zero element in the specified range via > > > > + * Returns the index of the first zero element in the specified range via > > > > * binary search. The range is assumed to be sorted, and must contain > > > > * at least one zero. > > > > * > > > > @@ -1726,18 +1722,17 @@ > > > > * @param low the index of the first element, inclusive, to be searched > > > > * @param high the index of the last element, inclusive, to be searched > > > > */ > > > > - private static int findAnyZero(float[] a, int low, int high) { > > > > - while (true) { > > > > + private static int findFirstZero(float[] a, int low, int high) { > > > > + while (low < high) { > > > > int middle = (low + high) >>> 1; > > > > float middleValue = a[middle]; > > > > > > > > if (middleValue < 0.0f) { > > > > low = middle + 1; > > > > - } else if (middleValue > 0.0f) { > > > > - high = middle - 1; > > > > - } else { // middleValue == 0.0f > > > > - return middle; > > > > + } else { // middleValue >= 0.0f > > > > + high = middle; > > > > } > > > > + return low; > > > > } > > > > } > > > > > > > > Counting negative values appeared more expensive than any other variants. > > > > The last proposal seems to me as efficient as the current solution is in its worst case - when we have only one negative zero (in the half of array). > > > > And it shows the best result if we have many zeros. > > > > > > > > Regards, > > > > Dmytro Sheyko > > > > > > > > > From: iaroslavski at mail.ru > > > > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > > > Subject: Re[2]: New portion of improvements for Dual-Pivot Quicksort > > > > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > > > > > > > > Josh, > > > > > Dmytro, > > > > > > > > > > I have done more thoroughly testing "great - less > 5 * seventh" vs. "less < e1 && great > e5", > > > > > and found that more symmetric code "less < e1 && great > e5" is little bit faster, ~0.5..0.7% > > > > > on both VMs. Other code has not been changed. > > > > > > > > > > Please, take the latest version in attachment. > > > > > > > > > > Vladimir > > > > > > > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua Bloch : > > > > > > > > > > > Vladimir, > > > > > > > > > > > > Old: > > > > > > > > > > > >298 if (less < e1 && great > e5) { > > > > > > > > > > > > New: > > > > > > > > > > > >256 if (great - less > 5 * seventh) { > > > > > > > > > > >Regards, > > > > > >Josh _________________________________________________________________ Hotmail: Free, trusted and rich email service. https://signup.live.com/signup.aspx?id=60969 -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: DualPivotQuicksort.java.diff Type: application/octet-stream Size: 9869 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: DualPivotQuicksort.java Type: text/x-java Size: 105870 bytes Desc: not available URL: From iaroslavski at mail.ru Mon May 17 13:30:37 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Mon, 17 May 2010 17:30:37 +0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: Message-ID: <4BF144FD.9040801@mail.ru> Hello, Thank you for review, I'll check and run tests again with you changes. Thank you, Vladimir Dmytro Sheyko wrote: > Hello, > > More ideas. > > 1. We can use > Double.doubleToRawLongBits instead of Double.doubleToLongBits and > Float.floatToRawIntBits instead of Float.floatToIntBits. > No need to handle NaN's because they all are placed to the end of array. > > 2. Note that > Double.doubleToRawLongBits(+0.0) == 0L and > Double.doubleToRawLongBits(-0.0) == Long.MIN_VALUE and > Float.floatToRawIntBits(+0.0) == 0 and > Float.floatToRawIntBits(-0.0) == Integer.MIN_VALUE. > > Comparing with is zero usually more efficient (or at least not worse) > than with other values. Thus such pattern > > if (ak == 0.0f && NEGATIVE_ZERO == Float.floatToIntBits(ak)) > > can be replaced with > > if (ak == 0.0f && Float.floatToIntBits(ak) < 0) > > 3. It would be more efficient to count negative zeros after sorting. > General sorting algorithm puts both negative and positive zeros together > (but maybe not in right order). > Therefore we have to process less elements because usually we have less > zeros than other numbers. > > Thanks, > Dmytro Sheyko > > > From: iaroslavski at mail.ru > > To: dmytro_sheyko at hotmail.com; jjb at google.com > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > Subject: Re[6]: New portion of improvements for Dual-Pivot Quicksort > > Date: Fri, 14 May 2010 23:54:06 +0400 > > > > Hello, > > > > I've updated the class, please, review the changes. > > > > Vladimir > > > > Fri, 14 May 2010 01:48:11 +0700 ?????? ?? Dmytro Sheyko > : > > > > > Yes. I prefer F (Find First zero using binary search) over C (Count > negatives) and S (Smart Scan for zero). > > > > > > > From: iaroslavski at mail.ru > > > > To: dmytro_sheyko at hotmail.com > > > > CC: jjb at google.com; core-libs-dev at openjdk.java.net; > iaroslavski at mail.ru > > > > Subject: Re[4]: New portion of improvements for Dual-Pivot Quicksort > > > > Date: Thu, 13 May 2010 21:34:54 +0400 > > > > > > > > Dmytro, > > > > > > > > I've tested your suggested variants, and found that case "C" > > > > (very interesting approach to find first position of zero > > > > by counting negative elements) works slower than original > > > > or two other cases. > > > > > > > > Implementations "F" and "S" are very close to each other > > > > and little bit faster than original. I prefer case "F": > > > > it is shorter and more clear. Do you agree? > > > > > > > > I'll prepare updated DualPivotQuicksort file and send it > > > > tomorrow. > > > > > > > > Thank you, > > > > Vladimir > > > > > > > > Wed, 12 May 2010 17:04:52 +0700 ?????? ?? Dmytro Sheyko > : > > > > > > > > > Vladimir, > > > > > > > > > > Your changes are good for me. > > > > > > > > > > Additionally I have some comments/proposals regarding dealing > with negative zeros. > > > > > > > > > > 1. Scanning for the first zero we can avoid range check (i >= > left) if we have at least one negative value. > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 2010 > > > > > @@ -1705,10 +1705,15 @@ > > > > > } > > > > > > > > > > // Find first zero element > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > + int zeroIndex = 0; > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > > > > - zeroIndex = i; > > > > > + if (a[left] < 0.0f) { > > > > > + zeroIndex = findAnyZero(a, left, n); > > > > > + > > > > > + // there is at least one negative value, so range check is > not needed > > > > > + for (int i = zeroIndex - 1; /*i >= left &&*/ a[i] == 0.0f; i--) { > > > > > + zeroIndex = i; > > > > > + } > > > > > } > > > > > > > > > > // Turn the right number of positive zeros back into negative zeros > > > > > > > > > > 2. We can find the position of the first zero by counting > negative values during preprocessing phase. > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 2010 > > > > > @@ -1678,7 +1678,7 @@ > > > > > * Phase 1: Count negative zeros and move NaNs to end of array. > > > > > */ > > > > > final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f); > > > > > - int numNegativeZeros = 0; > > > > > + int numNegativeZeros = 0, numNegativeValues = 0; > > > > > int n = right; > > > > > > > > > > for (int k = left; k <= n; k++) { > > > > > @@ -1689,6 +1689,8 @@ > > > > > } else if (ak != ak) { // i.e., ak is NaN > > > > > a[k--] = a[n]; > > > > > a[n--] = Float.NaN; > > > > > + } else if (ak < 0.0f) { > > > > > + numNegativeValues++; > > > > > } > > > > > } > > > > > > > > > > @@ -1705,7 +1707,7 @@ > > > > > } > > > > > > > > > > // Find first zero element > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > + int zeroIndex = numNegativeValues; > > > > > > > > > > for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > > > > zeroIndex = i; > > > > > > > > > > 3. We can use binary search to find the first zero and thus > avoid linear scan. > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 2010 > > > > > @@ -1705,11 +1705,7 @@ > > > > > } > > > > > > > > > > // Find first zero element > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > - > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > > > > - zeroIndex = i; > > > > > - } > > > > > + int zeroIndex = findFirstZero(a, left, n); > > > > > > > > > > // Turn the right number of positive zeros back into negative zeros > > > > > for (int i = zeroIndex, m = zeroIndex + numNegativeZeros; i < > m; i++) { > > > > > @@ -1718,7 +1714,7 @@ > > > > > } > > > > > > > > > > /** > > > > > - * Returns the index of some zero element in the specified > range via > > > > > + * Returns the index of the first zero element in the > specified range via > > > > > * binary search. The range is assumed to be sorted, and must > contain > > > > > * at least one zero. > > > > > * > > > > > @@ -1726,18 +1722,17 @@ > > > > > * @param low the index of the first element, inclusive, to be > searched > > > > > * @param high the index of the last element, inclusive, to be > searched > > > > > */ > > > > > - private static int findAnyZero(float[] a, int low, int high) { > > > > > - while (true) { > > > > > + private static int findFirstZero(float[] a, int low, int high) { > > > > > + while (low < high) { > > > > > int middle = (low + high) >>> 1; > > > > > float middleValue = a[middle]; > > > > > > > > > > if (middleValue < 0.0f) { > > > > > low = middle + 1; > > > > > - } else if (middleValue > 0.0f) { > > > > > - high = middle - 1; > > > > > - } else { // middleValue == 0.0f > > > > > - return middle; > > > > > + } else { // middleValue >= 0.0f > > > > > + high = middle; > > > > > } > > > > > + return low; > > > > > } > > > > > } > > > > > > > > > > Counting negative values appeared more expensive than any other > variants. > > > > > The last proposal seems to me as efficient as the current > solution is in its worst case - when we have only one negative zero (in > the half of array). > > > > > And it shows the best result if we have many zeros. > > > > > > > > > > Regards, > > > > > Dmytro Sheyko > > > > > > > > > > > From: iaroslavski at mail.ru > > > > > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > > > > Subject: Re[2]: New portion of improvements for Dual-Pivot > Quicksort > > > > > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > > > > > > > > > > Josh, > > > > > > Dmytro, > > > > > > > > > > > > I have done more thoroughly testing "great - less > 5 * > seventh" vs. "less < e1 && great > e5", > > > > > > and found that more symmetric code "less < e1 && great > e5" > is little bit faster, ~0.5..0.7% > > > > > > on both VMs. Other code has not been changed. > > > > > > > > > > > > Please, take the latest version in attachment. > > > > > > > > > > > > Vladimir > > > > > > > > > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua Bloch > : > > > > > > > > > > > > > Vladimir, > > > > > > > > > > > > > > Old: > > > > > > > > > > > > > >298 if (less < e1 && great > e5) { > > > > > > > > > > > > > > New: > > > > > > > > > > > > > >256 if (great - less > 5 * seventh) { > > > > > > > > > > > > >Regards, > > > > > > >Josh From dmytro_sheyko at hotmail.com Mon May 17 15:24:11 2010 From: dmytro_sheyko at hotmail.com (Dmytro Sheyko) Date: Mon, 17 May 2010 22:24:11 +0700 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: <4BF144FD.9040801@mail.ru> References: , , , <4BF144FD.9040801@mail.ru> Message-ID: Hi, Regarding counting sort. We can check whether we should switch to counting sort only once in the beginning. > Date: Mon, 17 May 2010 17:30:37 +0400 > From: iaroslavski at mail.ru > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > To: dmytro_sheyko at hotmail.com > CC: core-libs-dev at openjdk.java.net > > Hello, > > Thank you for review, I'll check and run tests again with you changes. > > Thank you, > Vladimir > > Dmytro Sheyko wrote: > > Hello, > > > > More ideas. > > > > 1. We can use > > Double.doubleToRawLongBits instead of Double.doubleToLongBits and > > Float.floatToRawIntBits instead of Float.floatToIntBits. > > No need to handle NaN's because they all are placed to the end of array. > > > > 2. Note that > > Double.doubleToRawLongBits(+0.0) == 0L and > > Double.doubleToRawLongBits(-0.0) == Long.MIN_VALUE and > > Float.floatToRawIntBits(+0.0) == 0 and > > Float.floatToRawIntBits(-0.0) == Integer.MIN_VALUE. > > > > Comparing with is zero usually more efficient (or at least not worse) > > than with other values. Thus such pattern > > > > if (ak == 0.0f && NEGATIVE_ZERO == Float.floatToIntBits(ak)) > > > > can be replaced with > > > > if (ak == 0.0f && Float.floatToIntBits(ak) < 0) > > > > 3. It would be more efficient to count negative zeros after sorting. > > General sorting algorithm puts both negative and positive zeros together > > (but maybe not in right order). > > Therefore we have to process less elements because usually we have less > > zeros than other numbers. > > > > Thanks, > > Dmytro Sheyko > > > > > From: iaroslavski at mail.ru > > > To: dmytro_sheyko at hotmail.com; jjb at google.com > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > Subject: Re[6]: New portion of improvements for Dual-Pivot Quicksort > > > Date: Fri, 14 May 2010 23:54:06 +0400 > > > > > > Hello, > > > > > > I've updated the class, please, review the changes. > > > > > > Vladimir > > > > > > Fri, 14 May 2010 01:48:11 +0700 ?????? ?? Dmytro Sheyko > > : > > > > > > > Yes. I prefer F (Find First zero using binary search) over C (Count > > negatives) and S (Smart Scan for zero). > > > > > > > > > From: iaroslavski at mail.ru > > > > > To: dmytro_sheyko at hotmail.com > > > > > CC: jjb at google.com; core-libs-dev at openjdk.java.net; > > iaroslavski at mail.ru > > > > > Subject: Re[4]: New portion of improvements for Dual-Pivot Quicksort > > > > > Date: Thu, 13 May 2010 21:34:54 +0400 > > > > > > > > > > Dmytro, > > > > > > > > > > I've tested your suggested variants, and found that case "C" > > > > > (very interesting approach to find first position of zero > > > > > by counting negative elements) works slower than original > > > > > or two other cases. > > > > > > > > > > Implementations "F" and "S" are very close to each other > > > > > and little bit faster than original. I prefer case "F": > > > > > it is shorter and more clear. Do you agree? > > > > > > > > > > I'll prepare updated DualPivotQuicksort file and send it > > > > > tomorrow. > > > > > > > > > > Thank you, > > > > > Vladimir > > > > > > > > > > Wed, 12 May 2010 17:04:52 +0700 ?????? ?? Dmytro Sheyko > > : > > > > > > > > > > > Vladimir, > > > > > > > > > > > > Your changes are good for me. > > > > > > > > > > > > Additionally I have some comments/proposals regarding dealing > > with negative zeros. > > > > > > > > > > > > 1. Scanning for the first zero we can avoid range check (i >= > > left) if we have at least one negative value. > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 2010 > > > > > > @@ -1705,10 +1705,15 @@ > > > > > > } > > > > > > > > > > > > // Find first zero element > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > + int zeroIndex = 0; > > > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > > > > > - zeroIndex = i; > > > > > > + if (a[left] < 0.0f) { > > > > > > + zeroIndex = findAnyZero(a, left, n); > > > > > > + > > > > > > + // there is at least one negative value, so range check is > > not needed > > > > > > + for (int i = zeroIndex - 1; /*i >= left &&*/ a[i] == 0.0f; i--) { > > > > > > + zeroIndex = i; > > > > > > + } > > > > > > } > > > > > > > > > > > > // Turn the right number of positive zeros back into negative zeros > > > > > > > > > > > > 2. We can find the position of the first zero by counting > > negative values during preprocessing phase. > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 2010 > > > > > > @@ -1678,7 +1678,7 @@ > > > > > > * Phase 1: Count negative zeros and move NaNs to end of array. > > > > > > */ > > > > > > final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f); > > > > > > - int numNegativeZeros = 0; > > > > > > + int numNegativeZeros = 0, numNegativeValues = 0; > > > > > > int n = right; > > > > > > > > > > > > for (int k = left; k <= n; k++) { > > > > > > @@ -1689,6 +1689,8 @@ > > > > > > } else if (ak != ak) { // i.e., ak is NaN > > > > > > a[k--] = a[n]; > > > > > > a[n--] = Float.NaN; > > > > > > + } else if (ak < 0.0f) { > > > > > > + numNegativeValues++; > > > > > > } > > > > > > } > > > > > > > > > > > > @@ -1705,7 +1707,7 @@ > > > > > > } > > > > > > > > > > > > // Find first zero element > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > + int zeroIndex = numNegativeValues; > > > > > > > > > > > > for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > > > > > zeroIndex = i; > > > > > > > > > > > > 3. We can use binary search to find the first zero and thus > > avoid linear scan. > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 2010 > > > > > > @@ -1705,11 +1705,7 @@ > > > > > > } > > > > > > > > > > > > // Find first zero element > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > - > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > > > > > - zeroIndex = i; > > > > > > - } > > > > > > + int zeroIndex = findFirstZero(a, left, n); > > > > > > > > > > > > // Turn the right number of positive zeros back into negative zeros > > > > > > for (int i = zeroIndex, m = zeroIndex + numNegativeZeros; i < > > m; i++) { > > > > > > @@ -1718,7 +1714,7 @@ > > > > > > } > > > > > > > > > > > > /** > > > > > > - * Returns the index of some zero element in the specified > > range via > > > > > > + * Returns the index of the first zero element in the > > specified range via > > > > > > * binary search. The range is assumed to be sorted, and must > > contain > > > > > > * at least one zero. > > > > > > * > > > > > > @@ -1726,18 +1722,17 @@ > > > > > > * @param low the index of the first element, inclusive, to be > > searched > > > > > > * @param high the index of the last element, inclusive, to be > > searched > > > > > > */ > > > > > > - private static int findAnyZero(float[] a, int low, int high) { > > > > > > - while (true) { > > > > > > + private static int findFirstZero(float[] a, int low, int high) { > > > > > > + while (low < high) { > > > > > > int middle = (low + high) >>> 1; > > > > > > float middleValue = a[middle]; > > > > > > > > > > > > if (middleValue < 0.0f) { > > > > > > low = middle + 1; > > > > > > - } else if (middleValue > 0.0f) { > > > > > > - high = middle - 1; > > > > > > - } else { // middleValue == 0.0f > > > > > > - return middle; > > > > > > + } else { // middleValue >= 0.0f > > > > > > + high = middle; > > > > > > } > > > > > > + return low; > > > > > > } > > > > > > } > > > > > > > > > > > > Counting negative values appeared more expensive than any other > > variants. > > > > > > The last proposal seems to me as efficient as the current > > solution is in its worst case - when we have only one negative zero (in > > the half of array). > > > > > > And it shows the best result if we have many zeros. > > > > > > > > > > > > Regards, > > > > > > Dmytro Sheyko > > > > > > > > > > > > > From: iaroslavski at mail.ru > > > > > > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > > > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > > > > > Subject: Re[2]: New portion of improvements for Dual-Pivot > > Quicksort > > > > > > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > > > > > > > > > > > > Josh, > > > > > > > Dmytro, > > > > > > > > > > > > > > I have done more thoroughly testing "great - less > 5 * > > seventh" vs. "less < e1 && great > e5", > > > > > > > and found that more symmetric code "less < e1 && great > e5" > > is little bit faster, ~0.5..0.7% > > > > > > > on both VMs. Other code has not been changed. > > > > > > > > > > > > > > Please, take the latest version in attachment. > > > > > > > > > > > > > > Vladimir > > > > > > > > > > > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua Bloch > > : > > > > > > > > > > > > > > > Vladimir, > > > > > > > > > > > > > > > > Old: > > > > > > > > > > > > > > > >298 if (less < e1 && great > e5) { > > > > > > > > > > > > > > > > New: > > > > > > > > > > > > > > > >256 if (great - less > 5 * seventh) { > > > > > > > > > > > > > > >Regards, > > > > > > > >Josh _________________________________________________________________ Hotmail: Trusted email with powerful SPAM protection. https://signup.live.com/signup.aspx?id=60969 -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: DualPivotQuicksort.diff Type: application/octet-stream Size: 7032 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: DualPivotQuicksort.java Type: text/x-java Size: 101456 bytes Desc: not available URL: From xueming.shen at oracle.com Mon May 17 19:26:14 2010 From: xueming.shen at oracle.com (xueming.shen at oracle.com) Date: Mon, 17 May 2010 19:26:14 +0000 Subject: hg: jdk7/tl/jdk: 4813885: RFE: GZIPOutputStream should implement flush using Z_SYNC_FLUSH Message-ID: <20100517192646.A4FED44EAD@hg.openjdk.java.net> Changeset: 43f83a2cf5b5 Author: sherman Date: 2010-05-17 12:19 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/43f83a2cf5b5 4813885: RFE: GZIPOutputStream should implement flush using Z_SYNC_FLUSH Summary: Added new constructors to allow flush() work in Z_SYNC_FLUSH mode Reviewed-by: martin ! src/share/classes/java/util/zip/GZIPOutputStream.java ! test/java/util/zip/InflateIn_DeflateOut.java From xueming.shen at oracle.com Mon May 17 20:33:07 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Mon, 17 May 2010 13:33:07 -0700 Subject: Review request for #4853493 Message-ID: <4BF1A803.8010009@oracle.com> Martin, It appears we should make the defensive copy in this case, as we usually do in lib code. http://cr.openjdk.java.net/~sherman/4853493/webrev -Sherman From iaroslavski at mail.ru Mon May 17 21:11:19 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Tue, 18 May 2010 01:11:19 +0400 Subject: =?koi8-r?Q?Re[2]=3A_New_portion_of_improvements_for_Dual-Pivot_Quicksort?= In-Reply-To: References: Message-ID: Sounds good! Will consider too... Mon, 17 May 2010 22:24:11 +0700 ?????? ?? Dmytro Sheyko : > Hi, > > Regarding counting sort. We can check whether we should switch to counting sort only once in the beginning. > > > Date: Mon, 17 May 2010 17:30:37 +0400 > > From: iaroslavski at mail.ru > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > To: dmytro_sheyko at hotmail.com > > CC: core-libs-dev at openjdk.java.net > > > > Hello, > > > > Thank you for review, I'll check and run tests again with you changes. > > > > Thank you, > > Vladimir > > > > Dmytro Sheyko wrote: > > > Hello, > > > > > > More ideas. > > > > > > 1. We can use > > > Double.doubleToRawLongBits instead of Double.doubleToLongBits and > > > Float.floatToRawIntBits instead of Float.floatToIntBits. > > > No need to handle NaN's because they all are placed to the end of array. > > > > > > 2. Note that > > > Double.doubleToRawLongBits(+0.0) == 0L and > > > Double.doubleToRawLongBits(-0.0) == Long.MIN_VALUE and > > > Float.floatToRawIntBits(+0.0) == 0 and > > > Float.floatToRawIntBits(-0.0) == Integer.MIN_VALUE. > > > > > > Comparing with is zero usually more efficient (or at least not worse) > > > than with other values. Thus such pattern > > > > > > if (ak == 0.0f && NEGATIVE_ZERO == Float.floatToIntBits(ak)) > > > > > > can be replaced with > > > > > > if (ak == 0.0f && Float.floatToIntBits(ak) < 0) > > > > > > 3. It would be more efficient to count negative zeros after sorting. > > > General sorting algorithm puts both negative and positive zeros together > > > (but maybe not in right order). > > > Therefore we have to process less elements because usually we have less > > > zeros than other numbers. > > > > > > Thanks, > > > Dmytro Sheyko > > > > > > > From: iaroslavski at mail.ru > > > > To: dmytro_sheyko at hotmail.com; jjb at google.com > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > > Subject: Re[6]: New portion of improvements for Dual-Pivot Quicksort > > > > Date: Fri, 14 May 2010 23:54:06 +0400 > > > > > > > > Hello, > > > > > > > > I've updated the class, please, review the changes. > > > > > > > > Vladimir > > > > > > > > Fri, 14 May 2010 01:48:11 +0700 ?????? ?? Dmytro Sheyko > > > : > > > > > > > > > Yes. I prefer F (Find First zero using binary search) over C (Count > > > negatives) and S (Smart Scan for zero). > > > > > > > > > > > From: iaroslavski at mail.ru > > > > > > To: dmytro_sheyko at hotmail.com > > > > > > CC: jjb at google.com; core-libs-dev at openjdk.java.net; > > > iaroslavski at mail.ru > > > > > > Subject: Re[4]: New portion of improvements for Dual-Pivot Quicksort > > > > > > Date: Thu, 13 May 2010 21:34:54 +0400 > > > > > > > > > > > > Dmytro, > > > > > > > > > > > > I've tested your suggested variants, and found that case "C" > > > > > > (very interesting approach to find first position of zero > > > > > > by counting negative elements) works slower than original > > > > > > or two other cases. > > > > > > > > > > > > Implementations "F" and "S" are very close to each other > > > > > > and little bit faster than original. I prefer case "F": > > > > > > it is shorter and more clear. Do you agree? > > > > > > > > > > > > I'll prepare updated DualPivotQuicksort file and send it > > > > > > tomorrow. > > > > > > > > > > > > Thank you, > > > > > > Vladimir > > > > > > > > > > > > Wed, 12 May 2010 17:04:52 +0700 ?????? ?? Dmytro Sheyko > > > : > > > > > > > > > > > > > Vladimir, > > > > > > > > > > > > > > Your changes are good for me. > > > > > > > > > > > > > > Additionally I have some comments/proposals regarding dealing > > > with negative zeros. > > > > > > > > > > > > > > 1. Scanning for the first zero we can avoid range check (i >= > > > left) if we have at least one negative value. > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > > > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 2010 > > > > > > > @@ -1705,10 +1705,15 @@ > > > > > > > } > > > > > > > > > > > > > > // Find first zero element > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > > + int zeroIndex = 0; > > > > > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > > > > > > - zeroIndex = i; > > > > > > > + if (a[left] < 0.0f) { > > > > > > > + zeroIndex = findAnyZero(a, left, n); > > > > > > > + > > > > > > > + // there is at least one negative value, so range check is > > > not needed > > > > > > > + for (int i = zeroIndex - 1; /*i >= left &&*/ a[i] == 0.0f; i--) { > > > > > > > + zeroIndex = i; > > > > > > > + } > > > > > > > } > > > > > > > > > > > > > > // Turn the right number of positive zeros back into negative zeros > > > > > > > > > > > > > > 2. We can find the position of the first zero by counting > > > negative values during preprocessing phase. > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > > > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 2010 > > > > > > > @@ -1678,7 +1678,7 @@ > > > > > > > * Phase 1: Count negative zeros and move NaNs to end of array. > > > > > > > */ > > > > > > > final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f); > > > > > > > - int numNegativeZeros = 0; > > > > > > > + int numNegativeZeros = 0, numNegativeValues = 0; > > > > > > > int n = right; > > > > > > > > > > > > > > for (int k = left; k <= n; k++) { > > > > > > > @@ -1689,6 +1689,8 @@ > > > > > > > } else if (ak != ak) { // i.e., ak is NaN > > > > > > > a[k--] = a[n]; > > > > > > > a[n--] = Float.NaN; > > > > > > > + } else if (ak < 0.0f) { > > > > > > > + numNegativeValues++; > > > > > > > } > > > > > > > } > > > > > > > > > > > > > > @@ -1705,7 +1707,7 @@ > > > > > > > } > > > > > > > > > > > > > > // Find first zero element > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > > + int zeroIndex = numNegativeValues; > > > > > > > > > > > > > > for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > > > > > > zeroIndex = i; > > > > > > > > > > > > > > 3. We can use binary search to find the first zero and thus > > > avoid linear scan. > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > > > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 2010 > > > > > > > @@ -1705,11 +1705,7 @@ > > > > > > > } > > > > > > > > > > > > > > // Find first zero element > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > > - > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > > > > > > - zeroIndex = i; > > > > > > > - } > > > > > > > + int zeroIndex = findFirstZero(a, left, n); > > > > > > > > > > > > > > // Turn the right number of positive zeros back into negative zeros > > > > > > > for (int i = zeroIndex, m = zeroIndex + numNegativeZeros; i < > > > m; i++) { > > > > > > > @@ -1718,7 +1714,7 @@ > > > > > > > } > > > > > > > > > > > > > > /** > > > > > > > - * Returns the index of some zero element in the specified > > > range via > > > > > > > + * Returns the index of the first zero element in the > > > specified range via > > > > > > > * binary search. The range is assumed to be sorted, and must > > > contain > > > > > > > * at least one zero. > > > > > > > * > > > > > > > @@ -1726,18 +1722,17 @@ > > > > > > > * @param low the index of the first element, inclusive, to be > > > searched > > > > > > > * @param high the index of the last element, inclusive, to be > > > searched > > > > > > > */ > > > > > > > - private static int findAnyZero(float[] a, int low, int high) { > > > > > > > - while (true) { > > > > > > > + private static int findFirstZero(float[] a, int low, int high) { > > > > > > > + while (low < high) { > > > > > > > int middle = (low + high) >>> 1; > > > > > > > float middleValue = a[middle]; > > > > > > > > > > > > > > if (middleValue < 0.0f) { > > > > > > > low = middle + 1; > > > > > > > - } else if (middleValue > 0.0f) { > > > > > > > - high = middle - 1; > > > > > > > - } else { // middleValue == 0.0f > > > > > > > - return middle; > > > > > > > + } else { // middleValue >= 0.0f > > > > > > > + high = middle; > > > > > > > } > > > > > > > + return low; > > > > > > > } > > > > > > > } > > > > > > > > > > > > > > Counting negative values appeared more expensive than any other > > > variants. > > > > > > > The last proposal seems to me as efficient as the current > > > solution is in its worst case - when we have only one negative zero (in > > > the half of array). > > > > > > > And it shows the best result if we have many zeros. > > > > > > > > > > > > > > Regards, > > > > > > > Dmytro Sheyko > > > > > > > > > > > > > > > From: iaroslavski at mail.ru > > > > > > > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > > > > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > > > > > > Subject: Re[2]: New portion of improvements for Dual-Pivot > > > Quicksort > > > > > > > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > > > > > > > > > > > > > > Josh, > > > > > > > > Dmytro, > > > > > > > > > > > > > > > > I have done more thoroughly testing "great - less > 5 * > > > seventh" vs. "less < e1 && great > e5", > > > > > > > > and found that more symmetric code "less < e1 && great > e5" > > > is little bit faster, ~0.5..0.7% > > > > > > > > on both VMs. Other code has not been changed. > > > > > > > > > > > > > > > > Please, take the latest version in attachment. > > > > > > > > > > > > > > > > Vladimir > > > > > > > > > > > > > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua Bloch > > > : > > > > > > > > > > > > > > > > > Vladimir, > > > > > > > > > > > > > > > > > > Old: > > > > > > > > > > > > > > > > > >298 if (less < e1 && great > e5) { > > > > > > > > > > > > > > > > > > New: > > > > > > > > > > > > > > > > > >256 if (great - less > 5 * seventh) { > > > > > > > > > > > > > > > > >Regards, > > > > > > > > >Josh From martinrb at google.com Mon May 17 22:32:32 2010 From: martinrb at google.com (Martin Buchholz) Date: Mon, 17 May 2010 15:32:32 -0700 Subject: Review request for #4853493 In-Reply-To: <4BF1A803.8010009@oracle.com> References: <4BF1A803.8010009@oracle.com> Message-ID: On Mon, May 17, 2010 at 13:33, Xueming Shen wrote: > Martin, > > It appears we should make the defensive copy in this case, as we usually do > in lib code. Yeah, that does look necessary. Approved! You could also keep the header code inside the method thus: private void writeHeader() throws IOException { out.write(new byte[] { (byte) GZIP_MAGIC, // Magic number (short) (byte)(GZIP_MAGIC >> 8), // Magic number (short) Deflater.DEFLATED, // Compression method (CM) 0, // Flags (FLG) 0, // Modification time MTIME (int) 0, // Modification time MTIME (int) 0, // Modification time MTIME (int) 0, // Modification time MTIME (int) 0, // Extra flags (XFLG) 0 // Operating system (OS) }); } > http://cr.openjdk.java.net/~sherman/4853493/webrev > > -Sherman > From xueming.shen at oracle.com Mon May 17 22:59:03 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Mon, 17 May 2010 15:59:03 -0700 Subject: Review request for #4853493 In-Reply-To: References: <4BF1A803.8010009@oracle.com> Message-ID: <4BF1CA37.5030107@oracle.com> It appears the "inline" version makes the GZIPOutputStream.class about 140 byte smaller. And I would guess it might be also faster. The webrev has been updated to go with the "inline" version. Thanks, -Sherman Martin Buchholz wrote: > On Mon, May 17, 2010 at 13:33, Xueming Shen wrote: > >> Martin, >> >> It appears we should make the defensive copy in this case, as we usually do >> in lib code. >> > > Yeah, that does look necessary. Approved! > > You could also keep the header code > inside the method thus: > > private void writeHeader() throws IOException { > out.write(new byte[] { > (byte) GZIP_MAGIC, // Magic number (short) > (byte)(GZIP_MAGIC >> 8), // Magic number (short) > Deflater.DEFLATED, // Compression method (CM) > 0, // Flags (FLG) > 0, // Modification time MTIME (int) > 0, // Modification time MTIME (int) > 0, // Modification time MTIME (int) > 0, // Modification time MTIME (int) > 0, // Extra flags (XFLG) > 0 // Operating system (OS) > }); > } > > > >> http://cr.openjdk.java.net/~sherman/4853493/webrev >> >> -Sherman >> >> From martinrb at google.com Mon May 17 23:06:27 2010 From: martinrb at google.com (Martin Buchholz) Date: Mon, 17 May 2010 16:06:27 -0700 Subject: Review request for #4853493 In-Reply-To: <4BF1CA37.5030107@oracle.com> References: <4BF1A803.8010009@oracle.com> <4BF1CA37.5030107@oracle.com> Message-ID: Looks good! Martin On Mon, May 17, 2010 at 15:59, Xueming Shen wrote: > > It appears the "inline" version makes the GZIPOutputStream.class about 140 > byte smaller. And I would > guess it might be also faster. The webrev has been updated to go with the > "inline" version. > > Thanks, > -Sherman > > Martin Buchholz wrote: >> >> On Mon, May 17, 2010 at 13:33, Xueming Shen >> wrote: >> >>> >>> Martin, >>> >>> It appears we should make the defensive copy in this case, as we usually >>> do >>> in lib code. >>> >> >> Yeah, that does look necessary. ?Approved! >> >> You could also keep the header code >> inside the method thus: >> >> ? ?private void writeHeader() throws IOException { >> ? ? ? ?out.write(new byte[] { >> ? ? ? ? ? ? ? ? ? ? ?(byte) GZIP_MAGIC, ? ? ? // Magic number (short) >> ? ? ? ? ? ? ? ? ? ? ?(byte)(GZIP_MAGIC >> 8), // Magic number (short) >> ? ? ? ? ? ? ? ? ? ? ?Deflater.DEFLATED, ? ? ? // Compression method (CM) >> ? ? ? ? ? ? ? ? ? ? ?0, ? ? ? ? ? ? ? ? ? ? ? // Flags (FLG) >> ? ? ? ? ? ? ? ? ? ? ?0, ? ? ? ? ? ? ? ? ? ? ? // Modification time MTIME >> (int) >> ? ? ? ? ? ? ? ? ? ? ?0, ? ? ? ? ? ? ? ? ? ? ? // Modification time MTIME >> (int) >> ? ? ? ? ? ? ? ? ? ? ?0, ? ? ? ? ? ? ? ? ? ? ? // Modification time MTIME >> (int) >> ? ? ? ? ? ? ? ? ? ? ?0, ? ? ? ? ? ? ? ? ? ? ? // Modification time MTIME >> (int) >> ? ? ? ? ? ? ? ? ? ? ?0, ? ? ? ? ? ? ? ? ? ? ? // Extra flags (XFLG) >> ? ? ? ? ? ? ? ? ? ? ?0 ? ? ? ? ? ? ? ? ? ? ? ?// Operating system (OS) >> ? ? ? ? ? ? ? ? ?}); >> ? ?} >> >> >> >>> >>> http://cr.openjdk.java.net/~sherman/4853493/webrev >>> >>> -Sherman >>> >>> > > From xueming.shen at oracle.com Mon May 17 23:21:46 2010 From: xueming.shen at oracle.com (xueming.shen at oracle.com) Date: Mon, 17 May 2010 23:21:46 +0000 Subject: hg: jdk7/tl/jdk: 4853493: GZIPOutputStream passes a reference to a private array into an untrusted method Message-ID: <20100517232158.DB4CD44EED@hg.openjdk.java.net> Changeset: 1e0c3e864fb1 Author: sherman Date: 2010-05-17 16:18 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/1e0c3e864fb1 4853493: GZIPOutputStream passes a reference to a private array into an untrusted method Summary: create a new header byte array for each header writeout Reviewed-by: martin ! src/share/classes/java/util/zip/GZIPOutputStream.java From dmytro_sheyko at hotmail.com Tue May 18 08:15:07 2010 From: dmytro_sheyko at hotmail.com (Dmytro Sheyko) Date: Tue, 18 May 2010 15:15:07 +0700 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: , Message-ID: Hi, About counting sort again. 1. This condition "i < count.length && k <= right" is excessive. Any one conjunct is enough. "k <= right" seems better. 2. No need to calculate "short value = (short) (i + Short.MIN_VALUE)" when "count[i]" is zero. 3. For signed primitives (byte and short) we would better loop backward. Thanks to "k >= fromIndex" condition we will quit looping earlier assuming that typically we work with positive numbers. For unsigned primitives (char) we would better loop forward because typically we work with characters about zero (ASCII). - for (int i = 0, k = left; i < count.length && k <= right; i++) { - short value = (short) (i + Short.MIN_VALUE); - for (int s = count[i]; s > 0; s--) { - a[k++] = value; - } - } + for (int i = NUM_SHORT_VALUES - 1, k = toIndex - 1; k >= fromIndex; --i) { + while (count[i] == 0) --i; + short value = (short) (i + Short.MIN_VALUE); + int s = count[i]; + do { a[k--] = value; } while (--s > 0); + } Thanks, Dmytro Sheyko > From: iaroslavski at mail.ru > To: dmytro_sheyko at hotmail.com > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > Subject: Re[2]: New portion of improvements for Dual-Pivot Quicksort > Date: Tue, 18 May 2010 01:11:19 +0400 > > Sounds good! > Will consider too... > > Mon, 17 May 2010 22:24:11 +0700 ?????? ?? Dmytro Sheyko : > > > Hi, > > > > Regarding counting sort. We can check whether we should switch to counting sort only once in the beginning. > > > > > Date: Mon, 17 May 2010 17:30:37 +0400 > > > From: iaroslavski at mail.ru > > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > > To: dmytro_sheyko at hotmail.com > > > CC: core-libs-dev at openjdk.java.net > > > > > > Hello, > > > > > > Thank you for review, I'll check and run tests again with you changes. > > > > > > Thank you, > > > Vladimir > > > > > > Dmytro Sheyko wrote: > > > > Hello, > > > > > > > > More ideas. > > > > > > > > 1. We can use > > > > Double.doubleToRawLongBits instead of Double.doubleToLongBits and > > > > Float.floatToRawIntBits instead of Float.floatToIntBits. > > > > No need to handle NaN's because they all are placed to the end of array. > > > > > > > > 2. Note that > > > > Double.doubleToRawLongBits(+0.0) == 0L and > > > > Double.doubleToRawLongBits(-0.0) == Long.MIN_VALUE and > > > > Float.floatToRawIntBits(+0.0) == 0 and > > > > Float.floatToRawIntBits(-0.0) == Integer.MIN_VALUE. > > > > > > > > Comparing with is zero usually more efficient (or at least not worse) > > > > than with other values. Thus such pattern > > > > > > > > if (ak == 0.0f && NEGATIVE_ZERO == Float.floatToIntBits(ak)) > > > > > > > > can be replaced with > > > > > > > > if (ak == 0.0f && Float.floatToIntBits(ak) < 0) > > > > > > > > 3. It would be more efficient to count negative zeros after sorting. > > > > General sorting algorithm puts both negative and positive zeros together > > > > (but maybe not in right order). > > > > Therefore we have to process less elements because usually we have less > > > > zeros than other numbers. > > > > > > > > Thanks, > > > > Dmytro Sheyko > > > > > > > > > From: iaroslavski at mail.ru > > > > > To: dmytro_sheyko at hotmail.com; jjb at google.com > > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > > > Subject: Re[6]: New portion of improvements for Dual-Pivot Quicksort > > > > > Date: Fri, 14 May 2010 23:54:06 +0400 > > > > > > > > > > Hello, > > > > > > > > > > I've updated the class, please, review the changes. > > > > > > > > > > Vladimir > > > > > > > > > > Fri, 14 May 2010 01:48:11 +0700 ?????? ?? Dmytro Sheyko > > > > : > > > > > > > > > > > Yes. I prefer F (Find First zero using binary search) over C (Count > > > > negatives) and S (Smart Scan for zero). > > > > > > > > > > > > > From: iaroslavski at mail.ru > > > > > > > To: dmytro_sheyko at hotmail.com > > > > > > > CC: jjb at google.com; core-libs-dev at openjdk.java.net; > > > > iaroslavski at mail.ru > > > > > > > Subject: Re[4]: New portion of improvements for Dual-Pivot Quicksort > > > > > > > Date: Thu, 13 May 2010 21:34:54 +0400 > > > > > > > > > > > > > > Dmytro, > > > > > > > > > > > > > > I've tested your suggested variants, and found that case "C" > > > > > > > (very interesting approach to find first position of zero > > > > > > > by counting negative elements) works slower than original > > > > > > > or two other cases. > > > > > > > > > > > > > > Implementations "F" and "S" are very close to each other > > > > > > > and little bit faster than original. I prefer case "F": > > > > > > > it is shorter and more clear. Do you agree? > > > > > > > > > > > > > > I'll prepare updated DualPivotQuicksort file and send it > > > > > > > tomorrow. > > > > > > > > > > > > > > Thank you, > > > > > > > Vladimir > > > > > > > > > > > > > > Wed, 12 May 2010 17:04:52 +0700 ?????? ?? Dmytro Sheyko > > > > : > > > > > > > > > > > > > > > Vladimir, > > > > > > > > > > > > > > > > Your changes are good for me. > > > > > > > > > > > > > > > > Additionally I have some comments/proposals regarding dealing > > > > with negative zeros. > > > > > > > > > > > > > > > > 1. Scanning for the first zero we can avoid range check (i >= > > > > left) if we have at least one negative value. > > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > > > > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 2010 > > > > > > > > @@ -1705,10 +1705,15 @@ > > > > > > > > } > > > > > > > > > > > > > > > > // Find first zero element > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > > > + int zeroIndex = 0; > > > > > > > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > > > > > > > - zeroIndex = i; > > > > > > > > + if (a[left] < 0.0f) { > > > > > > > > + zeroIndex = findAnyZero(a, left, n); > > > > > > > > + > > > > > > > > + // there is at least one negative value, so range check is > > > > not needed > > > > > > > > + for (int i = zeroIndex - 1; /*i >= left &&*/ a[i] == 0.0f; i--) { > > > > > > > > + zeroIndex = i; > > > > > > > > + } > > > > > > > > } > > > > > > > > > > > > > > > > // Turn the right number of positive zeros back into negative zeros > > > > > > > > > > > > > > > > 2. We can find the position of the first zero by counting > > > > negative values during preprocessing phase. > > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > > > > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 2010 > > > > > > > > @@ -1678,7 +1678,7 @@ > > > > > > > > * Phase 1: Count negative zeros and move NaNs to end of array. > > > > > > > > */ > > > > > > > > final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f); > > > > > > > > - int numNegativeZeros = 0; > > > > > > > > + int numNegativeZeros = 0, numNegativeValues = 0; > > > > > > > > int n = right; > > > > > > > > > > > > > > > > for (int k = left; k <= n; k++) { > > > > > > > > @@ -1689,6 +1689,8 @@ > > > > > > > > } else if (ak != ak) { // i.e., ak is NaN > > > > > > > > a[k--] = a[n]; > > > > > > > > a[n--] = Float.NaN; > > > > > > > > + } else if (ak < 0.0f) { > > > > > > > > + numNegativeValues++; > > > > > > > > } > > > > > > > > } > > > > > > > > > > > > > > > > @@ -1705,7 +1707,7 @@ > > > > > > > > } > > > > > > > > > > > > > > > > // Find first zero element > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > > > + int zeroIndex = numNegativeValues; > > > > > > > > > > > > > > > > for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > > > > > > > zeroIndex = i; > > > > > > > > > > > > > > > > 3. We can use binary search to find the first zero and thus > > > > avoid linear scan. > > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > > > > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 2010 > > > > > > > > @@ -1705,11 +1705,7 @@ > > > > > > > > } > > > > > > > > > > > > > > > > // Find first zero element > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > > > - > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; i--) { > > > > > > > > - zeroIndex = i; > > > > > > > > - } > > > > > > > > + int zeroIndex = findFirstZero(a, left, n); > > > > > > > > > > > > > > > > // Turn the right number of positive zeros back into negative zeros > > > > > > > > for (int i = zeroIndex, m = zeroIndex + numNegativeZeros; i < > > > > m; i++) { > > > > > > > > @@ -1718,7 +1714,7 @@ > > > > > > > > } > > > > > > > > > > > > > > > > /** > > > > > > > > - * Returns the index of some zero element in the specified > > > > range via > > > > > > > > + * Returns the index of the first zero element in the > > > > specified range via > > > > > > > > * binary search. The range is assumed to be sorted, and must > > > > contain > > > > > > > > * at least one zero. > > > > > > > > * > > > > > > > > @@ -1726,18 +1722,17 @@ > > > > > > > > * @param low the index of the first element, inclusive, to be > > > > searched > > > > > > > > * @param high the index of the last element, inclusive, to be > > > > searched > > > > > > > > */ > > > > > > > > - private static int findAnyZero(float[] a, int low, int high) { > > > > > > > > - while (true) { > > > > > > > > + private static int findFirstZero(float[] a, int low, int high) { > > > > > > > > + while (low < high) { > > > > > > > > int middle = (low + high) >>> 1; > > > > > > > > float middleValue = a[middle]; > > > > > > > > > > > > > > > > if (middleValue < 0.0f) { > > > > > > > > low = middle + 1; > > > > > > > > - } else if (middleValue > 0.0f) { > > > > > > > > - high = middle - 1; > > > > > > > > - } else { // middleValue == 0.0f > > > > > > > > - return middle; > > > > > > > > + } else { // middleValue >= 0.0f > > > > > > > > + high = middle; > > > > > > > > } > > > > > > > > + return low; > > > > > > > > } > > > > > > > > } > > > > > > > > > > > > > > > > Counting negative values appeared more expensive than any other > > > > variants. > > > > > > > > The last proposal seems to me as efficient as the current > > > > solution is in its worst case - when we have only one negative zero (in > > > > the half of array). > > > > > > > > And it shows the best result if we have many zeros. > > > > > > > > > > > > > > > > Regards, > > > > > > > > Dmytro Sheyko > > > > > > > > > > > > > > > > > From: iaroslavski at mail.ru > > > > > > > > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > > > > > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > > > > > > > Subject: Re[2]: New portion of improvements for Dual-Pivot > > > > Quicksort > > > > > > > > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > > > > > > > > > > > > > > > > Josh, > > > > > > > > > Dmytro, > > > > > > > > > > > > > > > > > > I have done more thoroughly testing "great - less > 5 * > > > > seventh" vs. "less < e1 && great > e5", > > > > > > > > > and found that more symmetric code "less < e1 && great > e5" > > > > is little bit faster, ~0.5..0.7% > > > > > > > > > on both VMs. Other code has not been changed. > > > > > > > > > > > > > > > > > > Please, take the latest version in attachment. > > > > > > > > > > > > > > > > > > Vladimir > > > > > > > > > > > > > > > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua Bloch > > > > : > > > > > > > > > > > > > > > > > > > Vladimir, > > > > > > > > > > > > > > > > > > > > Old: > > > > > > > > > > > > > > > > > > > >298 if (less < e1 && great > e5) { > > > > > > > > > > > > > > > > > > > > New: > > > > > > > > > > > > > > > > > > > >256 if (great - less > 5 * seventh) { > > > > > > > > > > > > > > > > > > >Regards, > > > > > > > > > >Josh _________________________________________________________________ Hotmail: Powerful Free email with security by Microsoft. https://signup.live.com/signup.aspx?id=60969 -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: DualPivotQuicksort.diff Type: application/octet-stream Size: 7127 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: DualPivotQuicksort.java Type: text/x-java Size: 101553 bytes Desc: not available URL: From iaroslavski at mail.ru Tue May 18 14:57:50 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Tue, 18 May 2010 18:57:50 +0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: Message-ID: <4BF2AAEE.1040706@mail.ru> Hello, I've run your modification for counting sort, it real faster. I attached new version with your changes (I did little bit format it) and included my case with float/double. Note that you modification doesn't pass test from Sorting class, which I sent earlier. It fails on float/double test: Test #3: random = 666, len = 34, a = 0, g = 6, z = 9, n = 10, p = 9 I suggest shorter method (which is based on your idea to skip counting negative zeros on Phase 1.): I found find first zero index (or it will be index of first positive element if no zeros at all, or last negative, if no positive and zero elements) and then swap negative zero to the beginning of the sub-range. int hi = right; while (left < hi) { int middle = (left + hi) >>> 1; float middleValue = a[middle]; if (middleValue < 0.0f) { left = middle + 1; } else { hi = middle; } } for (int k = left, p = left; k <= right; k++) { float ak = a[k]; if (ak != 0.0f) { return; } if (Float.floatToRawIntBits(ak) < 0) { // ak is -0.0f a[k] = +0.0f; a[p++] = -0.0f; } } Important note: in partitioning loop there are several places (marked by // !) where potential bug with -0.0 could be (when pivot and a[great] are zeros with different signs): if (a[great] == pivot1) { a[k] = a[less]; - a[less++] = pivot1; // ! + a[less++] = a[great]; } else { // pivot1 < a[great] < pivot2 a[k] = a[great]; } - a[great--] = pivot2; // ! + a[great--] = ak; } else if (ak == pivot1) { // Move a[k] to left part a[k] = a[less]; - a[less++] = pivot1; // ! + a[less++] = ak; } and the same in "Pivots are equal" branch. I did changes "pivot1/2 -> ak" in methods for all types and "pivot1 -> a[great]" in float/double sections only. Please, review format changes for counting sort and new version of Phase 3 for float/double. Thank you, Vladimir Dmytro Sheyko wrote: > Hi, > > About counting sort again. > > 1. This condition "i < count.length && k <= right" is excessive. Any one > conjunct is enough. "k <= right" seems better. > 2. No need to calculate "short value = (short) (i + Short.MIN_VALUE)" > when "count[i]" is zero. > 3. For signed primitives (byte and short) we would better loop backward. > Thanks to "k >= fromIndex" condition we will quit looping earlier > assuming that typically we work with positive numbers. > For unsigned primitives (char) we would better loop forward because > typically we work with characters about zero (ASCII). > > - for (int i = 0, k = left; i < count.length && k <= right; i++) { > - short value = (short) (i + Short.MIN_VALUE); > - for (int s = count[i]; s > 0; s--) { > - a[k++] = value; > - } > - } > > + for (int i = NUM_SHORT_VALUES - 1, k = toIndex - 1; k >= > fromIndex; --i) { > + while (count[i] == 0) --i; > + short value = (short) (i + Short.MIN_VALUE); > + int s = count[i]; > + do { a[k--] = value; } while (--s > 0); > + } > > Thanks, > Dmytro Sheyko > > > From: iaroslavski at mail.ru > > To: dmytro_sheyko at hotmail.com > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > Subject: Re[2]: New portion of improvements for Dual-Pivot Quicksort > > Date: Tue, 18 May 2010 01:11:19 +0400 > > > > Sounds good! > > Will consider too... > > > > Mon, 17 May 2010 22:24:11 +0700 ?????? ?? Dmytro Sheyko > : > > > > > Hi, > > > > > > Regarding counting sort. We can check whether we should switch to > counting sort only once in the beginning. > > > > > > > Date: Mon, 17 May 2010 17:30:37 +0400 > > > > From: iaroslavski at mail.ru > > > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > > > To: dmytro_sheyko at hotmail.com > > > > CC: core-libs-dev at openjdk.java.net > > > > > > > > Hello, > > > > > > > > Thank you for review, I'll check and run tests again with you > changes. > > > > > > > > Thank you, > > > > Vladimir > > > > > > > > Dmytro Sheyko wrote: > > > > > Hello, > > > > > > > > > > More ideas. > > > > > > > > > > 1. We can use > > > > > Double.doubleToRawLongBits instead of Double.doubleToLongBits and > > > > > Float.floatToRawIntBits instead of Float.floatToIntBits. > > > > > No need to handle NaN's because they all are placed to the end > of array. > > > > > > > > > > 2. Note that > > > > > Double.doubleToRawLongBits(+0.0) == 0L and > > > > > Double.doubleToRawLongBits(-0.0) == Long.MIN_VALUE and > > > > > Float.floatToRawIntBits(+0.0) == 0 and > > > > > Float.floatToRawIntBits(-0.0) == Integer.MIN_VALUE. > > > > > > > > > > Comparing with is zero usually more efficient (or at least not > worse) > > > > > than with other values. Thus such pattern > > > > > > > > > > if (ak == 0.0f && NEGATIVE_ZERO == Float.floatToIntBits(ak)) > > > > > > > > > > can be replaced with > > > > > > > > > > if (ak == 0.0f && Float.floatToIntBits(ak) < 0) > > > > > > > > > > 3. It would be more efficient to count negative zeros after > sorting. > > > > > General sorting algorithm puts both negative and positive zeros > together > > > > > (but maybe not in right order). > > > > > Therefore we have to process less elements because usually we > have less > > > > > zeros than other numbers. > > > > > > > > > > Thanks, > > > > > Dmytro Sheyko > > > > > > > > > > > From: iaroslavski at mail.ru > > > > > > To: dmytro_sheyko at hotmail.com; jjb at google.com > > > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > > > > Subject: Re[6]: New portion of improvements for Dual-Pivot > Quicksort > > > > > > Date: Fri, 14 May 2010 23:54:06 +0400 > > > > > > > > > > > > Hello, > > > > > > > > > > > > I've updated the class, please, review the changes. > > > > > > > > > > > > Vladimir > > > > > > > > > > > > Fri, 14 May 2010 01:48:11 +0700 ?????? ?? Dmytro Sheyko > > > > > : > > > > > > > > > > > > > Yes. I prefer F (Find First zero using binary search) over > C (Count > > > > > negatives) and S (Smart Scan for zero). > > > > > > > > > > > > > > > From: iaroslavski at mail.ru > > > > > > > > To: dmytro_sheyko at hotmail.com > > > > > > > > CC: jjb at google.com; core-libs-dev at openjdk.java.net; > > > > > iaroslavski at mail.ru > > > > > > > > Subject: Re[4]: New portion of improvements for > Dual-Pivot Quicksort > > > > > > > > Date: Thu, 13 May 2010 21:34:54 +0400 > > > > > > > > > > > > > > > > Dmytro, > > > > > > > > > > > > > > > > I've tested your suggested variants, and found that case "C" > > > > > > > > (very interesting approach to find first position of zero > > > > > > > > by counting negative elements) works slower than original > > > > > > > > or two other cases. > > > > > > > > > > > > > > > > Implementations "F" and "S" are very close to each other > > > > > > > > and little bit faster than original. I prefer case "F": > > > > > > > > it is shorter and more clear. Do you agree? > > > > > > > > > > > > > > > > I'll prepare updated DualPivotQuicksort file and send it > > > > > > > > tomorrow. > > > > > > > > > > > > > > > > Thank you, > > > > > > > > Vladimir > > > > > > > > > > > > > > > > Wed, 12 May 2010 17:04:52 +0700 ?????? ?? Dmytro Sheyko > > > > > : > > > > > > > > > > > > > > > > > Vladimir, > > > > > > > > > > > > > > > > > > Your changes are good for me. > > > > > > > > > > > > > > > > > > Additionally I have some comments/proposals regarding > dealing > > > > > with negative zeros. > > > > > > > > > > > > > > > > > > 1. Scanning for the first zero we can avoid range check > (i >= > > > > > left) if we have at least one negative value. > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > > > > > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 2010 > > > > > > > > > @@ -1705,10 +1705,15 @@ > > > > > > > > > } > > > > > > > > > > > > > > > > > > // Find first zero element > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > > > > + int zeroIndex = 0; > > > > > > > > > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == > 0.0f; i--) { > > > > > > > > > - zeroIndex = i; > > > > > > > > > + if (a[left] < 0.0f) { > > > > > > > > > + zeroIndex = findAnyZero(a, left, n); > > > > > > > > > + > > > > > > > > > + // there is at least one negative value, so range > check is > > > > > not needed > > > > > > > > > + for (int i = zeroIndex - 1; /*i >= left &&*/ a[i] == > 0.0f; i--) { > > > > > > > > > + zeroIndex = i; > > > > > > > > > + } > > > > > > > > > } > > > > > > > > > > > > > > > > > > // Turn the right number of positive zeros back into > negative zeros > > > > > > > > > > > > > > > > > > 2. We can find the position of the first zero by counting > > > > > negative values during preprocessing phase. > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > > > > > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 2010 > > > > > > > > > @@ -1678,7 +1678,7 @@ > > > > > > > > > * Phase 1: Count negative zeros and move NaNs to end of > array. > > > > > > > > > */ > > > > > > > > > final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f); > > > > > > > > > - int numNegativeZeros = 0; > > > > > > > > > + int numNegativeZeros = 0, numNegativeValues = 0; > > > > > > > > > int n = right; > > > > > > > > > > > > > > > > > > for (int k = left; k <= n; k++) { > > > > > > > > > @@ -1689,6 +1689,8 @@ > > > > > > > > > } else if (ak != ak) { // i.e., ak is NaN > > > > > > > > > a[k--] = a[n]; > > > > > > > > > a[n--] = Float.NaN; > > > > > > > > > + } else if (ak < 0.0f) { > > > > > > > > > + numNegativeValues++; > > > > > > > > > } > > > > > > > > > } > > > > > > > > > > > > > > > > > > @@ -1705,7 +1707,7 @@ > > > > > > > > > } > > > > > > > > > > > > > > > > > > // Find first zero element > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > > > > + int zeroIndex = numNegativeValues; > > > > > > > > > > > > > > > > > > for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; > i--) { > > > > > > > > > zeroIndex = i; > > > > > > > > > > > > > > > > > > 3. We can use binary search to find the first zero and > thus > > > > > avoid linear scan. > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > > > > > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 2010 > > > > > > > > > @@ -1705,11 +1705,7 @@ > > > > > > > > > } > > > > > > > > > > > > > > > > > > // Find first zero element > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > > > > - > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == > 0.0f; i--) { > > > > > > > > > - zeroIndex = i; > > > > > > > > > - } > > > > > > > > > + int zeroIndex = findFirstZero(a, left, n); > > > > > > > > > > > > > > > > > > // Turn the right number of positive zeros back into > negative zeros > > > > > > > > > for (int i = zeroIndex, m = zeroIndex + > numNegativeZeros; i < > > > > > m; i++) { > > > > > > > > > @@ -1718,7 +1714,7 @@ > > > > > > > > > } > > > > > > > > > > > > > > > > > > /** > > > > > > > > > - * Returns the index of some zero element in the > specified > > > > > range via > > > > > > > > > + * Returns the index of the first zero element in the > > > > > specified range via > > > > > > > > > * binary search. The range is assumed to be sorted, and > must > > > > > contain > > > > > > > > > * at least one zero. > > > > > > > > > * > > > > > > > > > @@ -1726,18 +1722,17 @@ > > > > > > > > > * @param low the index of the first element, inclusive, > to be > > > > > searched > > > > > > > > > * @param high the index of the last element, inclusive, > to be > > > > > searched > > > > > > > > > */ > > > > > > > > > - private static int findAnyZero(float[] a, int low, > int high) { > > > > > > > > > - while (true) { > > > > > > > > > + private static int findFirstZero(float[] a, int low, > int high) { > > > > > > > > > + while (low < high) { > > > > > > > > > int middle = (low + high) >>> 1; > > > > > > > > > float middleValue = a[middle]; > > > > > > > > > > > > > > > > > > if (middleValue < 0.0f) { > > > > > > > > > low = middle + 1; > > > > > > > > > - } else if (middleValue > 0.0f) { > > > > > > > > > - high = middle - 1; > > > > > > > > > - } else { // middleValue == 0.0f > > > > > > > > > - return middle; > > > > > > > > > + } else { // middleValue >= 0.0f > > > > > > > > > + high = middle; > > > > > > > > > } > > > > > > > > > + return low; > > > > > > > > > } > > > > > > > > > } > > > > > > > > > > > > > > > > > > Counting negative values appeared more expensive than > any other > > > > > variants. > > > > > > > > > The last proposal seems to me as efficient as the current > > > > > solution is in its worst case - when we have only one negative > zero (in > > > > > the half of array). > > > > > > > > > And it shows the best result if we have many zeros. > > > > > > > > > > > > > > > > > > Regards, > > > > > > > > > Dmytro Sheyko > > > > > > > > > > > > > > > > > > > From: iaroslavski at mail.ru > > > > > > > > > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > > > > > > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > > > > > > > > Subject: Re[2]: New portion of improvements for > Dual-Pivot > > > > > Quicksort > > > > > > > > > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > > > > > > > > > > > > > > > > > > Josh, > > > > > > > > > > Dmytro, > > > > > > > > > > > > > > > > > > > > I have done more thoroughly testing "great - less > 5 * > > > > > seventh" vs. "less < e1 && great > e5", > > > > > > > > > > and found that more symmetric code "less < e1 && > great > e5" > > > > > is little bit faster, ~0.5..0.7% > > > > > > > > > > on both VMs. Other code has not been changed. > > > > > > > > > > > > > > > > > > > > Please, take the latest version in attachment. > > > > > > > > > > > > > > > > > > > > Vladimir > > > > > > > > > > > > > > > > > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua Bloch > > > > > : > > > > > > > > > > > > > > > > > > > > > Vladimir, > > > > > > > > > > > > > > > > > > > > > > Old: > > > > > > > > > > > > > > > > > > > > > >298 if (less < e1 && great > e5) { > > > > > > > > > > > > > > > > > > > > > > New: > > > > > > > > > > > > > > > > > > > > > >256 if (great - less > 5 * seventh) { > > > > > > > > > > > > > > > > > > > > >Regards, > > > > > > > > > > >Josh -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: DualPivotQuicksort.java URL: From mandy.chung at oracle.com Tue May 18 20:14:43 2010 From: mandy.chung at oracle.com (mandy.chung at oracle.com) Date: Tue, 18 May 2010 20:14:43 +0000 Subject: hg: jdk7/tl/jdk: 6951599: Rename package of security tools for modularization Message-ID: <20100518201521.6CD0F44079@hg.openjdk.java.net> Changeset: b3466e2c3819 Author: mchung Date: 2010-05-18 13:12 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/b3466e2c3819 6951599: Rename package of security tools for modularization Summary: Move PolicyTool to sun.security.tools.policytool package Reviewed-by: weijun ! make/modules/modules.config ! make/sun/security/tools/Makefile - src/share/classes/sun/security/tools/PolicyTool.java + src/share/classes/sun/security/tools/policytool/PolicyTool.java From xueming.shen at oracle.com Tue May 18 22:39:46 2010 From: xueming.shen at oracle.com (xueming.shen at oracle.com) Date: Tue, 18 May 2010 22:39:46 +0000 Subject: hg: jdk7/tl/jdk: 6945564: Unicode script support in Character class; ... Message-ID: <20100518224001.283924413D@hg.openjdk.java.net> Changeset: 33409b9b0f49 Author: sherman Date: 2010-05-18 15:36 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/33409b9b0f49 6945564: Unicode script support in Character class 6948903: Make Unicode scripts available for use in regular expressions Summary: added Unicode script suport Reviewed-by: martin ! make/java/java/FILES_java.gmk ! make/java/java/Makefile + make/tools/UnicodeData/Scripts.txt + make/tools/src/build/tools/generatecharacter/CharacterName.java + make/tools/src/build/tools/generatecharacter/CharacterScript.java ! make/tools/src/build/tools/generatecharacter/GenerateCharacter.java ! src/share/classes/java/lang/Character.java + src/share/classes/java/lang/CharacterName.java ! src/share/classes/java/util/regex/Pattern.java + test/java/lang/Character/CheckScript.java + test/java/lang/Character/Scripts.txt ! test/java/util/regex/RegExTest.java From martinrb at google.com Wed May 19 04:32:59 2010 From: martinrb at google.com (Martin Buchholz) Date: Tue, 18 May 2010 21:32:59 -0700 Subject: 4813885: RFE: GZIPOutputStream should implement flush using Z_SYNC_FLUSH In-Reply-To: <4BEBA622.2050303@oracle.com> References: <4BEB310E.5090602@oracle.com> <4BEBA061.4000206@oracle.com> <4BEBA622.2050303@oracle.com> Message-ID: On Thu, May 13, 2010 at 00:11, Xueming Shen wrote: > Martin Buchholz wrote: >> >> On Wed, May 12, 2010 at 23:46, Xueming Shen >> wrote: >> >>> >>> Thanks for the review. >>> >>> The Z_SYNC_FLUSH is supposed to fully replace the Z_PARTIAL_FLUSH. >>> >>> We concluded last round that Z_SYNC_FLUSH is enough for the "high-level" >>> DOS, as well as the GZIPOS, use Deflater directly if ?more needed. I hope >>> you >>> are not suggesting we go back to redo the flush to int. >>> >> >> Maybe we should. >> >> http://www.jcraft.com/jzlib/ >> >> """ >> To implement this functionality, the Z_PARTIAL_FLUSH mode of zlib must >> be used, however JDK does not permit us to do so. It seems that this >> problem has been well known and some people have already reported to >> JavaSoft's BugParade(for example, BugId:4255743), but any positive >> response has not been returned from JavaSoft, so this problem will not >> be solved forever. This is our motivation to hack JZlib. >> """ >> >> > > I thought I had closed this one (#4255743) as the dup of #4206909. > > This is actually why we did 4206909 and now doing #4813885. With the fix for > #4206909, you no > longer need jzlib:-) Yes, we use Z_SYNC_FLUSH, not Z_PARTIAL_FLUSH because > the later is going > away, replaced by Z_SYNC_FLUSH. They are the same thing. I can't say that I really understand the difference, but... The description of the different flush modes in zlib.h clearly distinguishes between Z_SYNC_FLUSH and Z_PARTIAL_FLUSH. Z_PARTIAL_FLUSH is clearly undeprecated in zlib 1.2.5 """- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays)""" So I remain unconvinced, but I'm not going to push on this any more, or at least not until I understand it better. Martin > So with #4206909 and #4813885 you can now ?sync_flush the GZIPOutputStream > and > DeflaterOutputStream, as needed by the "functionality" mentioned in jzlib. > > Sherman > > > From martinrb at google.com Wed May 19 04:35:16 2010 From: martinrb at google.com (Martin Buchholz) Date: Tue, 18 May 2010 21:35:16 -0700 Subject: 4813885: RFE: GZIPOutputStream should implement flush using Z_SYNC_FLUSH In-Reply-To: <4BEB310E.5090602@oracle.com> References: <4BEB310E.5090602@oracle.com> Message-ID: The Z_PARTIAL_FLUSH mini-controversy should not hold up the commit of 4813885: RFE: GZIPOutputStream should implement flush using Z_SYNC_FLUSH It looks good to me, except for two unnecessary added blank lines * @exception IllegalArgumentException if size is <= 0 + */ } + /** * Creates a new output stream with a default buffer size. Martin On Wed, May 12, 2010 at 15:51, Xueming Shen wrote: > Martin, > > Would you please help review the change for > > 4813885: RFE: GZIPOutputStream should implement flush using Z_SYNC_FLUSH > > http://cr.openjdk.java.net/~sherman/4813885/webrev > > It appears people want to have the same flush option in GZIPOutputStream as > the > one we provided in DeflaterOutputStream for #4206909 a while ago, the webrev > for > 4206909 is at > > http://cr.openjdk.java.net/~sherman/4206909/webrev > > Thanks, > -Sherman > From dmytro_sheyko at hotmail.com Wed May 19 09:02:56 2010 From: dmytro_sheyko at hotmail.com (Dmytro Sheyko) Date: Wed, 19 May 2010 16:02:56 +0700 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: <4BF2AAEE.1040706@mail.ru> References: , , , <4BF2AAEE.1040706@mail.ru> Message-ID: Vladimir, I can see that you changed sortNegZeroAndNaN(float[]...) but probably forgot to change sortNegZeroAndNaN(double[]...). You really puzzled me with failed testcase and note that sorting algorithm (without special attention to zeros) generally may change number of negative zeros. I will provide my comments later. As for counting sort, I think we should use single format style over the file (unless we have valuable reason not to do this). I mean to choose 1) if (toIndex - fromIndex > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { countingSort(a, fromIndex, toIndex); return; } sort(a, fromIndex, toIndex - 1, true); 2) if (toIndex - fromIndex > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { countingSort(a, fromIndex, toIndex); } else { sort(a, fromIndex, toIndex - 1, true); } I prefer the second one. Thanks a lot, Dmytro Sheyko > Date: Tue, 18 May 2010 18:57:50 +0400 > From: iaroslavski at mail.ru > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > To: dmytro_sheyko at hotmail.com > CC: core-libs-dev at openjdk.java.net > > Hello, > > I've run your modification for counting sort, it real faster. > I attached new version with your changes (I did little bit > format it) and included my case with float/double. > > Note that you modification doesn't pass test from Sorting class, > which I sent earlier. It fails on float/double test: > > Test #3: random = 666, len = 34, a = 0, g = 6, z = 9, n = 10, p = 9 > > I suggest shorter method (which is based on your idea to skip counting > negative zeros on Phase 1.): I found find first zero index (or it will > be index of first positive element if no zeros at all, or last negative, > if no positive and zero elements) and then swap negative zero to the > beginning of the sub-range. > > int hi = right; > > while (left < hi) { > int middle = (left + hi) >>> 1; > float middleValue = a[middle]; > > if (middleValue < 0.0f) { > left = middle + 1; > } else { > hi = middle; > } > } > > for (int k = left, p = left; k <= right; k++) { > float ak = a[k]; > if (ak != 0.0f) { > return; > } > if (Float.floatToRawIntBits(ak) < 0) { // ak is -0.0f > a[k] = +0.0f; > a[p++] = -0.0f; > } > } > > Important note: in partitioning loop there are several places > (marked by // !) where potential bug with -0.0 could be > (when pivot and a[great] are zeros with different signs): > > if (a[great] == pivot1) { > a[k] = a[less]; > - a[less++] = pivot1; // ! > + a[less++] = a[great]; > } else { // pivot1 < a[great] < pivot2 > a[k] = a[great]; > } > - a[great--] = pivot2; // ! > + a[great--] = ak; > } else if (ak == pivot1) { // Move a[k] to left part > a[k] = a[less]; > - a[less++] = pivot1; // ! > + a[less++] = ak; > } > > and the same in "Pivots are equal" branch. > > I did changes "pivot1/2 -> ak" in methods for all types > and "pivot1 -> a[great]" in float/double sections only. > > Please, review format changes for counting sort and new version > of Phase 3 for float/double. > > Thank you, > Vladimir > > Dmytro Sheyko wrote: > > Hi, > > > > About counting sort again. > > > > 1. This condition "i < count.length && k <= right" is excessive. Any one > > conjunct is enough. "k <= right" seems better. > > 2. No need to calculate "short value = (short) (i + Short.MIN_VALUE)" > > when "count[i]" is zero. > > 3. For signed primitives (byte and short) we would better loop backward. > > Thanks to "k >= fromIndex" condition we will quit looping earlier > > assuming that typically we work with positive numbers. > > For unsigned primitives (char) we would better loop forward because > > typically we work with characters about zero (ASCII). > > > > - for (int i = 0, k = left; i < count.length && k <= right; i++) { > > - short value = (short) (i + Short.MIN_VALUE); > > - for (int s = count[i]; s > 0; s--) { > > - a[k++] = value; > > - } > > - } > > > > + for (int i = NUM_SHORT_VALUES - 1, k = toIndex - 1; k >= > > fromIndex; --i) { > > + while (count[i] == 0) --i; > > + short value = (short) (i + Short.MIN_VALUE); > > + int s = count[i]; > > + do { a[k--] = value; } while (--s > 0); > > + } > > > > Thanks, > > Dmytro Sheyko > > > > > From: iaroslavski at mail.ru > > > To: dmytro_sheyko at hotmail.com > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > Subject: Re[2]: New portion of improvements for Dual-Pivot Quicksort > > > Date: Tue, 18 May 2010 01:11:19 +0400 > > > > > > Sounds good! > > > Will consider too... > > > > > > Mon, 17 May 2010 22:24:11 +0700 ?????? ?? Dmytro Sheyko > > : > > > > > > > Hi, > > > > > > > > Regarding counting sort. We can check whether we should switch to > > counting sort only once in the beginning. > > > > > > > > > Date: Mon, 17 May 2010 17:30:37 +0400 > > > > > From: iaroslavski at mail.ru > > > > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > > > > To: dmytro_sheyko at hotmail.com > > > > > CC: core-libs-dev at openjdk.java.net > > > > > > > > > > Hello, > > > > > > > > > > Thank you for review, I'll check and run tests again with you > > changes. > > > > > > > > > > Thank you, > > > > > Vladimir > > > > > > > > > > Dmytro Sheyko wrote: > > > > > > Hello, > > > > > > > > > > > > More ideas. > > > > > > > > > > > > 1. We can use > > > > > > Double.doubleToRawLongBits instead of Double.doubleToLongBits and > > > > > > Float.floatToRawIntBits instead of Float.floatToIntBits. > > > > > > No need to handle NaN's because they all are placed to the end > > of array. > > > > > > > > > > > > 2. Note that > > > > > > Double.doubleToRawLongBits(+0.0) == 0L and > > > > > > Double.doubleToRawLongBits(-0.0) == Long.MIN_VALUE and > > > > > > Float.floatToRawIntBits(+0.0) == 0 and > > > > > > Float.floatToRawIntBits(-0.0) == Integer.MIN_VALUE. > > > > > > > > > > > > Comparing with is zero usually more efficient (or at least not > > worse) > > > > > > than with other values. Thus such pattern > > > > > > > > > > > > if (ak == 0.0f && NEGATIVE_ZERO == Float.floatToIntBits(ak)) > > > > > > > > > > > > can be replaced with > > > > > > > > > > > > if (ak == 0.0f && Float.floatToIntBits(ak) < 0) > > > > > > > > > > > > 3. It would be more efficient to count negative zeros after > > sorting. > > > > > > General sorting algorithm puts both negative and positive zeros > > together > > > > > > (but maybe not in right order). > > > > > > Therefore we have to process less elements because usually we > > have less > > > > > > zeros than other numbers. > > > > > > > > > > > > Thanks, > > > > > > Dmytro Sheyko > > > > > > > > > > > > > From: iaroslavski at mail.ru > > > > > > > To: dmytro_sheyko at hotmail.com; jjb at google.com > > > > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > > > > > Subject: Re[6]: New portion of improvements for Dual-Pivot > > Quicksort > > > > > > > Date: Fri, 14 May 2010 23:54:06 +0400 > > > > > > > > > > > > > > Hello, > > > > > > > > > > > > > > I've updated the class, please, review the changes. > > > > > > > > > > > > > > Vladimir > > > > > > > > > > > > > > Fri, 14 May 2010 01:48:11 +0700 ?????? ?? Dmytro Sheyko > > > > > > : > > > > > > > > > > > > > > > Yes. I prefer F (Find First zero using binary search) over > > C (Count > > > > > > negatives) and S (Smart Scan for zero). > > > > > > > > > > > > > > > > > From: iaroslavski at mail.ru > > > > > > > > > To: dmytro_sheyko at hotmail.com > > > > > > > > > CC: jjb at google.com; core-libs-dev at openjdk.java.net; > > > > > > iaroslavski at mail.ru > > > > > > > > > Subject: Re[4]: New portion of improvements for > > Dual-Pivot Quicksort > > > > > > > > > Date: Thu, 13 May 2010 21:34:54 +0400 > > > > > > > > > > > > > > > > > > Dmytro, > > > > > > > > > > > > > > > > > > I've tested your suggested variants, and found that case "C" > > > > > > > > > (very interesting approach to find first position of zero > > > > > > > > > by counting negative elements) works slower than original > > > > > > > > > or two other cases. > > > > > > > > > > > > > > > > > > Implementations "F" and "S" are very close to each other > > > > > > > > > and little bit faster than original. I prefer case "F": > > > > > > > > > it is shorter and more clear. Do you agree? > > > > > > > > > > > > > > > > > > I'll prepare updated DualPivotQuicksort file and send it > > > > > > > > > tomorrow. > > > > > > > > > > > > > > > > > > Thank you, > > > > > > > > > Vladimir > > > > > > > > > > > > > > > > > > Wed, 12 May 2010 17:04:52 +0700 ?????? ?? Dmytro Sheyko > > > > > > : > > > > > > > > > > > > > > > > > > > Vladimir, > > > > > > > > > > > > > > > > > > > > Your changes are good for me. > > > > > > > > > > > > > > > > > > > > Additionally I have some comments/proposals regarding > > dealing > > > > > > with negative zeros. > > > > > > > > > > > > > > > > > > > > 1. Scanning for the first zero we can avoid range check > > (i >= > > > > > > left) if we have at least one negative value. > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > > > > > > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 2010 > > > > > > > > > > @@ -1705,10 +1705,15 @@ > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > // Find first zero element > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > > > > > + int zeroIndex = 0; > > > > > > > > > > > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == > > 0.0f; i--) { > > > > > > > > > > - zeroIndex = i; > > > > > > > > > > + if (a[left] < 0.0f) { > > > > > > > > > > + zeroIndex = findAnyZero(a, left, n); > > > > > > > > > > + > > > > > > > > > > + // there is at least one negative value, so range > > check is > > > > > > not needed > > > > > > > > > > + for (int i = zeroIndex - 1; /*i >= left &&*/ a[i] == > > 0.0f; i--) { > > > > > > > > > > + zeroIndex = i; > > > > > > > > > > + } > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > // Turn the right number of positive zeros back into > > negative zeros > > > > > > > > > > > > > > > > > > > > 2. We can find the position of the first zero by counting > > > > > > negative values during preprocessing phase. > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > > > > > > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 2010 > > > > > > > > > > @@ -1678,7 +1678,7 @@ > > > > > > > > > > * Phase 1: Count negative zeros and move NaNs to end of > > array. > > > > > > > > > > */ > > > > > > > > > > final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f); > > > > > > > > > > - int numNegativeZeros = 0; > > > > > > > > > > + int numNegativeZeros = 0, numNegativeValues = 0; > > > > > > > > > > int n = right; > > > > > > > > > > > > > > > > > > > > for (int k = left; k <= n; k++) { > > > > > > > > > > @@ -1689,6 +1689,8 @@ > > > > > > > > > > } else if (ak != ak) { // i.e., ak is NaN > > > > > > > > > > a[k--] = a[n]; > > > > > > > > > > a[n--] = Float.NaN; > > > > > > > > > > + } else if (ak < 0.0f) { > > > > > > > > > > + numNegativeValues++; > > > > > > > > > > } > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > @@ -1705,7 +1707,7 @@ > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > // Find first zero element > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > > > > > + int zeroIndex = numNegativeValues; > > > > > > > > > > > > > > > > > > > > for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; > > i--) { > > > > > > > > > > zeroIndex = i; > > > > > > > > > > > > > > > > > > > > 3. We can use binary search to find the first zero and > > thus > > > > > > avoid linear scan. > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > > > > > > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 2010 > > > > > > > > > > @@ -1705,11 +1705,7 @@ > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > // Find first zero element > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > > > > > - > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == > > 0.0f; i--) { > > > > > > > > > > - zeroIndex = i; > > > > > > > > > > - } > > > > > > > > > > + int zeroIndex = findFirstZero(a, left, n); > > > > > > > > > > > > > > > > > > > > // Turn the right number of positive zeros back into > > negative zeros > > > > > > > > > > for (int i = zeroIndex, m = zeroIndex + > > numNegativeZeros; i < > > > > > > m; i++) { > > > > > > > > > > @@ -1718,7 +1714,7 @@ > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > - * Returns the index of some zero element in the > > specified > > > > > > range via > > > > > > > > > > + * Returns the index of the first zero element in the > > > > > > specified range via > > > > > > > > > > * binary search. The range is assumed to be sorted, and > > must > > > > > > contain > > > > > > > > > > * at least one zero. > > > > > > > > > > * > > > > > > > > > > @@ -1726,18 +1722,17 @@ > > > > > > > > > > * @param low the index of the first element, inclusive, > > to be > > > > > > searched > > > > > > > > > > * @param high the index of the last element, inclusive, > > to be > > > > > > searched > > > > > > > > > > */ > > > > > > > > > > - private static int findAnyZero(float[] a, int low, > > int high) { > > > > > > > > > > - while (true) { > > > > > > > > > > + private static int findFirstZero(float[] a, int low, > > int high) { > > > > > > > > > > + while (low < high) { > > > > > > > > > > int middle = (low + high) >>> 1; > > > > > > > > > > float middleValue = a[middle]; > > > > > > > > > > > > > > > > > > > > if (middleValue < 0.0f) { > > > > > > > > > > low = middle + 1; > > > > > > > > > > - } else if (middleValue > 0.0f) { > > > > > > > > > > - high = middle - 1; > > > > > > > > > > - } else { // middleValue == 0.0f > > > > > > > > > > - return middle; > > > > > > > > > > + } else { // middleValue >= 0.0f > > > > > > > > > > + high = middle; > > > > > > > > > > } > > > > > > > > > > + return low; > > > > > > > > > > } > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > Counting negative values appeared more expensive than > > any other > > > > > > variants. > > > > > > > > > > The last proposal seems to me as efficient as the current > > > > > > solution is in its worst case - when we have only one negative > > zero (in > > > > > > the half of array). > > > > > > > > > > And it shows the best result if we have many zeros. > > > > > > > > > > > > > > > > > > > > Regards, > > > > > > > > > > Dmytro Sheyko > > > > > > > > > > > > > > > > > > > > > From: iaroslavski at mail.ru > > > > > > > > > > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > > > > > > > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > > > > > > > > > Subject: Re[2]: New portion of improvements for > > Dual-Pivot > > > > > > Quicksort > > > > > > > > > > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > > > > > > > > > > > > > > > > > > > > Josh, > > > > > > > > > > > Dmytro, > > > > > > > > > > > > > > > > > > > > > > I have done more thoroughly testing "great - less > 5 * > > > > > > seventh" vs. "less < e1 && great > e5", > > > > > > > > > > > and found that more symmetric code "less < e1 && > > great > e5" > > > > > > is little bit faster, ~0.5..0.7% > > > > > > > > > > > on both VMs. Other code has not been changed. > > > > > > > > > > > > > > > > > > > > > > Please, take the latest version in attachment. > > > > > > > > > > > > > > > > > > > > > > Vladimir > > > > > > > > > > > > > > > > > > > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua Bloch > > > > > > : > > > > > > > > > > > > > > > > > > > > > > > Vladimir, > > > > > > > > > > > > > > > > > > > > > > > > Old: > > > > > > > > > > > > > > > > > > > > > > > >298 if (less < e1 && great > e5) { > > > > > > > > > > > > > > > > > > > > > > > > New: > > > > > > > > > > > > > > > > > > > > > > > >256 if (great - less > 5 * seventh) { > > > > > > > > > > > > > > > > > > > > > > >Regards, > > > > > > > > > > > >Josh _________________________________________________________________ Hotmail: Trusted email with powerful SPAM protection. https://signup.live.com/signup.aspx?id=60969 -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Wed May 19 10:09:57 2010 From: forax at univ-mlv.fr (=?UTF-8?B?UsOpbWkgRm9yYXg=?=) Date: Wed, 19 May 2010 12:09:57 +0200 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: , , , <4BF2AAEE.1040706@mail.ru> Message-ID: <4BF3B8F5.1010409@univ-mlv.fr> Le 19/05/2010 11:02, Dmytro Sheyko a ?crit : > Vladimir, > > I can see that you changed sortNegZeroAndNaN(float[]...) but probably > forgot to change sortNegZeroAndNaN(double[]...). > > You really puzzled me with failed testcase and note that sorting > algorithm (without special attention to zeros) generally may change > number of negative zeros. > I will provide my comments later. > > As for counting sort, I think we should use single format style over > the file (unless we have valuable reason not to do this). I mean to choose > 1) > if (toIndex - fromIndex > > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > countingSort(a, fromIndex, toIndex); > return; > } > sort(a, fromIndex, toIndex - 1, true); > 2) > if (toIndex - fromIndex > > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > countingSort(a, fromIndex, toIndex); > } else { > sort(a, fromIndex, toIndex - 1, true); > } > I prefer the second one. > > Thanks a lot, > Dmytro Sheyko But the former have a more compact bytecode representation (return vs goto) and avoid an unecessary jump for interpreters. R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From iaroslavski at mail.ru Wed May 19 10:39:57 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Wed, 19 May 2010 14:39:57 +0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: <4BF2AAEE.1040706@mail.ru> Message-ID: <4BF3BFFD.8010007@mail.ru> Dmytro, Thank you for comments, I updated double method, did little bit javadoc changes and replaced in char/short/byte methods "fromIndex -> left", "toIndex-1 -> right", the code became consistent with main sort method and more compact. Also I use more usual "i--" and "i++" in for loops (instead of "--i", "++i. To accent the difference between float/double and other types, I put comment where it is important: /* * In spite of a[great] == pivot1, the assignment * a[less++] = pivot1 may be incorrect, if a[great] * and pivot1 are floating-point zeros of different * signs, therefore in float/double methods we have * to use more accurate assignment a[k] = a[great]. */ a[less++] = pivot1; and for double/float: /* ..... */ a[k] = a[great]; See updated version in attachment. Thank you, Vladimir Dmytro Sheyko wrote: > Vladimir, > > I can see that you changed sortNegZeroAndNaN(float[]...) but probably > forgot to change sortNegZeroAndNaN(double[]...). > > You really puzzled me with failed testcase and note that sorting > algorithm (without special attention to zeros) generally may change > number of negative zeros. > I will provide my comments later. > > As for counting sort, I think we should use single format style over the > file (unless we have valuable reason not to do this). I mean to choose > 1) > if (toIndex - fromIndex > > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > countingSort(a, fromIndex, toIndex); > return; > } > sort(a, fromIndex, toIndex - 1, true); > 2) > if (toIndex - fromIndex > > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > countingSort(a, fromIndex, toIndex); > } else { > sort(a, fromIndex, toIndex - 1, true); > } > I prefer the second one. > > Thanks a lot, > Dmytro Sheyko > > > Date: Tue, 18 May 2010 18:57:50 +0400 > > From: iaroslavski at mail.ru > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > To: dmytro_sheyko at hotmail.com > > CC: core-libs-dev at openjdk.java.net > > > > Hello, > > > > I've run your modification for counting sort, it real faster. > > I attached new version with your changes (I did little bit > > format it) and included my case with float/double. > > > > Note that you modification doesn't pass test from Sorting class, > > which I sent earlier. It fails on float/double test: > > > > Test #3: random = 666, len = 34, a = 0, g = 6, z = 9, n = 10, p = 9 > > > > I suggest shorter method (which is based on your idea to skip counting > > negative zeros on Phase 1.): I found find first zero index (or it will > > be index of first positive element if no zeros at all, or last negative, > > if no positive and zero elements) and then swap negative zero to the > > beginning of the sub-range. > > > > int hi = right; > > > > while (left < hi) { > > int middle = (left + hi) >>> 1; > > float middleValue = a[middle]; > > > > if (middleValue < 0.0f) { > > left = middle + 1; > > } else { > > hi = middle; > > } > > } > > > > for (int k = left, p = left; k <= right; k++) { > > float ak = a[k]; > > if (ak != 0.0f) { > > return; > > } > > if (Float.floatToRawIntBits(ak) < 0) { // ak is -0.0f > > a[k] = +0.0f; > > a[p++] = -0.0f; > > } > > } > > > > Important note: in partitioning loop there are several places > > (marked by // !) where potential bug with -0.0 could be > > (when pivot and a[great] are zeros with different signs): > > > > if (a[great] == pivot1) { > > a[k] = a[less]; > > - a[less++] = pivot1; // ! > > + a[less++] = a[great]; > > } else { // pivot1 < a[great] < pivot2 > > a[k] = a[great]; > > } > > - a[great--] = pivot2; // ! > > + a[great--] = ak; > > } else if (ak == pivot1) { // Move a[k] to left part > > a[k] = a[less]; > > - a[less++] = pivot1; // ! > > + a[less++] = ak; > > } > > > > and the same in "Pivots are equal" branch. > > > > I did changes "pivot1/2 -> ak" in methods for all types > > and "pivot1 -> a[great]" in float/double sections only. > > > > Please, review format changes for counting sort and new version > > of Phase 3 for float/double. > > > > Thank you, > > Vladimir > > > > Dmytro Sheyko wrote: > > > Hi, > > > > > > About counting sort again. > > > > > > 1. This condition "i < count.length && k <= right" is excessive. > Any one > > > conjunct is enough. "k <= right" seems better. > > > 2. No need to calculate "short value = (short) (i + Short.MIN_VALUE)" > > > when "count[i]" is zero. > > > 3. For signed primitives (byte and short) we would better loop > backward. > > > Thanks to "k >= fromIndex" condition we will quit looping earlier > > > assuming that typically we work with positive numbers. > > > For unsigned primitives (char) we would better loop forward because > > > typically we work with characters about zero (ASCII). > > > > > > - for (int i = 0, k = left; i < count.length && k <= right; i++) { > > > - short value = (short) (i + Short.MIN_VALUE); > > > - for (int s = count[i]; s > 0; s--) { > > > - a[k++] = value; > > > - } > > > - } > > > > > > + for (int i = NUM_SHORT_VALUES - 1, k = toIndex - 1; k >= > > > fromIndex; --i) { > > > + while (count[i] == 0) --i; > > > + short value = (short) (i + Short.MIN_VALUE); > > > + int s = count[i]; > > > + do { a[k--] = value; } while (--s > 0); > > > + } > > > > > > Thanks, > > > Dmytro Sheyko > > > > > > > From: iaroslavski at mail.ru > > > > To: dmytro_sheyko at hotmail.com > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > > Subject: Re[2]: New portion of improvements for Dual-Pivot Quicksort > > > > Date: Tue, 18 May 2010 01:11:19 +0400 > > > > > > > > Sounds good! > > > > Will consider too... > > > > > > > > Mon, 17 May 2010 22:24:11 +0700 ?????? ?? Dmytro Sheyko > > > : > > > > > > > > > Hi, > > > > > > > > > > Regarding counting sort. We can check whether we should switch to > > > counting sort only once in the beginning. > > > > > > > > > > > Date: Mon, 17 May 2010 17:30:37 +0400 > > > > > > From: iaroslavski at mail.ru > > > > > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > > > > > To: dmytro_sheyko at hotmail.com > > > > > > CC: core-libs-dev at openjdk.java.net > > > > > > > > > > > > Hello, > > > > > > > > > > > > Thank you for review, I'll check and run tests again with you > > > changes. > > > > > > > > > > > > Thank you, > > > > > > Vladimir > > > > > > > > > > > > Dmytro Sheyko wrote: > > > > > > > Hello, > > > > > > > > > > > > > > More ideas. > > > > > > > > > > > > > > 1. We can use > > > > > > > Double.doubleToRawLongBits instead of > Double.doubleToLongBits and > > > > > > > Float.floatToRawIntBits instead of Float.floatToIntBits. > > > > > > > No need to handle NaN's because they all are placed to the end > > > of array. > > > > > > > > > > > > > > 2. Note that > > > > > > > Double.doubleToRawLongBits(+0.0) == 0L and > > > > > > > Double.doubleToRawLongBits(-0.0) == Long.MIN_VALUE and > > > > > > > Float.floatToRawIntBits(+0.0) == 0 and > > > > > > > Float.floatToRawIntBits(-0.0) == Integer.MIN_VALUE. > > > > > > > > > > > > > > Comparing with is zero usually more efficient (or at least not > > > worse) > > > > > > > than with other values. Thus such pattern > > > > > > > > > > > > > > if (ak == 0.0f && NEGATIVE_ZERO == Float.floatToIntBits(ak)) > > > > > > > > > > > > > > can be replaced with > > > > > > > > > > > > > > if (ak == 0.0f && Float.floatToIntBits(ak) < 0) > > > > > > > > > > > > > > 3. It would be more efficient to count negative zeros after > > > sorting. > > > > > > > General sorting algorithm puts both negative and positive > zeros > > > together > > > > > > > (but maybe not in right order). > > > > > > > Therefore we have to process less elements because usually we > > > have less > > > > > > > zeros than other numbers. > > > > > > > > > > > > > > Thanks, > > > > > > > Dmytro Sheyko > > > > > > > > > > > > > > > From: iaroslavski at mail.ru > > > > > > > > To: dmytro_sheyko at hotmail.com; jjb at google.com > > > > > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > > > > > > Subject: Re[6]: New portion of improvements for Dual-Pivot > > > Quicksort > > > > > > > > Date: Fri, 14 May 2010 23:54:06 +0400 > > > > > > > > > > > > > > > > Hello, > > > > > > > > > > > > > > > > I've updated the class, please, review the changes. > > > > > > > > > > > > > > > > Vladimir > > > > > > > > > > > > > > > > Fri, 14 May 2010 01:48:11 +0700 ?????? ?? Dmytro Sheyko > > > > > > > : > > > > > > > > > > > > > > > > > Yes. I prefer F (Find First zero using binary search) over > > > C (Count > > > > > > > negatives) and S (Smart Scan for zero). > > > > > > > > > > > > > > > > > > > From: iaroslavski at mail.ru > > > > > > > > > > To: dmytro_sheyko at hotmail.com > > > > > > > > > > CC: jjb at google.com; core-libs-dev at openjdk.java.net; > > > > > > > iaroslavski at mail.ru > > > > > > > > > > Subject: Re[4]: New portion of improvements for > > > Dual-Pivot Quicksort > > > > > > > > > > Date: Thu, 13 May 2010 21:34:54 +0400 > > > > > > > > > > > > > > > > > > > > Dmytro, > > > > > > > > > > > > > > > > > > > > I've tested your suggested variants, and found that > case "C" > > > > > > > > > > (very interesting approach to find first position of zero > > > > > > > > > > by counting negative elements) works slower than original > > > > > > > > > > or two other cases. > > > > > > > > > > > > > > > > > > > > Implementations "F" and "S" are very close to each other > > > > > > > > > > and little bit faster than original. I prefer case "F": > > > > > > > > > > it is shorter and more clear. Do you agree? > > > > > > > > > > > > > > > > > > > > I'll prepare updated DualPivotQuicksort file and send it > > > > > > > > > > tomorrow. > > > > > > > > > > > > > > > > > > > > Thank you, > > > > > > > > > > Vladimir > > > > > > > > > > > > > > > > > > > > Wed, 12 May 2010 17:04:52 +0700 ?????? ?? Dmytro Sheyko > > > > > > > : > > > > > > > > > > > > > > > > > > > > > Vladimir, > > > > > > > > > > > > > > > > > > > > > > Your changes are good for me. > > > > > > > > > > > > > > > > > > > > > > Additionally I have some comments/proposals regarding > > > dealing > > > > > > > with negative zeros. > > > > > > > > > > > > > > > > > > > > > > 1. Scanning for the first zero we can avoid range > check > > > (i >= > > > > > > > left) if we have at least one negative value. > > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > > > > > > > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 2010 > > > > > > > > > > > @@ -1705,10 +1705,15 @@ > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > // Find first zero element > > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > > > > > > + int zeroIndex = 0; > > > > > > > > > > > > > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == > > > 0.0f; i--) { > > > > > > > > > > > - zeroIndex = i; > > > > > > > > > > > + if (a[left] < 0.0f) { > > > > > > > > > > > + zeroIndex = findAnyZero(a, left, n); > > > > > > > > > > > + > > > > > > > > > > > + // there is at least one negative value, so range > > > check is > > > > > > > not needed > > > > > > > > > > > + for (int i = zeroIndex - 1; /*i >= left &&*/ a[i] == > > > 0.0f; i--) { > > > > > > > > > > > + zeroIndex = i; > > > > > > > > > > > + } > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > // Turn the right number of positive zeros back into > > > negative zeros > > > > > > > > > > > > > > > > > > > > > > 2. We can find the position of the first zero by > counting > > > > > > > negative values during preprocessing phase. > > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > > > > > > > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 2010 > > > > > > > > > > > @@ -1678,7 +1678,7 @@ > > > > > > > > > > > * Phase 1: Count negative zeros and move NaNs to > end of > > > array. > > > > > > > > > > > */ > > > > > > > > > > > final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f); > > > > > > > > > > > - int numNegativeZeros = 0; > > > > > > > > > > > + int numNegativeZeros = 0, numNegativeValues = 0; > > > > > > > > > > > int n = right; > > > > > > > > > > > > > > > > > > > > > > for (int k = left; k <= n; k++) { > > > > > > > > > > > @@ -1689,6 +1689,8 @@ > > > > > > > > > > > } else if (ak != ak) { // i.e., ak is NaN > > > > > > > > > > > a[k--] = a[n]; > > > > > > > > > > > a[n--] = Float.NaN; > > > > > > > > > > > + } else if (ak < 0.0f) { > > > > > > > > > > > + numNegativeValues++; > > > > > > > > > > > } > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > @@ -1705,7 +1707,7 @@ > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > // Find first zero element > > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > > > > > > + int zeroIndex = numNegativeValues; > > > > > > > > > > > > > > > > > > > > > > for (int i = zeroIndex - 1; i >= left && a[i] == 0.0f; > > > i--) { > > > > > > > > > > > zeroIndex = i; > > > > > > > > > > > > > > > > > > > > > > 3. We can use binary search to find the first zero and > > > thus > > > > > > > avoid linear scan. > > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > > > > > > > > > > > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 2010 > > > > > > > > > > > @@ -1705,11 +1705,7 @@ > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > // Find first zero element > > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > > > > > > - > > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == > > > 0.0f; i--) { > > > > > > > > > > > - zeroIndex = i; > > > > > > > > > > > - } > > > > > > > > > > > + int zeroIndex = findFirstZero(a, left, n); > > > > > > > > > > > > > > > > > > > > > > // Turn the right number of positive zeros back into > > > negative zeros > > > > > > > > > > > for (int i = zeroIndex, m = zeroIndex + > > > numNegativeZeros; i < > > > > > > > m; i++) { > > > > > > > > > > > @@ -1718,7 +1714,7 @@ > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > - * Returns the index of some zero element in the > > > specified > > > > > > > range via > > > > > > > > > > > + * Returns the index of the first zero element in the > > > > > > > specified range via > > > > > > > > > > > * binary search. The range is assumed to be sorted, > and > > > must > > > > > > > contain > > > > > > > > > > > * at least one zero. > > > > > > > > > > > * > > > > > > > > > > > @@ -1726,18 +1722,17 @@ > > > > > > > > > > > * @param low the index of the first element, > inclusive, > > > to be > > > > > > > searched > > > > > > > > > > > * @param high the index of the last element, > inclusive, > > > to be > > > > > > > searched > > > > > > > > > > > */ > > > > > > > > > > > - private static int findAnyZero(float[] a, int low, > > > int high) { > > > > > > > > > > > - while (true) { > > > > > > > > > > > + private static int findFirstZero(float[] a, int low, > > > int high) { > > > > > > > > > > > + while (low < high) { > > > > > > > > > > > int middle = (low + high) >>> 1; > > > > > > > > > > > float middleValue = a[middle]; > > > > > > > > > > > > > > > > > > > > > > if (middleValue < 0.0f) { > > > > > > > > > > > low = middle + 1; > > > > > > > > > > > - } else if (middleValue > 0.0f) { > > > > > > > > > > > - high = middle - 1; > > > > > > > > > > > - } else { // middleValue == 0.0f > > > > > > > > > > > - return middle; > > > > > > > > > > > + } else { // middleValue >= 0.0f > > > > > > > > > > > + high = middle; > > > > > > > > > > > } > > > > > > > > > > > + return low; > > > > > > > > > > > } > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > Counting negative values appeared more expensive than > > > any other > > > > > > > variants. > > > > > > > > > > > The last proposal seems to me as efficient as the > current > > > > > > > solution is in its worst case - when we have only one negative > > > zero (in > > > > > > > the half of array). > > > > > > > > > > > And it shows the best result if we have many zeros. > > > > > > > > > > > > > > > > > > > > > > Regards, > > > > > > > > > > > Dmytro Sheyko > > > > > > > > > > > > > > > > > > > > > > > From: iaroslavski at mail.ru > > > > > > > > > > > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > > > > > > > > > > > CC: core-libs-dev at openjdk.java.net; > iaroslavski at mail.ru > > > > > > > > > > > > Subject: Re[2]: New portion of improvements for > > > Dual-Pivot > > > > > > > Quicksort > > > > > > > > > > > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > > > > > > > > > > > > > > > > > > > > > > Josh, > > > > > > > > > > > > Dmytro, > > > > > > > > > > > > > > > > > > > > > > > > I have done more thoroughly testing "great - less > > 5 * > > > > > > > seventh" vs. "less < e1 && great > e5", > > > > > > > > > > > > and found that more symmetric code "less < e1 && > > > great > e5" > > > > > > > is little bit faster, ~0.5..0.7% > > > > > > > > > > > > on both VMs. Other code has not been changed. > > > > > > > > > > > > > > > > > > > > > > > > Please, take the latest version in attachment. > > > > > > > > > > > > > > > > > > > > > > > > Vladimir > > > > > > > > > > > > > > > > > > > > > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua Bloch > > > > > > > : > > > > > > > > > > > > > > > > > > > > > > > > > Vladimir, > > > > > > > > > > > > > > > > > > > > > > > > > > Old: > > > > > > > > > > > > > > > > > > > > > > > > > >298 if (less < e1 && great > e5) { > > > > > > > > > > > > > > > > > > > > > > > > > > New: > > > > > > > > > > > > > > > > > > > > > > > > > >256 if (great - less > 5 * seventh) { > > > > > > > > > > > > > > > > > > > > > > > > >Regards, > > > > > > > > > > > > >Josh -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: DualPivotQuicksort.java URL: From iaroslavski at mail.ru Wed May 19 10:41:32 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Wed, 19 May 2010 14:41:32 +0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: <4BF3BFFD.8010007@mail.ru> References: <4BF2AAEE.1040706@mail.ru> <4BF3BFFD.8010007@mail.ru> Message-ID: <4BF3C05C.7010300@mail.ru> resend the class with correct constructor Vladimir Iaroslavski wrote: > Dmytro, > > Thank you for comments, I updated double method, did little bit > javadoc changes and replaced in char/short/byte methods > "fromIndex -> left", "toIndex-1 -> right", the code became > consistent with main sort method and more compact. Also I use > more usual "i--" and "i++" in for loops (instead of "--i", "++i. > > To accent the difference between float/double and other types, > I put comment where it is important: > > /* > * In spite of a[great] == pivot1, the assignment > * a[less++] = pivot1 may be incorrect, if a[great] > * and pivot1 are floating-point zeros of different > * signs, therefore in float/double methods we have > * to use more accurate assignment a[k] = a[great]. > */ > a[less++] = pivot1; > > and for double/float: > > /* > ..... > */ > a[k] = a[great]; > > See updated version in attachment. > > Thank you, > Vladimir > > Dmytro Sheyko wrote: >> Vladimir, >> >> I can see that you changed sortNegZeroAndNaN(float[]...) but probably >> forgot to change sortNegZeroAndNaN(double[]...). >> >> You really puzzled me with failed testcase and note that sorting >> algorithm (without special attention to zeros) generally may change >> number of negative zeros. >> I will provide my comments later. >> >> As for counting sort, I think we should use single format style over >> the file (unless we have valuable reason not to do this). I mean to >> choose >> 1) >> if (toIndex - fromIndex > >> COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { >> countingSort(a, fromIndex, toIndex); >> return; >> } >> sort(a, fromIndex, toIndex - 1, true); >> 2) >> if (toIndex - fromIndex > >> COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { >> countingSort(a, fromIndex, toIndex); >> } else { >> sort(a, fromIndex, toIndex - 1, true); >> } >> I prefer the second one. >> >> Thanks a lot, >> Dmytro Sheyko >> >> > Date: Tue, 18 May 2010 18:57:50 +0400 >> > From: iaroslavski at mail.ru >> > Subject: Re: New portion of improvements for Dual-Pivot Quicksort >> > To: dmytro_sheyko at hotmail.com >> > CC: core-libs-dev at openjdk.java.net >> > >> > Hello, >> > >> > I've run your modification for counting sort, it real faster. >> > I attached new version with your changes (I did little bit >> > format it) and included my case with float/double. >> > >> > Note that you modification doesn't pass test from Sorting class, >> > which I sent earlier. It fails on float/double test: >> > >> > Test #3: random = 666, len = 34, a = 0, g = 6, z = 9, n = 10, p = 9 >> > >> > I suggest shorter method (which is based on your idea to skip counting >> > negative zeros on Phase 1.): I found find first zero index (or it will >> > be index of first positive element if no zeros at all, or last >> negative, >> > if no positive and zero elements) and then swap negative zero to the >> > beginning of the sub-range. >> > >> > int hi = right; >> > >> > while (left < hi) { >> > int middle = (left + hi) >>> 1; >> > float middleValue = a[middle]; >> > >> > if (middleValue < 0.0f) { >> > left = middle + 1; >> > } else { >> > hi = middle; >> > } >> > } >> > >> > for (int k = left, p = left; k <= right; k++) { >> > float ak = a[k]; >> > if (ak != 0.0f) { >> > return; >> > } >> > if (Float.floatToRawIntBits(ak) < 0) { // ak is -0.0f >> > a[k] = +0.0f; >> > a[p++] = -0.0f; >> > } >> > } >> > >> > Important note: in partitioning loop there are several places >> > (marked by // !) where potential bug with -0.0 could be >> > (when pivot and a[great] are zeros with different signs): >> > >> > if (a[great] == pivot1) { >> > a[k] = a[less]; >> > - a[less++] = pivot1; // ! >> > + a[less++] = a[great]; >> > } else { // pivot1 < a[great] < pivot2 >> > a[k] = a[great]; >> > } >> > - a[great--] = pivot2; // ! >> > + a[great--] = ak; >> > } else if (ak == pivot1) { // Move a[k] to left part >> > a[k] = a[less]; >> > - a[less++] = pivot1; // ! >> > + a[less++] = ak; >> > } >> > >> > and the same in "Pivots are equal" branch. >> > >> > I did changes "pivot1/2 -> ak" in methods for all types >> > and "pivot1 -> a[great]" in float/double sections only. >> > >> > Please, review format changes for counting sort and new version >> > of Phase 3 for float/double. >> > >> > Thank you, >> > Vladimir >> > >> > Dmytro Sheyko wrote: >> > > Hi, >> > > >> > > About counting sort again. >> > > >> > > 1. This condition "i < count.length && k <= right" is excessive. >> Any one >> > > conjunct is enough. "k <= right" seems better. >> > > 2. No need to calculate "short value = (short) (i + >> Short.MIN_VALUE)" >> > > when "count[i]" is zero. >> > > 3. For signed primitives (byte and short) we would better loop >> backward. >> > > Thanks to "k >= fromIndex" condition we will quit looping earlier >> > > assuming that typically we work with positive numbers. >> > > For unsigned primitives (char) we would better loop forward because >> > > typically we work with characters about zero (ASCII). >> > > >> > > - for (int i = 0, k = left; i < count.length && k <= right; i++) { >> > > - short value = (short) (i + Short.MIN_VALUE); >> > > - for (int s = count[i]; s > 0; s--) { >> > > - a[k++] = value; >> > > - } >> > > - } >> > > >> > > + for (int i = NUM_SHORT_VALUES - 1, k = toIndex - 1; k >= >> > > fromIndex; --i) { >> > > + while (count[i] == 0) --i; >> > > + short value = (short) (i + Short.MIN_VALUE); >> > > + int s = count[i]; >> > > + do { a[k--] = value; } while (--s > 0); >> > > + } >> > > >> > > Thanks, >> > > Dmytro Sheyko >> > > >> > > > From: iaroslavski at mail.ru >> > > > To: dmytro_sheyko at hotmail.com >> > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru >> > > > Subject: Re[2]: New portion of improvements for Dual-Pivot >> Quicksort >> > > > Date: Tue, 18 May 2010 01:11:19 +0400 >> > > > >> > > > Sounds good! >> > > > Will consider too... >> > > > >> > > > Mon, 17 May 2010 22:24:11 +0700 ?????? ?? Dmytro Sheyko >> > > : >> > > > >> > > > > Hi, >> > > > > >> > > > > Regarding counting sort. We can check whether we should >> switch to >> > > counting sort only once in the beginning. >> > > > > >> > > > > > Date: Mon, 17 May 2010 17:30:37 +0400 >> > > > > > From: iaroslavski at mail.ru >> > > > > > Subject: Re: New portion of improvements for Dual-Pivot >> Quicksort >> > > > > > To: dmytro_sheyko at hotmail.com >> > > > > > CC: core-libs-dev at openjdk.java.net >> > > > > > >> > > > > > Hello, >> > > > > > >> > > > > > Thank you for review, I'll check and run tests again with you >> > > changes. >> > > > > > >> > > > > > Thank you, >> > > > > > Vladimir >> > > > > > >> > > > > > Dmytro Sheyko wrote: >> > > > > > > Hello, >> > > > > > > >> > > > > > > More ideas. >> > > > > > > >> > > > > > > 1. We can use >> > > > > > > Double.doubleToRawLongBits instead of >> Double.doubleToLongBits and >> > > > > > > Float.floatToRawIntBits instead of Float.floatToIntBits. >> > > > > > > No need to handle NaN's because they all are placed to >> the end >> > > of array. >> > > > > > > >> > > > > > > 2. Note that >> > > > > > > Double.doubleToRawLongBits(+0.0) == 0L and >> > > > > > > Double.doubleToRawLongBits(-0.0) == Long.MIN_VALUE and >> > > > > > > Float.floatToRawIntBits(+0.0) == 0 and >> > > > > > > Float.floatToRawIntBits(-0.0) == Integer.MIN_VALUE. >> > > > > > > >> > > > > > > Comparing with is zero usually more efficient (or at >> least not >> > > worse) >> > > > > > > than with other values. Thus such pattern >> > > > > > > >> > > > > > > if (ak == 0.0f && NEGATIVE_ZERO == Float.floatToIntBits(ak)) >> > > > > > > >> > > > > > > can be replaced with >> > > > > > > >> > > > > > > if (ak == 0.0f && Float.floatToIntBits(ak) < 0) >> > > > > > > >> > > > > > > 3. It would be more efficient to count negative zeros after >> > > sorting. >> > > > > > > General sorting algorithm puts both negative and positive >> zeros >> > > together >> > > > > > > (but maybe not in right order). >> > > > > > > Therefore we have to process less elements because >> usually we >> > > have less >> > > > > > > zeros than other numbers. >> > > > > > > >> > > > > > > Thanks, >> > > > > > > Dmytro Sheyko >> > > > > > > >> > > > > > > > From: iaroslavski at mail.ru >> > > > > > > > To: dmytro_sheyko at hotmail.com; jjb at google.com >> > > > > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru >> > > > > > > > Subject: Re[6]: New portion of improvements for Dual-Pivot >> > > Quicksort >> > > > > > > > Date: Fri, 14 May 2010 23:54:06 +0400 >> > > > > > > > >> > > > > > > > Hello, >> > > > > > > > >> > > > > > > > I've updated the class, please, review the changes. >> > > > > > > > >> > > > > > > > Vladimir >> > > > > > > > >> > > > > > > > Fri, 14 May 2010 01:48:11 +0700 ?????? ?? Dmytro Sheyko >> > > > > > > : >> > > > > > > > >> > > > > > > > > Yes. I prefer F (Find First zero using binary search) >> over >> > > C (Count >> > > > > > > negatives) and S (Smart Scan for zero). >> > > > > > > > > >> > > > > > > > > > From: iaroslavski at mail.ru >> > > > > > > > > > To: dmytro_sheyko at hotmail.com >> > > > > > > > > > CC: jjb at google.com; core-libs-dev at openjdk.java.net; >> > > > > > > iaroslavski at mail.ru >> > > > > > > > > > Subject: Re[4]: New portion of improvements for >> > > Dual-Pivot Quicksort >> > > > > > > > > > Date: Thu, 13 May 2010 21:34:54 +0400 >> > > > > > > > > > >> > > > > > > > > > Dmytro, >> > > > > > > > > > >> > > > > > > > > > I've tested your suggested variants, and found that >> case "C" >> > > > > > > > > > (very interesting approach to find first position >> of zero >> > > > > > > > > > by counting negative elements) works slower than >> original >> > > > > > > > > > or two other cases. >> > > > > > > > > > >> > > > > > > > > > Implementations "F" and "S" are very close to each >> other >> > > > > > > > > > and little bit faster than original. I prefer case >> "F": >> > > > > > > > > > it is shorter and more clear. Do you agree? >> > > > > > > > > > >> > > > > > > > > > I'll prepare updated DualPivotQuicksort file and >> send it >> > > > > > > > > > tomorrow. >> > > > > > > > > > >> > > > > > > > > > Thank you, >> > > > > > > > > > Vladimir >> > > > > > > > > > >> > > > > > > > > > Wed, 12 May 2010 17:04:52 +0700 ?????? ?? Dmytro >> Sheyko >> > > > > > > : >> > > > > > > > > > >> > > > > > > > > > > Vladimir, >> > > > > > > > > > > >> > > > > > > > > > > Your changes are good for me. >> > > > > > > > > > > >> > > > > > > > > > > Additionally I have some comments/proposals >> regarding >> > > dealing >> > > > > > > with negative zeros. >> > > > > > > > > > > >> > > > > > > > > > > 1. Scanning for the first zero we can avoid range >> check >> > > (i >= >> > > > > > > left) if we have at least one negative value. >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 >> > > > > > > > > > > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 >> 2010 >> > > > > > > > > > > @@ -1705,10 +1705,15 @@ >> > > > > > > > > > > } >> > > > > > > > > > > >> > > > > > > > > > > // Find first zero element >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); >> > > > > > > > > > > + int zeroIndex = 0; >> > > > > > > > > > > >> > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == >> > > 0.0f; i--) { >> > > > > > > > > > > - zeroIndex = i; >> > > > > > > > > > > + if (a[left] < 0.0f) { >> > > > > > > > > > > + zeroIndex = findAnyZero(a, left, n); >> > > > > > > > > > > + >> > > > > > > > > > > + // there is at least one negative value, so range >> > > check is >> > > > > > > not needed >> > > > > > > > > > > + for (int i = zeroIndex - 1; /*i >= left &&*/ >> a[i] == >> > > 0.0f; i--) { >> > > > > > > > > > > + zeroIndex = i; >> > > > > > > > > > > + } >> > > > > > > > > > > } >> > > > > > > > > > > >> > > > > > > > > > > // Turn the right number of positive zeros back into >> > > negative zeros >> > > > > > > > > > > >> > > > > > > > > > > 2. We can find the position of the first zero by >> counting >> > > > > > > negative values during preprocessing phase. >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 >> > > > > > > > > > > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 >> 2010 >> > > > > > > > > > > @@ -1678,7 +1678,7 @@ >> > > > > > > > > > > * Phase 1: Count negative zeros and move NaNs to >> end of >> > > array. >> > > > > > > > > > > */ >> > > > > > > > > > > final int NEGATIVE_ZERO = >> Float.floatToIntBits(-0.0f); >> > > > > > > > > > > - int numNegativeZeros = 0; >> > > > > > > > > > > + int numNegativeZeros = 0, numNegativeValues = 0; >> > > > > > > > > > > int n = right; >> > > > > > > > > > > >> > > > > > > > > > > for (int k = left; k <= n; k++) { >> > > > > > > > > > > @@ -1689,6 +1689,8 @@ >> > > > > > > > > > > } else if (ak != ak) { // i.e., ak is NaN >> > > > > > > > > > > a[k--] = a[n]; >> > > > > > > > > > > a[n--] = Float.NaN; >> > > > > > > > > > > + } else if (ak < 0.0f) { >> > > > > > > > > > > + numNegativeValues++; >> > > > > > > > > > > } >> > > > > > > > > > > } >> > > > > > > > > > > >> > > > > > > > > > > @@ -1705,7 +1707,7 @@ >> > > > > > > > > > > } >> > > > > > > > > > > >> > > > > > > > > > > // Find first zero element >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); >> > > > > > > > > > > + int zeroIndex = numNegativeValues; >> > > > > > > > > > > >> > > > > > > > > > > for (int i = zeroIndex - 1; i >= left && a[i] == >> 0.0f; >> > > i--) { >> > > > > > > > > > > zeroIndex = i; >> > > > > > > > > > > >> > > > > > > > > > > 3. We can use binary search to find the first >> zero and >> > > thus >> > > > > > > avoid linear scan. >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 >> > > > > > > > > > > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 >> 2010 >> > > > > > > > > > > @@ -1705,11 +1705,7 @@ >> > > > > > > > > > > } >> > > > > > > > > > > >> > > > > > > > > > > // Find first zero element >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); >> > > > > > > > > > > - >> > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == >> > > 0.0f; i--) { >> > > > > > > > > > > - zeroIndex = i; >> > > > > > > > > > > - } >> > > > > > > > > > > + int zeroIndex = findFirstZero(a, left, n); >> > > > > > > > > > > >> > > > > > > > > > > // Turn the right number of positive zeros back into >> > > negative zeros >> > > > > > > > > > > for (int i = zeroIndex, m = zeroIndex + >> > > numNegativeZeros; i < >> > > > > > > m; i++) { >> > > > > > > > > > > @@ -1718,7 +1714,7 @@ >> > > > > > > > > > > } >> > > > > > > > > > > >> > > > > > > > > > > /** >> > > > > > > > > > > - * Returns the index of some zero element in the >> > > specified >> > > > > > > range via >> > > > > > > > > > > + * Returns the index of the first zero element >> in the >> > > > > > > specified range via >> > > > > > > > > > > * binary search. The range is assumed to be >> sorted, and >> > > must >> > > > > > > contain >> > > > > > > > > > > * at least one zero. >> > > > > > > > > > > * >> > > > > > > > > > > @@ -1726,18 +1722,17 @@ >> > > > > > > > > > > * @param low the index of the first element, >> inclusive, >> > > to be >> > > > > > > searched >> > > > > > > > > > > * @param high the index of the last element, >> inclusive, >> > > to be >> > > > > > > searched >> > > > > > > > > > > */ >> > > > > > > > > > > - private static int findAnyZero(float[] a, int low, >> > > int high) { >> > > > > > > > > > > - while (true) { >> > > > > > > > > > > + private static int findFirstZero(float[] a, int >> low, >> > > int high) { >> > > > > > > > > > > + while (low < high) { >> > > > > > > > > > > int middle = (low + high) >>> 1; >> > > > > > > > > > > float middleValue = a[middle]; >> > > > > > > > > > > >> > > > > > > > > > > if (middleValue < 0.0f) { >> > > > > > > > > > > low = middle + 1; >> > > > > > > > > > > - } else if (middleValue > 0.0f) { >> > > > > > > > > > > - high = middle - 1; >> > > > > > > > > > > - } else { // middleValue == 0.0f >> > > > > > > > > > > - return middle; >> > > > > > > > > > > + } else { // middleValue >= 0.0f >> > > > > > > > > > > + high = middle; >> > > > > > > > > > > } >> > > > > > > > > > > + return low; >> > > > > > > > > > > } >> > > > > > > > > > > } >> > > > > > > > > > > >> > > > > > > > > > > Counting negative values appeared more expensive >> than >> > > any other >> > > > > > > variants. >> > > > > > > > > > > The last proposal seems to me as efficient as the >> current >> > > > > > > solution is in its worst case - when we have only one >> negative >> > > zero (in >> > > > > > > the half of array). >> > > > > > > > > > > And it shows the best result if we have many zeros. >> > > > > > > > > > > >> > > > > > > > > > > Regards, >> > > > > > > > > > > Dmytro Sheyko >> > > > > > > > > > > >> > > > > > > > > > > > From: iaroslavski at mail.ru >> > > > > > > > > > > > To: jjb at google.com; dmytro_sheyko at hotmail.com >> > > > > > > > > > > > CC: core-libs-dev at openjdk.java.net; >> iaroslavski at mail.ru >> > > > > > > > > > > > Subject: Re[2]: New portion of improvements for >> > > Dual-Pivot >> > > > > > > Quicksort >> > > > > > > > > > > > Date: Sun, 9 May 2010 23:51:27 +0400 >> > > > > > > > > > > > >> > > > > > > > > > > > Josh, >> > > > > > > > > > > > Dmytro, >> > > > > > > > > > > > >> > > > > > > > > > > > I have done more thoroughly testing "great - >> less > 5 * >> > > > > > > seventh" vs. "less < e1 && great > e5", >> > > > > > > > > > > > and found that more symmetric code "less < e1 && >> > > great > e5" >> > > > > > > is little bit faster, ~0.5..0.7% >> > > > > > > > > > > > on both VMs. Other code has not been changed. >> > > > > > > > > > > > >> > > > > > > > > > > > Please, take the latest version in attachment. >> > > > > > > > > > > > >> > > > > > > > > > > > Vladimir >> > > > > > > > > > > > >> > > > > > > > > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua >> Bloch >> > > > > > > : >> > > > > > > > > > > > >> > > > > > > > > > > > > Vladimir, >> > > > > > > > > > > > > >> > > > > > > > > > > > > Old: >> > > > > > > > > > > > > >> > > > > > > > > > > > >298 if (less < e1 && great > e5) { >> > > > > > > > > > > > > >> > > > > > > > > > > > > New: >> > > > > > > > > > > > > >> > > > > > > > > > > > >256 if (great - less > 5 * seventh) { >> > > > > > > > > > > > >> > > > > > > > > > > > >Regards, >> > > > > > > > > > > > >Josh -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: DualPivotQuicksort.java URL: From mbien at fh-landshut.de Wed May 19 18:54:44 2010 From: mbien at fh-landshut.de (Michael Bien) Date: Wed, 19 May 2010 20:54:44 +0200 Subject: signal chaining and self defence Message-ID: <4BF433F4.2090603@fh-landshut.de> Hello Everyone, (sorry for the delay, but something went wrong with my subscription, i haven't noticed that I already got an answer) comments inline... > More info from Hotspot engineers. > > ---- > >Does webstart allow running your own native code in an applet? yes > (Does > plugin while > >So I am guessing that they have java interfaces using the jvm/JIT > > - then gluegen -- how does gluegen work here? Is it precompiled > gluegen generates very thin JNI binding code, its precompiled -> nothing at runtime. but we have basically two modes: static linking against libOpenCL.so or dynamic loading and invocation via function pointers which we currently use for JOGL but not yet for JOCL (except for CL extensions). > or does it do a translation at run time? > no > > - which talks to OpenCL "C" binaries > > - there appear to be a set running on the "host" or main CPU, > > including interfacing to the underlying device drivers, such as > the amd and nvidia drivers mentioned > > - which then can also start OpenCL "C" binaries that run on > auxiliary processors like GPUs > yes thats basically how it works > >So to answer Michael's question from a VM perspective: > > >It appears that the amd and nvidia native drivers that I would guess > they link to in their > >"host" code register for the system signals listed below, but don't > support signal chaining, > >i.e. they are overwriting the jvm's signal handlers. > > >So - the technical solution for that, assuming we can't change the amd > and nvidia drivers, > >is to interpose our libjsig.so before their libraries are loaded. This > lets our vm chain > >their signal handlers, so that the VM only handles signals that apply > to the vm and then > >calls their signal handlers. > > >I am guessing they can't link libjsig with their application or he > would have done so - but > >it is worth first asking why he can't. > Reading the libjsig doc i thought it would not work. my understanding of libjsig: it must be loaded before the most of the JVM starts, thats why there are two options: 1.) LD_PRELOAD=path/to/libjsig 2.) link a custom native JVM launcher against libjsig since webstart does not allow 2.) it won't help. (please correct me if i am wrong here, otherwise the issue is already solved :) ) > >If it is the case that he can not, then he needs to setenv LD_PRELOAD > /libjsig.so > >before starting up java. > > >Is there a way to do that with WebStart? Is there a way to specify to > do that? > No - there is no ability to set any env variables before launching > java. If jnlp file itself is signed and trusted, you could set system > propertys before launching java, but not environmental variables. > exactly thats the issue... dead end regarding webstart. In the meantime i talked to the Nvidia devs and they will try to workaround this issue. Looking at the AMD drivers the situation is not different but for some reasons it appears to run more stable (but this is probably just luck). So we would have to talk to them too and maybe other vendors. Is there a reason why signal chaining is not enabled by default on linux/solaris? If there is a reason, could the webstart launcher enable it only for webstart on those systems? Third way to solve this issue is to introduce a "-XX:enableSignalChaining" flag as mentioned before and allow it to be passed via JNLP. This might work since i heard webstart runs out of process anyway... so there must be a launcher involved which interprets this flags before JVM launch. to quote my original mail: It looks like a good self-defence mechanism for me :) thanks for the support, best regards, Michael Bien > ----- > > Paul > >/ A partial answer: one of the Hotspot engineers says > />/ > />/ "I think the short answer is that chaining requires LD_PRELOAD to > />/ override the signal entry points. Otherwise we [Hotspot] wouldn't see > />/ the calls that change the signal handlers. If the Java command itself > />/ linked against jsig that would work too I think. I believe that's the > />/ only way to solve the problem he is seeing in an automatic fashion. > />/ Depending on how the driver library gets loaded they might be able to > />/ build their own signal handler trampolines to work around it and > />/ correct the signal handlers after it gets loaded." > />/ > />/ Regards, > />/ > />/ Paul > />/ > />/ On 5/8/10 7:31 AM, Michael Bien wrote: > />>/ Hello everyone, > />>/ > />>/ i am one of the maintainers of JOGL and wrote JOCL > />>/ (http://jogamp.org/) and we are currently facing some signal handling > />>/ issues caused by the nvidia and amd drivers. > />>/ (I got the hint to post to this list since there is no better alias > />>/ for this kind of topics) > />>/ > />>/ e.g. the nvidia OpenCL driver uses at least the following handlers: > />>/ Warning: SIGSEGV handler expected:libjvm.so+0x5d8cf0 > />>/ found:libnvidia-compiler.so+0x1865e0 > />>/ Warning: SIGILL handler expected:libjvm.so+0x5d8cf0 > />>/ found:libnvidia-compiler.so+0x1865e0 > />>/ Warning: SIGFPE handler expected:libjvm.so+0x5d8cf0 > />>/ found:libnvidia-compiler.so+0x1865e0 > />>/ Warning: SIGBUS handler expected:libjvm.so+0x5d8cf0 > />>/ found:libnvidia-compiler.so+0x1865e0 > />>/ Warning: SIGXFSZ handler expected:libjvm.so+0x5d8cf0 > />>/ found:libnvidia-compiler.so+0x1865e0 > />>/ (-Xcheck:jni) > />>/ > />>/ which basically makes the jvm unusable on Linux and leads to > />>/ segmentation faults (in the driver, I suppose the driver catches jvm > />>/ signals). > />>/ > />>/ LD_PRELOAD > />>/ (http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/signals.html#gbzbl) > />>/ works perfectly but it is not allowed for webstart + applets... > />>/ > />>/ do you have any advice how we could workaround this issue? The > />>/ perfect solution would be a "-XX:enableSignalChaining" flag which we > />>/ could set via jnlp. Since the webstart JVM is out of process anyway > />>/ (since u10 or so) this would probably work. > />>/ > />>/ Why isn't signal chaining enabled by default on linux and solaris? It > />>/ looks like a good self-defence mechanism for me :) > />>/ > />>/ best regards, > />>/ Michael Bien > />>/ > />>/ --- > />>/ > />>/ http://michael-bien.com > /-------------- next part -------------- > -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Wed May 19 15:48:08 2010 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Wed, 19 May 2010 15:48:08 +0000 Subject: hg: jdk7/tl/langtools: 4 new changesets Message-ID: <20100519154819.D5B40442AD@hg.openjdk.java.net> Changeset: e9ef849ae0ed Author: mcimadamore Date: 2010-05-19 16:41 +0100 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/e9ef849ae0ed 6880344: Recursive type parameters do not compile Summary: Issue in type-variable substitution causes valid code to be rejected Reviewed-by: jjg ! src/share/classes/com/sun/tools/javac/code/Types.java ! src/share/classes/com/sun/tools/javac/comp/Check.java + test/tools/javac/generics/typevars/T6880344.java Changeset: 2881b376a689 Author: mcimadamore Date: 2010-05-19 16:42 +0100 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/2881b376a689 6946618: sqe test fails: javac/generics/NewOnTypeParm in pit jdk7 b91 in all platforms. Summary: Bad cast to ClassType in the new diamond implementation fails if the target type of the instance creation expression is a type-variable Reviewed-by: jjg ! src/share/classes/com/sun/tools/javac/comp/Attr.java + test/tools/javac/generics/6946618/T6946618a.java + test/tools/javac/generics/6946618/T6946618a.out + test/tools/javac/generics/6946618/T6946618b.java + test/tools/javac/generics/6946618/T6946618b.out + test/tools/javac/generics/6946618/T6946618c.java + test/tools/javac/generics/6946618/T6946618c.out Changeset: eb849389ae2c Author: mcimadamore Date: 2010-05-19 16:43 +0100 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/eb849389ae2c 6948381: javac Null Pointer Exception in Types.makeCompoundType Summary: Race condition between symbol completion and attribution of import statements causes NPE when creating intersection type Reviewed-by: jjg ! src/share/classes/com/sun/tools/javac/code/Types.java + test/tools/javac/6948381/T6948381.java + test/tools/javac/6948381/npe/A.java + test/tools/javac/6948381/npe/B.java Changeset: 1d587ef8bf56 Author: mcimadamore Date: 2010-05-19 16:43 +0100 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/1d587ef8bf56 6951833: latest diamond implementation generates spurious raw type warnings Summary: Raw warning checks should be disabled in the presence of a diamond AST node Reviewed-by: jjg ! src/share/classes/com/sun/tools/javac/comp/Check.java + test/tools/javac/generics/diamond/T6951833.java From dmytro_sheyko at hotmail.com Thu May 20 10:42:11 2010 From: dmytro_sheyko at hotmail.com (Dmytro Sheyko) Date: Thu, 20 May 2010 17:42:11 +0700 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: <4BF3C05C.7010300@mail.ru> References: , , <4BF2AAEE.1040706@mail.ru>, <4BF3BFFD.8010007@mail.ru>,<4BF3C05C.7010300@mail.ru> Message-ID: Hi Vladimir, I tried to figure out why the testcase failed on my modification. It appeared that number of negative zeros were changed during general sort. As I can see you already fixed this issue. Well, my modification was based on assumption that we can speed up eliminating explicit array range checks. However, such assumption is wrong because Hotspot anyway emits range checks at its discretion and therefore processZeros generally does not work as fast as I expected. So complications I made are not worth doing. As for the latest code you posted. Doesn't it make sense to skip leading negative zeros before farther processing? In this case we avoid unnecessary assigning +0.0 and then -0.0 to the same location a[k] (i.e. where k == p). /* * Skip the last negative value (if any) or all leading negative zeros */ while (left <= right && Double.doubleToRawLongBits(a[left]) < 0) { left++; } for (int k = left + 1, p = left; k <= right; k++) { double ak = a[k]; if (ak != 0.0d) { return; } if (Double.doubleToRawLongBits(ak) < 0) { // ak is -0.0d a[k] = 0.0d; a[p++] = -0.0d; } } Thank you, Dmytro Sheyko > Date: Wed, 19 May 2010 14:41:32 +0400 > From: iaroslavski at mail.ru > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > To: dmytro_sheyko at hotmail.com > CC: core-libs-dev at openjdk.java.net > > resend the class with correct constructor > > Vladimir Iaroslavski wrote: > > Dmytro, > > > > Thank you for comments, I updated double method, did little bit > > javadoc changes and replaced in char/short/byte methods > > "fromIndex -> left", "toIndex-1 -> right", the code became > > consistent with main sort method and more compact. Also I use > > more usual "i--" and "i++" in for loops (instead of "--i", "++i. > > > > To accent the difference between float/double and other types, > > I put comment where it is important: > > > > /* > > * In spite of a[great] == pivot1, the assignment > > * a[less++] = pivot1 may be incorrect, if a[great] > > * and pivot1 are floating-point zeros of different > > * signs, therefore in float/double methods we have > > * to use more accurate assignment a[k] = a[great]. > > */ > > a[less++] = pivot1; > > > > and for double/float: > > > > /* > > ..... > > */ > > a[k] = a[great]; > > > > See updated version in attachment. > > > > Thank you, > > Vladimir > > > > Dmytro Sheyko wrote: > >> Vladimir, > >> > >> I can see that you changed sortNegZeroAndNaN(float[]...) but probably > >> forgot to change sortNegZeroAndNaN(double[]...). > >> > >> You really puzzled me with failed testcase and note that sorting > >> algorithm (without special attention to zeros) generally may change > >> number of negative zeros. > >> I will provide my comments later. > >> > >> As for counting sort, I think we should use single format style over > >> the file (unless we have valuable reason not to do this). I mean to > >> choose > >> 1) > >> if (toIndex - fromIndex > > >> COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > >> countingSort(a, fromIndex, toIndex); > >> return; > >> } > >> sort(a, fromIndex, toIndex - 1, true); > >> 2) > >> if (toIndex - fromIndex > > >> COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > >> countingSort(a, fromIndex, toIndex); > >> } else { > >> sort(a, fromIndex, toIndex - 1, true); > >> } > >> I prefer the second one. > >> > >> Thanks a lot, > >> Dmytro Sheyko > >> > >> > Date: Tue, 18 May 2010 18:57:50 +0400 > >> > From: iaroslavski at mail.ru > >> > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > >> > To: dmytro_sheyko at hotmail.com > >> > CC: core-libs-dev at openjdk.java.net > >> > > >> > Hello, > >> > > >> > I've run your modification for counting sort, it real faster. > >> > I attached new version with your changes (I did little bit > >> > format it) and included my case with float/double. > >> > > >> > Note that you modification doesn't pass test from Sorting class, > >> > which I sent earlier. It fails on float/double test: > >> > > >> > Test #3: random = 666, len = 34, a = 0, g = 6, z = 9, n = 10, p = 9 > >> > > >> > I suggest shorter method (which is based on your idea to skip counting > >> > negative zeros on Phase 1.): I found find first zero index (or it will > >> > be index of first positive element if no zeros at all, or last > >> negative, > >> > if no positive and zero elements) and then swap negative zero to the > >> > beginning of the sub-range. > >> > > >> > int hi = right; > >> > > >> > while (left < hi) { > >> > int middle = (left + hi) >>> 1; > >> > float middleValue = a[middle]; > >> > > >> > if (middleValue < 0.0f) { > >> > left = middle + 1; > >> > } else { > >> > hi = middle; > >> > } > >> > } > >> > > >> > for (int k = left, p = left; k <= right; k++) { > >> > float ak = a[k]; > >> > if (ak != 0.0f) { > >> > return; > >> > } > >> > if (Float.floatToRawIntBits(ak) < 0) { // ak is -0.0f > >> > a[k] = +0.0f; > >> > a[p++] = -0.0f; > >> > } > >> > } > >> > > >> > Important note: in partitioning loop there are several places > >> > (marked by // !) where potential bug with -0.0 could be > >> > (when pivot and a[great] are zeros with different signs): > >> > > >> > if (a[great] == pivot1) { > >> > a[k] = a[less]; > >> > - a[less++] = pivot1; // ! > >> > + a[less++] = a[great]; > >> > } else { // pivot1 < a[great] < pivot2 > >> > a[k] = a[great]; > >> > } > >> > - a[great--] = pivot2; // ! > >> > + a[great--] = ak; > >> > } else if (ak == pivot1) { // Move a[k] to left part > >> > a[k] = a[less]; > >> > - a[less++] = pivot1; // ! > >> > + a[less++] = ak; > >> > } > >> > > >> > and the same in "Pivots are equal" branch. > >> > > >> > I did changes "pivot1/2 -> ak" in methods for all types > >> > and "pivot1 -> a[great]" in float/double sections only. > >> > > >> > Please, review format changes for counting sort and new version > >> > of Phase 3 for float/double. > >> > > >> > Thank you, > >> > Vladimir > >> > > >> > Dmytro Sheyko wrote: > >> > > Hi, > >> > > > >> > > About counting sort again. > >> > > > >> > > 1. This condition "i < count.length && k <= right" is excessive. > >> Any one > >> > > conjunct is enough. "k <= right" seems better. > >> > > 2. No need to calculate "short value = (short) (i + > >> Short.MIN_VALUE)" > >> > > when "count[i]" is zero. > >> > > 3. For signed primitives (byte and short) we would better loop > >> backward. > >> > > Thanks to "k >= fromIndex" condition we will quit looping earlier > >> > > assuming that typically we work with positive numbers. > >> > > For unsigned primitives (char) we would better loop forward because > >> > > typically we work with characters about zero (ASCII). > >> > > > >> > > - for (int i = 0, k = left; i < count.length && k <= right; i++) { > >> > > - short value = (short) (i + Short.MIN_VALUE); > >> > > - for (int s = count[i]; s > 0; s--) { > >> > > - a[k++] = value; > >> > > - } > >> > > - } > >> > > > >> > > + for (int i = NUM_SHORT_VALUES - 1, k = toIndex - 1; k >= > >> > > fromIndex; --i) { > >> > > + while (count[i] == 0) --i; > >> > > + short value = (short) (i + Short.MIN_VALUE); > >> > > + int s = count[i]; > >> > > + do { a[k--] = value; } while (--s > 0); > >> > > + } > >> > > > >> > > Thanks, > >> > > Dmytro Sheyko > >> > > > >> > > > From: iaroslavski at mail.ru > >> > > > To: dmytro_sheyko at hotmail.com > >> > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > >> > > > Subject: Re[2]: New portion of improvements for Dual-Pivot > >> Quicksort > >> > > > Date: Tue, 18 May 2010 01:11:19 +0400 > >> > > > > >> > > > Sounds good! > >> > > > Will consider too... > >> > > > > >> > > > Mon, 17 May 2010 22:24:11 +0700 ?????? ?? Dmytro Sheyko > >> > > : > >> > > > > >> > > > > Hi, > >> > > > > > >> > > > > Regarding counting sort. We can check whether we should > >> switch to > >> > > counting sort only once in the beginning. > >> > > > > > >> > > > > > Date: Mon, 17 May 2010 17:30:37 +0400 > >> > > > > > From: iaroslavski at mail.ru > >> > > > > > Subject: Re: New portion of improvements for Dual-Pivot > >> Quicksort > >> > > > > > To: dmytro_sheyko at hotmail.com > >> > > > > > CC: core-libs-dev at openjdk.java.net > >> > > > > > > >> > > > > > Hello, > >> > > > > > > >> > > > > > Thank you for review, I'll check and run tests again with you > >> > > changes. > >> > > > > > > >> > > > > > Thank you, > >> > > > > > Vladimir > >> > > > > > > >> > > > > > Dmytro Sheyko wrote: > >> > > > > > > Hello, > >> > > > > > > > >> > > > > > > More ideas. > >> > > > > > > > >> > > > > > > 1. We can use > >> > > > > > > Double.doubleToRawLongBits instead of > >> Double.doubleToLongBits and > >> > > > > > > Float.floatToRawIntBits instead of Float.floatToIntBits. > >> > > > > > > No need to handle NaN's because they all are placed to > >> the end > >> > > of array. > >> > > > > > > > >> > > > > > > 2. Note that > >> > > > > > > Double.doubleToRawLongBits(+0.0) == 0L and > >> > > > > > > Double.doubleToRawLongBits(-0.0) == Long.MIN_VALUE and > >> > > > > > > Float.floatToRawIntBits(+0.0) == 0 and > >> > > > > > > Float.floatToRawIntBits(-0.0) == Integer.MIN_VALUE. > >> > > > > > > > >> > > > > > > Comparing with is zero usually more efficient (or at > >> least not > >> > > worse) > >> > > > > > > than with other values. Thus such pattern > >> > > > > > > > >> > > > > > > if (ak == 0.0f && NEGATIVE_ZERO == Float.floatToIntBits(ak)) > >> > > > > > > > >> > > > > > > can be replaced with > >> > > > > > > > >> > > > > > > if (ak == 0.0f && Float.floatToIntBits(ak) < 0) > >> > > > > > > > >> > > > > > > 3. It would be more efficient to count negative zeros after > >> > > sorting. > >> > > > > > > General sorting algorithm puts both negative and positive > >> zeros > >> > > together > >> > > > > > > (but maybe not in right order). > >> > > > > > > Therefore we have to process less elements because > >> usually we > >> > > have less > >> > > > > > > zeros than other numbers. > >> > > > > > > > >> > > > > > > Thanks, > >> > > > > > > Dmytro Sheyko > >> > > > > > > > >> > > > > > > > From: iaroslavski at mail.ru > >> > > > > > > > To: dmytro_sheyko at hotmail.com; jjb at google.com > >> > > > > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > >> > > > > > > > Subject: Re[6]: New portion of improvements for Dual-Pivot > >> > > Quicksort > >> > > > > > > > Date: Fri, 14 May 2010 23:54:06 +0400 > >> > > > > > > > > >> > > > > > > > Hello, > >> > > > > > > > > >> > > > > > > > I've updated the class, please, review the changes. > >> > > > > > > > > >> > > > > > > > Vladimir > >> > > > > > > > > >> > > > > > > > Fri, 14 May 2010 01:48:11 +0700 ?????? ?? Dmytro Sheyko > >> > > > > > > : > >> > > > > > > > > >> > > > > > > > > Yes. I prefer F (Find First zero using binary search) > >> over > >> > > C (Count > >> > > > > > > negatives) and S (Smart Scan for zero). > >> > > > > > > > > > >> > > > > > > > > > From: iaroslavski at mail.ru > >> > > > > > > > > > To: dmytro_sheyko at hotmail.com > >> > > > > > > > > > CC: jjb at google.com; core-libs-dev at openjdk.java.net; > >> > > > > > > iaroslavski at mail.ru > >> > > > > > > > > > Subject: Re[4]: New portion of improvements for > >> > > Dual-Pivot Quicksort > >> > > > > > > > > > Date: Thu, 13 May 2010 21:34:54 +0400 > >> > > > > > > > > > > >> > > > > > > > > > Dmytro, > >> > > > > > > > > > > >> > > > > > > > > > I've tested your suggested variants, and found that > >> case "C" > >> > > > > > > > > > (very interesting approach to find first position > >> of zero > >> > > > > > > > > > by counting negative elements) works slower than > >> original > >> > > > > > > > > > or two other cases. > >> > > > > > > > > > > >> > > > > > > > > > Implementations "F" and "S" are very close to each > >> other > >> > > > > > > > > > and little bit faster than original. I prefer case > >> "F": > >> > > > > > > > > > it is shorter and more clear. Do you agree? > >> > > > > > > > > > > >> > > > > > > > > > I'll prepare updated DualPivotQuicksort file and > >> send it > >> > > > > > > > > > tomorrow. > >> > > > > > > > > > > >> > > > > > > > > > Thank you, > >> > > > > > > > > > Vladimir > >> > > > > > > > > > > >> > > > > > > > > > Wed, 12 May 2010 17:04:52 +0700 ?????? ?? Dmytro > >> Sheyko > >> > > > > > > : > >> > > > > > > > > > > >> > > > > > > > > > > Vladimir, > >> > > > > > > > > > > > >> > > > > > > > > > > Your changes are good for me. > >> > > > > > > > > > > > >> > > > > > > > > > > Additionally I have some comments/proposals > >> regarding > >> > > dealing > >> > > > > > > with negative zeros. > >> > > > > > > > > > > > >> > > > > > > > > > > 1. Scanning for the first zero we can avoid range > >> check > >> > > (i >= > >> > > > > > > left) if we have at least one negative value. > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > >> > > > > > > > > > > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 > >> 2010 > >> > > > > > > > > > > @@ -1705,10 +1705,15 @@ > >> > > > > > > > > > > } > >> > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > >> > > > > > > > > > > + int zeroIndex = 0; > >> > > > > > > > > > > > >> > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == > >> > > 0.0f; i--) { > >> > > > > > > > > > > - zeroIndex = i; > >> > > > > > > > > > > + if (a[left] < 0.0f) { > >> > > > > > > > > > > + zeroIndex = findAnyZero(a, left, n); > >> > > > > > > > > > > + > >> > > > > > > > > > > + // there is at least one negative value, so range > >> > > check is > >> > > > > > > not needed > >> > > > > > > > > > > + for (int i = zeroIndex - 1; /*i >= left &&*/ > >> a[i] == > >> > > 0.0f; i--) { > >> > > > > > > > > > > + zeroIndex = i; > >> > > > > > > > > > > + } > >> > > > > > > > > > > } > >> > > > > > > > > > > > >> > > > > > > > > > > // Turn the right number of positive zeros back into > >> > > negative zeros > >> > > > > > > > > > > > >> > > > > > > > > > > 2. We can find the position of the first zero by > >> counting > >> > > > > > > negative values during preprocessing phase. > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > >> > > > > > > > > > > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 > >> 2010 > >> > > > > > > > > > > @@ -1678,7 +1678,7 @@ > >> > > > > > > > > > > * Phase 1: Count negative zeros and move NaNs to > >> end of > >> > > array. > >> > > > > > > > > > > */ > >> > > > > > > > > > > final int NEGATIVE_ZERO = > >> Float.floatToIntBits(-0.0f); > >> > > > > > > > > > > - int numNegativeZeros = 0; > >> > > > > > > > > > > + int numNegativeZeros = 0, numNegativeValues = 0; > >> > > > > > > > > > > int n = right; > >> > > > > > > > > > > > >> > > > > > > > > > > for (int k = left; k <= n; k++) { > >> > > > > > > > > > > @@ -1689,6 +1689,8 @@ > >> > > > > > > > > > > } else if (ak != ak) { // i.e., ak is NaN > >> > > > > > > > > > > a[k--] = a[n]; > >> > > > > > > > > > > a[n--] = Float.NaN; > >> > > > > > > > > > > + } else if (ak < 0.0f) { > >> > > > > > > > > > > + numNegativeValues++; > >> > > > > > > > > > > } > >> > > > > > > > > > > } > >> > > > > > > > > > > > >> > > > > > > > > > > @@ -1705,7 +1707,7 @@ > >> > > > > > > > > > > } > >> > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > >> > > > > > > > > > > + int zeroIndex = numNegativeValues; > >> > > > > > > > > > > > >> > > > > > > > > > > for (int i = zeroIndex - 1; i >= left && a[i] == > >> 0.0f; > >> > > i--) { > >> > > > > > > > > > > zeroIndex = i; > >> > > > > > > > > > > > >> > > > > > > > > > > 3. We can use binary search to find the first > >> zero and > >> > > thus > >> > > > > > > avoid linear scan. > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 09:04:19 2010 > >> > > > > > > > > > > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 > >> 2010 > >> > > > > > > > > > > @@ -1705,11 +1705,7 @@ > >> > > > > > > > > > > } > >> > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > >> > > > > > > > > > > - > >> > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == > >> > > 0.0f; i--) { > >> > > > > > > > > > > - zeroIndex = i; > >> > > > > > > > > > > - } > >> > > > > > > > > > > + int zeroIndex = findFirstZero(a, left, n); > >> > > > > > > > > > > > >> > > > > > > > > > > // Turn the right number of positive zeros back into > >> > > negative zeros > >> > > > > > > > > > > for (int i = zeroIndex, m = zeroIndex + > >> > > numNegativeZeros; i < > >> > > > > > > m; i++) { > >> > > > > > > > > > > @@ -1718,7 +1714,7 @@ > >> > > > > > > > > > > } > >> > > > > > > > > > > > >> > > > > > > > > > > /** > >> > > > > > > > > > > - * Returns the index of some zero element in the > >> > > specified > >> > > > > > > range via > >> > > > > > > > > > > + * Returns the index of the first zero element > >> in the > >> > > > > > > specified range via > >> > > > > > > > > > > * binary search. The range is assumed to be > >> sorted, and > >> > > must > >> > > > > > > contain > >> > > > > > > > > > > * at least one zero. > >> > > > > > > > > > > * > >> > > > > > > > > > > @@ -1726,18 +1722,17 @@ > >> > > > > > > > > > > * @param low the index of the first element, > >> inclusive, > >> > > to be > >> > > > > > > searched > >> > > > > > > > > > > * @param high the index of the last element, > >> inclusive, > >> > > to be > >> > > > > > > searched > >> > > > > > > > > > > */ > >> > > > > > > > > > > - private static int findAnyZero(float[] a, int low, > >> > > int high) { > >> > > > > > > > > > > - while (true) { > >> > > > > > > > > > > + private static int findFirstZero(float[] a, int > >> low, > >> > > int high) { > >> > > > > > > > > > > + while (low < high) { > >> > > > > > > > > > > int middle = (low + high) >>> 1; > >> > > > > > > > > > > float middleValue = a[middle]; > >> > > > > > > > > > > > >> > > > > > > > > > > if (middleValue < 0.0f) { > >> > > > > > > > > > > low = middle + 1; > >> > > > > > > > > > > - } else if (middleValue > 0.0f) { > >> > > > > > > > > > > - high = middle - 1; > >> > > > > > > > > > > - } else { // middleValue == 0.0f > >> > > > > > > > > > > - return middle; > >> > > > > > > > > > > + } else { // middleValue >= 0.0f > >> > > > > > > > > > > + high = middle; > >> > > > > > > > > > > } > >> > > > > > > > > > > + return low; > >> > > > > > > > > > > } > >> > > > > > > > > > > } > >> > > > > > > > > > > > >> > > > > > > > > > > Counting negative values appeared more expensive > >> than > >> > > any other > >> > > > > > > variants. > >> > > > > > > > > > > The last proposal seems to me as efficient as the > >> current > >> > > > > > > solution is in its worst case - when we have only one > >> negative > >> > > zero (in > >> > > > > > > the half of array). > >> > > > > > > > > > > And it shows the best result if we have many zeros. > >> > > > > > > > > > > > >> > > > > > > > > > > Regards, > >> > > > > > > > > > > Dmytro Sheyko > >> > > > > > > > > > > > >> > > > > > > > > > > > From: iaroslavski at mail.ru > >> > > > > > > > > > > > To: jjb at google.com; dmytro_sheyko at hotmail.com > >> > > > > > > > > > > > CC: core-libs-dev at openjdk.java.net; > >> iaroslavski at mail.ru > >> > > > > > > > > > > > Subject: Re[2]: New portion of improvements for > >> > > Dual-Pivot > >> > > > > > > Quicksort > >> > > > > > > > > > > > Date: Sun, 9 May 2010 23:51:27 +0400 > >> > > > > > > > > > > > > >> > > > > > > > > > > > Josh, > >> > > > > > > > > > > > Dmytro, > >> > > > > > > > > > > > > >> > > > > > > > > > > > I have done more thoroughly testing "great - > >> less > 5 * > >> > > > > > > seventh" vs. "less < e1 && great > e5", > >> > > > > > > > > > > > and found that more symmetric code "less < e1 && > >> > > great > e5" > >> > > > > > > is little bit faster, ~0.5..0.7% > >> > > > > > > > > > > > on both VMs. Other code has not been changed. > >> > > > > > > > > > > > > >> > > > > > > > > > > > Please, take the latest version in attachment. > >> > > > > > > > > > > > > >> > > > > > > > > > > > Vladimir > >> > > > > > > > > > > > > >> > > > > > > > > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua > >> Bloch > >> > > > > > > : > >> > > > > > > > > > > > > >> > > > > > > > > > > > > Vladimir, > >> > > > > > > > > > > > > > >> > > > > > > > > > > > > Old: > >> > > > > > > > > > > > > > >> > > > > > > > > > > > >298 if (less < e1 && great > e5) { > >> > > > > > > > > > > > > > >> > > > > > > > > > > > > New: > >> > > > > > > > > > > > > > >> > > > > > > > > > > > >256 if (great - less > 5 * seventh) { > >> > > > > > > > > > > > > >> > > > > > > > > > > > >Regards, > >> > > > > > > > > > > > >Josh _________________________________________________________________ Hotmail: Free, trusted and rich email service. https://signup.live.com/signup.aspx?id=60969 -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: DualPivotQuicksort.diff Type: application/octet-stream Size: 1695 bytes Desc: not available URL: From dmytro_sheyko at hotmail.com Thu May 20 11:25:09 2010 From: dmytro_sheyko at hotmail.com (Dmytro Sheyko) Date: Thu, 20 May 2010 18:25:09 +0700 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: <4BF3B8F5.1010409@univ-mlv.fr> References: , , , , , , <4BF2AAEE.1040706@mail.ru>, , <4BF3B8F5.1010409@univ-mlv.fr> Message-ID: Hi Remi, I believe that it is up to javac to generate compact and interpretation-efficient bytecode. But anyway the first case seems to as acceptable as the second one. So I don't care which style is used (of course, if it's consistent). Thanks, Dmytro Sheyko Date: Wed, 19 May 2010 12:09:57 +0200 From: forax at univ-mlv.fr To: core-libs-dev at openjdk.java.net Subject: Re: New portion of improvements for Dual-Pivot Quicksort Le 19/05/2010 11:02, Dmytro Sheyko a ?crit : Vladimir, I can see that you changed sortNegZeroAndNaN(float[]...) but probably forgot to change sortNegZeroAndNaN(double[]...). You really puzzled me with failed testcase and note that sorting algorithm (without special attention to zeros) generally may change number of negative zeros. I will provide my comments later. As for counting sort, I think we should use single format style over the file (unless we have valuable reason not to do this). I mean to choose 1) if (toIndex - fromIndex > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { countingSort(a, fromIndex, toIndex); return; } sort(a, fromIndex, toIndex - 1, true); 2) if (toIndex - fromIndex > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { countingSort(a, fromIndex, toIndex); } else { sort(a, fromIndex, toIndex - 1, true); } I prefer the second one. Thanks a lot, Dmytro Sheyko But the former have a more compact bytecode representation (return vs goto) and avoid an unecessary jump for interpreters. R?mi _________________________________________________________________ Hotmail: Trusted email with Microsoft?s powerful SPAM protection. https://signup.live.com/signup.aspx?id=60969 -------------- next part -------------- An HTML attachment was scrubbed... URL: From iaroslavski at mail.ru Thu May 20 13:15:57 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Thu, 20 May 2010 17:15:57 +0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: <4BF2AAEE.1040706@mail.ru> <4BF3BFFD.8010007@mail.ru> <4BF3C05C.7010300@mail.ru> Message-ID: <4BF5360D.9020503@mail.ru> Hi Dmytro, It makes sense and should work faster. I will check it and other optimization tomorrow and let you know results. Thank you, Vladimir Dmytro Sheyko wrote: > Hi Vladimir, > > I tried to figure out why the testcase failed on my modification. It > appeared that number of negative zeros were changed during general sort. > As I can see you already fixed this issue. Well, my modification was > based on assumption that we can speed up eliminating explicit array > range checks. > However, such assumption is wrong because Hotspot anyway emits range > checks at its discretion and therefore processZeros generally does not > work as fast as I expected. > So complications I made are not worth doing. > > As for the latest code you posted. Doesn't it make sense to skip leading > negative zeros before farther processing? In this case we avoid > unnecessary assigning +0.0 and then -0.0 to the same location a[k] (i.e. > where k == p). > > > /* > * Skip the last negative value (if any) or all leading negative > zeros > */ > while (left <= right && Double.doubleToRawLongBits(a[left]) < 0) { > left++; > } > > for (int k = left + 1, p = left; k <= right; k++) { > double ak = a[k]; > if (ak != 0.0d) { > return; > } > if (Double.doubleToRawLongBits(ak) < 0) { // ak is -0.0d > a[k] = 0.0d; > a[p++] = -0.0d; > } > } > > Thank you, > Dmytro Sheyko > > > > Date: Wed, 19 May 2010 14:41:32 +0400 > > From: iaroslavski at mail.ru > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > To: dmytro_sheyko at hotmail.com > > CC: core-libs-dev at openjdk.java.net > > > > resend the class with correct constructor > > > > Vladimir Iaroslavski wrote: > > > Dmytro, > > > > > > Thank you for comments, I updated double method, did little bit > > > javadoc changes and replaced in char/short/byte methods > > > "fromIndex -> left", "toIndex-1 -> right", the code became > > > consistent with main sort method and more compact. Also I use > > > more usual "i--" and "i++" in for loops (instead of "--i", "++i. > > > > > > To accent the difference between float/double and other types, > > > I put comment where it is important: > > > > > > /* > > > * In spite of a[great] == pivot1, the assignment > > > * a[less++] = pivot1 may be incorrect, if a[great] > > > * and pivot1 are floating-point zeros of different > > > * signs, therefore in float/double methods we have > > > * to use more accurate assignment a[k] = a[great]. > > > */ > > > a[less++] = pivot1; > > > > > > and for double/float: > > > > > > /* > > > ..... > > > */ > > > a[k] = a[great]; > > > > > > See updated version in attachment. > > > > > > Thank you, > > > Vladimir > > > > > > Dmytro Sheyko wrote: > > >> Vladimir, > > >> > > >> I can see that you changed sortNegZeroAndNaN(float[]...) but probably > > >> forgot to change sortNegZeroAndNaN(double[]...). > > >> > > >> You really puzzled me with failed testcase and note that sorting > > >> algorithm (without special attention to zeros) generally may change > > >> number of negative zeros. > > >> I will provide my comments later. > > >> > > >> As for counting sort, I think we should use single format style over > > >> the file (unless we have valuable reason not to do this). I mean to > > >> choose > > >> 1) > > >> if (toIndex - fromIndex > > > >> COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > > >> countingSort(a, fromIndex, toIndex); > > >> return; > > >> } > > >> sort(a, fromIndex, toIndex - 1, true); > > >> 2) > > >> if (toIndex - fromIndex > > > >> COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > > >> countingSort(a, fromIndex, toIndex); > > >> } else { > > >> sort(a, fromIndex, toIndex - 1, true); > > >> } > > >> I prefer the second one. > > >> > > >> Thanks a lot, > > >> Dmytro Sheyko > > >> > > >> > Date: Tue, 18 May 2010 18:57:50 +0400 > > >> > From: iaroslavski at mail.ru > > >> > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > >> > To: dmytro_sheyko at hotmail.com > > >> > CC: core-libs-dev at openjdk.java.net > > >> > > > >> > Hello, > > >> > > > >> > I've run your modification for counting sort, it real faster. > > >> > I attached new version with your changes (I did little bit > > >> > format it) and included my case with float/double. > > >> > > > >> > Note that you modification doesn't pass test from Sorting class, > > >> > which I sent earlier. It fails on float/double test: > > >> > > > >> > Test #3: random = 666, len = 34, a = 0, g = 6, z = 9, n = 10, p = 9 > > >> > > > >> > I suggest shorter method (which is based on your idea to skip > counting > > >> > negative zeros on Phase 1.): I found find first zero index (or > it will > > >> > be index of first positive element if no zeros at all, or last > > >> negative, > > >> > if no positive and zero elements) and then swap negative zero to the > > >> > beginning of the sub-range. > > >> > > > >> > int hi = right; > > >> > > > >> > while (left < hi) { > > >> > int middle = (left + hi) >>> 1; > > >> > float middleValue = a[middle]; > > >> > > > >> > if (middleValue < 0.0f) { > > >> > left = middle + 1; > > >> > } else { > > >> > hi = middle; > > >> > } > > >> > } > > >> > > > >> > for (int k = left, p = left; k <= right; k++) { > > >> > float ak = a[k]; > > >> > if (ak != 0.0f) { > > >> > return; > > >> > } > > >> > if (Float.floatToRawIntBits(ak) < 0) { // ak is -0.0f > > >> > a[k] = +0.0f; > > >> > a[p++] = -0.0f; > > >> > } > > >> > } > > >> > > > >> > Important note: in partitioning loop there are several places > > >> > (marked by // !) where potential bug with -0.0 could be > > >> > (when pivot and a[great] are zeros with different signs): > > >> > > > >> > if (a[great] == pivot1) { > > >> > a[k] = a[less]; > > >> > - a[less++] = pivot1; // ! > > >> > + a[less++] = a[great]; > > >> > } else { // pivot1 < a[great] < pivot2 > > >> > a[k] = a[great]; > > >> > } > > >> > - a[great--] = pivot2; // ! > > >> > + a[great--] = ak; > > >> > } else if (ak == pivot1) { // Move a[k] to left part > > >> > a[k] = a[less]; > > >> > - a[less++] = pivot1; // ! > > >> > + a[less++] = ak; > > >> > } > > >> > > > >> > and the same in "Pivots are equal" branch. > > >> > > > >> > I did changes "pivot1/2 -> ak" in methods for all types > > >> > and "pivot1 -> a[great]" in float/double sections only. > > >> > > > >> > Please, review format changes for counting sort and new version > > >> > of Phase 3 for float/double. > > >> > > > >> > Thank you, > > >> > Vladimir > > >> > > > >> > Dmytro Sheyko wrote: > > >> > > Hi, > > >> > > > > >> > > About counting sort again. > > >> > > > > >> > > 1. This condition "i < count.length && k <= right" is excessive. > > >> Any one > > >> > > conjunct is enough. "k <= right" seems better. > > >> > > 2. No need to calculate "short value = (short) (i + > > >> Short.MIN_VALUE)" > > >> > > when "count[i]" is zero. > > >> > > 3. For signed primitives (byte and short) we would better loop > > >> backward. > > >> > > Thanks to "k >= fromIndex" condition we will quit looping earlier > > >> > > assuming that typically we work with positive numbers. > > >> > > For unsigned primitives (char) we would better loop forward > because > > >> > > typically we work with characters about zero (ASCII). > > >> > > > > >> > > - for (int i = 0, k = left; i < count.length && k <= right; i++) { > > >> > > - short value = (short) (i + Short.MIN_VALUE); > > >> > > - for (int s = count[i]; s > 0; s--) { > > >> > > - a[k++] = value; > > >> > > - } > > >> > > - } > > >> > > > > >> > > + for (int i = NUM_SHORT_VALUES - 1, k = toIndex - 1; k >= > > >> > > fromIndex; --i) { > > >> > > + while (count[i] == 0) --i; > > >> > > + short value = (short) (i + Short.MIN_VALUE); > > >> > > + int s = count[i]; > > >> > > + do { a[k--] = value; } while (--s > 0); > > >> > > + } > > >> > > > > >> > > Thanks, > > >> > > Dmytro Sheyko > > >> > > > > >> > > > From: iaroslavski at mail.ru > > >> > > > To: dmytro_sheyko at hotmail.com > > >> > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > >> > > > Subject: Re[2]: New portion of improvements for Dual-Pivot > > >> Quicksort > > >> > > > Date: Tue, 18 May 2010 01:11:19 +0400 > > >> > > > > > >> > > > Sounds good! > > >> > > > Will consider too... > > >> > > > > > >> > > > Mon, 17 May 2010 22:24:11 +0700 ?????? ?? Dmytro Sheyko > > >> > > : > > >> > > > > > >> > > > > Hi, > > >> > > > > > > >> > > > > Regarding counting sort. We can check whether we should > > >> switch to > > >> > > counting sort only once in the beginning. > > >> > > > > > > >> > > > > > Date: Mon, 17 May 2010 17:30:37 +0400 > > >> > > > > > From: iaroslavski at mail.ru > > >> > > > > > Subject: Re: New portion of improvements for Dual-Pivot > > >> Quicksort > > >> > > > > > To: dmytro_sheyko at hotmail.com > > >> > > > > > CC: core-libs-dev at openjdk.java.net > > >> > > > > > > > >> > > > > > Hello, > > >> > > > > > > > >> > > > > > Thank you for review, I'll check and run tests again > with you > > >> > > changes. > > >> > > > > > > > >> > > > > > Thank you, > > >> > > > > > Vladimir > > >> > > > > > > > >> > > > > > Dmytro Sheyko wrote: > > >> > > > > > > Hello, > > >> > > > > > > > > >> > > > > > > More ideas. > > >> > > > > > > > > >> > > > > > > 1. We can use > > >> > > > > > > Double.doubleToRawLongBits instead of > > >> Double.doubleToLongBits and > > >> > > > > > > Float.floatToRawIntBits instead of Float.floatToIntBits. > > >> > > > > > > No need to handle NaN's because they all are placed to > > >> the end > > >> > > of array. > > >> > > > > > > > > >> > > > > > > 2. Note that > > >> > > > > > > Double.doubleToRawLongBits(+0.0) == 0L and > > >> > > > > > > Double.doubleToRawLongBits(-0.0) == Long.MIN_VALUE and > > >> > > > > > > Float.floatToRawIntBits(+0.0) == 0 and > > >> > > > > > > Float.floatToRawIntBits(-0.0) == Integer.MIN_VALUE. > > >> > > > > > > > > >> > > > > > > Comparing with is zero usually more efficient (or at > > >> least not > > >> > > worse) > > >> > > > > > > than with other values. Thus such pattern > > >> > > > > > > > > >> > > > > > > if (ak == 0.0f && NEGATIVE_ZERO == > Float.floatToIntBits(ak)) > > >> > > > > > > > > >> > > > > > > can be replaced with > > >> > > > > > > > > >> > > > > > > if (ak == 0.0f && Float.floatToIntBits(ak) < 0) > > >> > > > > > > > > >> > > > > > > 3. It would be more efficient to count negative zeros > after > > >> > > sorting. > > >> > > > > > > General sorting algorithm puts both negative and positive > > >> zeros > > >> > > together > > >> > > > > > > (but maybe not in right order). > > >> > > > > > > Therefore we have to process less elements because > > >> usually we > > >> > > have less > > >> > > > > > > zeros than other numbers. > > >> > > > > > > > > >> > > > > > > Thanks, > > >> > > > > > > Dmytro Sheyko > > >> > > > > > > > > >> > > > > > > > From: iaroslavski at mail.ru > > >> > > > > > > > To: dmytro_sheyko at hotmail.com; jjb at google.com > > >> > > > > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > >> > > > > > > > Subject: Re[6]: New portion of improvements for > Dual-Pivot > > >> > > Quicksort > > >> > > > > > > > Date: Fri, 14 May 2010 23:54:06 +0400 > > >> > > > > > > > > > >> > > > > > > > Hello, > > >> > > > > > > > > > >> > > > > > > > I've updated the class, please, review the changes. > > >> > > > > > > > > > >> > > > > > > > Vladimir > > >> > > > > > > > > > >> > > > > > > > Fri, 14 May 2010 01:48:11 +0700 ?????? ?? Dmytro Sheyko > > >> > > > > > > : > > >> > > > > > > > > > >> > > > > > > > > Yes. I prefer F (Find First zero using binary search) > > >> over > > >> > > C (Count > > >> > > > > > > negatives) and S (Smart Scan for zero). > > >> > > > > > > > > > > >> > > > > > > > > > From: iaroslavski at mail.ru > > >> > > > > > > > > > To: dmytro_sheyko at hotmail.com > > >> > > > > > > > > > CC: jjb at google.com; core-libs-dev at openjdk.java.net; > > >> > > > > > > iaroslavski at mail.ru > > >> > > > > > > > > > Subject: Re[4]: New portion of improvements for > > >> > > Dual-Pivot Quicksort > > >> > > > > > > > > > Date: Thu, 13 May 2010 21:34:54 +0400 > > >> > > > > > > > > > > > >> > > > > > > > > > Dmytro, > > >> > > > > > > > > > > > >> > > > > > > > > > I've tested your suggested variants, and found that > > >> case "C" > > >> > > > > > > > > > (very interesting approach to find first position > > >> of zero > > >> > > > > > > > > > by counting negative elements) works slower than > > >> original > > >> > > > > > > > > > or two other cases. > > >> > > > > > > > > > > > >> > > > > > > > > > Implementations "F" and "S" are very close to each > > >> other > > >> > > > > > > > > > and little bit faster than original. I prefer case > > >> "F": > > >> > > > > > > > > > it is shorter and more clear. Do you agree? > > >> > > > > > > > > > > > >> > > > > > > > > > I'll prepare updated DualPivotQuicksort file and > > >> send it > > >> > > > > > > > > > tomorrow. > > >> > > > > > > > > > > > >> > > > > > > > > > Thank you, > > >> > > > > > > > > > Vladimir > > >> > > > > > > > > > > > >> > > > > > > > > > Wed, 12 May 2010 17:04:52 +0700 ?????? ?? Dmytro > > >> Sheyko > > >> > > > > > > : > > >> > > > > > > > > > > > >> > > > > > > > > > > Vladimir, > > >> > > > > > > > > > > > > >> > > > > > > > > > > Your changes are good for me. > > >> > > > > > > > > > > > > >> > > > > > > > > > > Additionally I have some comments/proposals > > >> regarding > > >> > > dealing > > >> > > > > > > with negative zeros. > > >> > > > > > > > > > > > > >> > > > > > > > > > > 1. Scanning for the first zero we can avoid range > > >> check > > >> > > (i >= > > >> > > > > > > left) if we have at least one negative value. > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > 09:04:19 2010 > > >> > > > > > > > > > > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 > > >> 2010 > > >> > > > > > > > > > > @@ -1705,10 +1705,15 @@ > > >> > > > > > > > > > > } > > >> > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > >> > > > > > > > > > > + int zeroIndex = 0; > > >> > > > > > > > > > > > > >> > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == > > >> > > 0.0f; i--) { > > >> > > > > > > > > > > - zeroIndex = i; > > >> > > > > > > > > > > + if (a[left] < 0.0f) { > > >> > > > > > > > > > > + zeroIndex = findAnyZero(a, left, n); > > >> > > > > > > > > > > + > > >> > > > > > > > > > > + // there is at least one negative value, so > range > > >> > > check is > > >> > > > > > > not needed > > >> > > > > > > > > > > + for (int i = zeroIndex - 1; /*i >= left &&*/ > > >> a[i] == > > >> > > 0.0f; i--) { > > >> > > > > > > > > > > + zeroIndex = i; > > >> > > > > > > > > > > + } > > >> > > > > > > > > > > } > > >> > > > > > > > > > > > > >> > > > > > > > > > > // Turn the right number of positive zeros > back into > > >> > > negative zeros > > >> > > > > > > > > > > > > >> > > > > > > > > > > 2. We can find the position of the first zero by > > >> counting > > >> > > > > > > negative values during preprocessing phase. > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > 09:04:19 2010 > > >> > > > > > > > > > > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 > > >> 2010 > > >> > > > > > > > > > > @@ -1678,7 +1678,7 @@ > > >> > > > > > > > > > > * Phase 1: Count negative zeros and move NaNs to > > >> end of > > >> > > array. > > >> > > > > > > > > > > */ > > >> > > > > > > > > > > final int NEGATIVE_ZERO = > > >> Float.floatToIntBits(-0.0f); > > >> > > > > > > > > > > - int numNegativeZeros = 0; > > >> > > > > > > > > > > + int numNegativeZeros = 0, numNegativeValues = 0; > > >> > > > > > > > > > > int n = right; > > >> > > > > > > > > > > > > >> > > > > > > > > > > for (int k = left; k <= n; k++) { > > >> > > > > > > > > > > @@ -1689,6 +1689,8 @@ > > >> > > > > > > > > > > } else if (ak != ak) { // i.e., ak is NaN > > >> > > > > > > > > > > a[k--] = a[n]; > > >> > > > > > > > > > > a[n--] = Float.NaN; > > >> > > > > > > > > > > + } else if (ak < 0.0f) { > > >> > > > > > > > > > > + numNegativeValues++; > > >> > > > > > > > > > > } > > >> > > > > > > > > > > } > > >> > > > > > > > > > > > > >> > > > > > > > > > > @@ -1705,7 +1707,7 @@ > > >> > > > > > > > > > > } > > >> > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > >> > > > > > > > > > > + int zeroIndex = numNegativeValues; > > >> > > > > > > > > > > > > >> > > > > > > > > > > for (int i = zeroIndex - 1; i >= left && a[i] == > > >> 0.0f; > > >> > > i--) { > > >> > > > > > > > > > > zeroIndex = i; > > >> > > > > > > > > > > > > >> > > > > > > > > > > 3. We can use binary search to find the first > > >> zero and > > >> > > thus > > >> > > > > > > avoid linear scan. > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > 09:04:19 2010 > > >> > > > > > > > > > > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 > > >> 2010 > > >> > > > > > > > > > > @@ -1705,11 +1705,7 @@ > > >> > > > > > > > > > > } > > >> > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > >> > > > > > > > > > > - > > >> > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == > > >> > > 0.0f; i--) { > > >> > > > > > > > > > > - zeroIndex = i; > > >> > > > > > > > > > > - } > > >> > > > > > > > > > > + int zeroIndex = findFirstZero(a, left, n); > > >> > > > > > > > > > > > > >> > > > > > > > > > > // Turn the right number of positive zeros > back into > > >> > > negative zeros > > >> > > > > > > > > > > for (int i = zeroIndex, m = zeroIndex + > > >> > > numNegativeZeros; i < > > >> > > > > > > m; i++) { > > >> > > > > > > > > > > @@ -1718,7 +1714,7 @@ > > >> > > > > > > > > > > } > > >> > > > > > > > > > > > > >> > > > > > > > > > > /** > > >> > > > > > > > > > > - * Returns the index of some zero element in the > > >> > > specified > > >> > > > > > > range via > > >> > > > > > > > > > > + * Returns the index of the first zero element > > >> in the > > >> > > > > > > specified range via > > >> > > > > > > > > > > * binary search. The range is assumed to be > > >> sorted, and > > >> > > must > > >> > > > > > > contain > > >> > > > > > > > > > > * at least one zero. > > >> > > > > > > > > > > * > > >> > > > > > > > > > > @@ -1726,18 +1722,17 @@ > > >> > > > > > > > > > > * @param low the index of the first element, > > >> inclusive, > > >> > > to be > > >> > > > > > > searched > > >> > > > > > > > > > > * @param high the index of the last element, > > >> inclusive, > > >> > > to be > > >> > > > > > > searched > > >> > > > > > > > > > > */ > > >> > > > > > > > > > > - private static int findAnyZero(float[] a, > int low, > > >> > > int high) { > > >> > > > > > > > > > > - while (true) { > > >> > > > > > > > > > > + private static int findFirstZero(float[] a, int > > >> low, > > >> > > int high) { > > >> > > > > > > > > > > + while (low < high) { > > >> > > > > > > > > > > int middle = (low + high) >>> 1; > > >> > > > > > > > > > > float middleValue = a[middle]; > > >> > > > > > > > > > > > > >> > > > > > > > > > > if (middleValue < 0.0f) { > > >> > > > > > > > > > > low = middle + 1; > > >> > > > > > > > > > > - } else if (middleValue > 0.0f) { > > >> > > > > > > > > > > - high = middle - 1; > > >> > > > > > > > > > > - } else { // middleValue == 0.0f > > >> > > > > > > > > > > - return middle; > > >> > > > > > > > > > > + } else { // middleValue >= 0.0f > > >> > > > > > > > > > > + high = middle; > > >> > > > > > > > > > > } > > >> > > > > > > > > > > + return low; > > >> > > > > > > > > > > } > > >> > > > > > > > > > > } > > >> > > > > > > > > > > > > >> > > > > > > > > > > Counting negative values appeared more expensive > > >> than > > >> > > any other > > >> > > > > > > variants. > > >> > > > > > > > > > > The last proposal seems to me as efficient as the > > >> current > > >> > > > > > > solution is in its worst case - when we have only one > > >> negative > > >> > > zero (in > > >> > > > > > > the half of array). > > >> > > > > > > > > > > And it shows the best result if we have many > zeros. > > >> > > > > > > > > > > > > >> > > > > > > > > > > Regards, > > >> > > > > > > > > > > Dmytro Sheyko > > >> > > > > > > > > > > > > >> > > > > > > > > > > > From: iaroslavski at mail.ru > > >> > > > > > > > > > > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > >> > > > > > > > > > > > CC: core-libs-dev at openjdk.java.net; > > >> iaroslavski at mail.ru > > >> > > > > > > > > > > > Subject: Re[2]: New portion of improvements for > > >> > > Dual-Pivot > > >> > > > > > > Quicksort > > >> > > > > > > > > > > > Date: Sun, 9 May 2010 23:51:27 +0400 > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > Josh, > > >> > > > > > > > > > > > Dmytro, > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > I have done more thoroughly testing "great - > > >> less > 5 * > > >> > > > > > > seventh" vs. "less < e1 && great > e5", > > >> > > > > > > > > > > > and found that more symmetric code "less < e1 && > > >> > > great > e5" > > >> > > > > > > is little bit faster, ~0.5..0.7% > > >> > > > > > > > > > > > on both VMs. Other code has not been changed. > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > Please, take the latest version in attachment. > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > Vladimir > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua > > >> Bloch > > >> > > > > > > : > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > > Vladimir, > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > > > Old: > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > > >298 if (less < e1 && great > e5) { > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > > > New: > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > > >256 if (great - less > 5 * seventh) { > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > >Regards, > > >> > > > > > > > > > > > >Josh > > ------------------------------------------------------------------------ > Hotmail: Free, trusted and rich email service. Get it now. > From christos at zoulas.com Thu May 20 16:47:58 2010 From: christos at zoulas.com (Christos Zoulas) Date: Thu, 20 May 2010 12:47:58 -0400 Subject: JIT bug? Message-ID: <20100520164758.2656E56425@rebar.astron.com> A friend of mine Andrew Neitsch sent this to me: christos public class Mainiac { public static void main(String[] args) throws Exception { int limit = Integer.MAX_VALUE; System.out.println("limit is " + limit); int i = 0; while (i++ < limit) { System.err.format("i = %d < limit: %b\n", i, i < limit); } System.err.println("i = " + i); System.err.println("limit = " + limit); } } From xueming.shen at oracle.com Thu May 20 22:19:38 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Thu, 20 May 2010 15:19:38 -0700 Subject: Concatenated .gz files/streams Message-ID: <4BF5B57A.3050307@oracle.com> Martin, Though there is different opinion that "it is not obvious that accepting multiple .gz files concatenated together is actually an improvement" back to 2006:-) it appears rfc1952 clearly specifies "A gzip file consists of a serious of "members"..." in its "File format" section[1], and more importantly:-) some of my new colleagues are very interested to have this rfe addressed because there is real world product actually still heavilly uses concatenated .gz files. So here is the webrev of a reasonable fix and the test case. (The test case only run against the output from GZIPOutputStream, I did test on couple .gz files from gzip, just don't want to introduce in gzip dependency into the test case) http://cr.openjdk.java.net/~sherman/4691425/webrev/ -Sherman [1] http://www.gzip.org/zlib/rfc-gzip.html#file-format From iaroslavski at mail.ru Fri May 21 14:38:51 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Fri, 21 May 2010 18:38:51 +0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: <4BF2AAEE.1040706@mail.ru> <4BF3BFFD.8010007@mail.ru> <4BF3C05C.7010300@mail.ru> Message-ID: <4BF69AFB.8060406@mail.ru> Hello, I prepared version with your changes "Skip the last negative value (if any) or all leading negative" and with my optimization for all types. I added two while loops before partitioning to skip elements, less than pivot1 and greater than pivot2: if (pivot1 != pivot2) { /* ... */ a[e2] = a[less]; a[e4] = a[great]; ++ while (a[++less] < pivot1); ++ while (a[--great] > pivot2); /* ... */ outer: for (int k = less; k <= great; k++) { ... } Here is benchmark result (in compare with quicksort from JDK 6): client server ------ ------ previous version: 60.70% 48.20% current version: 57.22% 46.18% So, we win 2-3% ! Thank you, Vladimir Dmytro Sheyko wrote: > Hi Vladimir, > > I tried to figure out why the testcase failed on my modification. It > appeared that number of negative zeros were changed during general sort. > As I can see you already fixed this issue. Well, my modification was > based on assumption that we can speed up eliminating explicit array > range checks. > However, such assumption is wrong because Hotspot anyway emits range > checks at its discretion and therefore processZeros generally does not > work as fast as I expected. > So complications I made are not worth doing. > > As for the latest code you posted. Doesn't it make sense to skip leading > negative zeros before farther processing? In this case we avoid > unnecessary assigning +0.0 and then -0.0 to the same location a[k] (i.e. > where k == p). > > /* > * Skip the last negative value (if any) or all leading negative > zeros > */ > while (left <= right && Double.doubleToRawLongBits(a[left]) < 0) { > left++; > } > > for (int k = left + 1, p = left; k <= right; k++) { > double ak = a[k]; > if (ak != 0.0d) { > return; > } > if (Double.doubleToRawLongBits(ak) < 0) { // ak is -0.0d > a[k] = 0.0d; > a[p++] = -0.0d; > } > } > > Thank you, > Dmytro Sheyko > > > > Date: Wed, 19 May 2010 14:41:32 +0400 > > From: iaroslavski at mail.ru > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > To: dmytro_sheyko at hotmail.com > > CC: core-libs-dev at openjdk.java.net > > > > resend the class with correct constructor > > > > Vladimir Iaroslavski wrote: > > > Dmytro, > > > > > > Thank you for comments, I updated double method, did little bit > > > javadoc changes and replaced in char/short/byte methods > > > "fromIndex -> left", "toIndex-1 -> right", the code became > > > consistent with main sort method and more compact. Also I use > > > more usual "i--" and "i++" in for loops (instead of "--i", "++i. > > > > > > To accent the difference between float/double and other types, > > > I put comment where it is important: > > > > > > /* > > > * In spite of a[great] == pivot1, the assignment > > > * a[less++] = pivot1 may be incorrect, if a[great] > > > * and pivot1 are floating-point zeros of different > > > * signs, therefore in float/double methods we have > > > * to use more accurate assignment a[k] = a[great]. > > > */ > > > a[less++] = pivot1; > > > > > > and for double/float: > > > > > > /* > > > ..... > > > */ > > > a[k] = a[great]; > > > > > > See updated version in attachment. > > > > > > Thank you, > > > Vladimir > > > > > > Dmytro Sheyko wrote: > > >> Vladimir, > > >> > > >> I can see that you changed sortNegZeroAndNaN(float[]...) but probably > > >> forgot to change sortNegZeroAndNaN(double[]...). > > >> > > >> You really puzzled me with failed testcase and note that sorting > > >> algorithm (without special attention to zeros) generally may change > > >> number of negative zeros. > > >> I will provide my comments later. > > >> > > >> As for counting sort, I think we should use single format style over > > >> the file (unless we have valuable reason not to do this). I mean to > > >> choose > > >> 1) > > >> if (toIndex - fromIndex > > > >> COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > > >> countingSort(a, fromIndex, toIndex); > > >> return; > > >> } > > >> sort(a, fromIndex, toIndex - 1, true); > > >> 2) > > >> if (toIndex - fromIndex > > > >> COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > > >> countingSort(a, fromIndex, toIndex); > > >> } else { > > >> sort(a, fromIndex, toIndex - 1, true); > > >> } > > >> I prefer the second one. > > >> > > >> Thanks a lot, > > >> Dmytro Sheyko > > >> > > >> > Date: Tue, 18 May 2010 18:57:50 +0400 > > >> > From: iaroslavski at mail.ru > > >> > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > >> > To: dmytro_sheyko at hotmail.com > > >> > CC: core-libs-dev at openjdk.java.net > > >> > > > >> > Hello, > > >> > > > >> > I've run your modification for counting sort, it real faster. > > >> > I attached new version with your changes (I did little bit > > >> > format it) and included my case with float/double. > > >> > > > >> > Note that you modification doesn't pass test from Sorting class, > > >> > which I sent earlier. It fails on float/double test: > > >> > > > >> > Test #3: random = 666, len = 34, a = 0, g = 6, z = 9, n = 10, p = 9 > > >> > > > >> > I suggest shorter method (which is based on your idea to skip > counting > > >> > negative zeros on Phase 1.): I found find first zero index (or > it will > > >> > be index of first positive element if no zeros at all, or last > > >> negative, > > >> > if no positive and zero elements) and then swap negative zero to the > > >> > beginning of the sub-range. > > >> > > > >> > int hi = right; > > >> > > > >> > while (left < hi) { > > >> > int middle = (left + hi) >>> 1; > > >> > float middleValue = a[middle]; > > >> > > > >> > if (middleValue < 0.0f) { > > >> > left = middle + 1; > > >> > } else { > > >> > hi = middle; > > >> > } > > >> > } > > >> > > > >> > for (int k = left, p = left; k <= right; k++) { > > >> > float ak = a[k]; > > >> > if (ak != 0.0f) { > > >> > return; > > >> > } > > >> > if (Float.floatToRawIntBits(ak) < 0) { // ak is -0.0f > > >> > a[k] = +0.0f; > > >> > a[p++] = -0.0f; > > >> > } > > >> > } > > >> > > > >> > Important note: in partitioning loop there are several places > > >> > (marked by // !) where potential bug with -0.0 could be > > >> > (when pivot and a[great] are zeros with different signs): > > >> > > > >> > if (a[great] == pivot1) { > > >> > a[k] = a[less]; > > >> > - a[less++] = pivot1; // ! > > >> > + a[less++] = a[great]; > > >> > } else { // pivot1 < a[great] < pivot2 > > >> > a[k] = a[great]; > > >> > } > > >> > - a[great--] = pivot2; // ! > > >> > + a[great--] = ak; > > >> > } else if (ak == pivot1) { // Move a[k] to left part > > >> > a[k] = a[less]; > > >> > - a[less++] = pivot1; // ! > > >> > + a[less++] = ak; > > >> > } > > >> > > > >> > and the same in "Pivots are equal" branch. > > >> > > > >> > I did changes "pivot1/2 -> ak" in methods for all types > > >> > and "pivot1 -> a[great]" in float/double sections only. > > >> > > > >> > Please, review format changes for counting sort and new version > > >> > of Phase 3 for float/double. > > >> > > > >> > Thank you, > > >> > Vladimir > > >> > > > >> > Dmytro Sheyko wrote: > > >> > > Hi, > > >> > > > > >> > > About counting sort again. > > >> > > > > >> > > 1. This condition "i < count.length && k <= right" is excessive. > > >> Any one > > >> > > conjunct is enough. "k <= right" seems better. > > >> > > 2. No need to calculate "short value = (short) (i + > > >> Short.MIN_VALUE)" > > >> > > when "count[i]" is zero. > > >> > > 3. For signed primitives (byte and short) we would better loop > > >> backward. > > >> > > Thanks to "k >= fromIndex" condition we will quit looping earlier > > >> > > assuming that typically we work with positive numbers. > > >> > > For unsigned primitives (char) we would better loop forward > because > > >> > > typically we work with characters about zero (ASCII). > > >> > > > > >> > > - for (int i = 0, k = left; i < count.length && k <= right; i++) { > > >> > > - short value = (short) (i + Short.MIN_VALUE); > > >> > > - for (int s = count[i]; s > 0; s--) { > > >> > > - a[k++] = value; > > >> > > - } > > >> > > - } > > >> > > > > >> > > + for (int i = NUM_SHORT_VALUES - 1, k = toIndex - 1; k >= > > >> > > fromIndex; --i) { > > >> > > + while (count[i] == 0) --i; > > >> > > + short value = (short) (i + Short.MIN_VALUE); > > >> > > + int s = count[i]; > > >> > > + do { a[k--] = value; } while (--s > 0); > > >> > > + } > > >> > > > > >> > > Thanks, > > >> > > Dmytro Sheyko > > >> > > > > >> > > > From: iaroslavski at mail.ru > > >> > > > To: dmytro_sheyko at hotmail.com > > >> > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > >> > > > Subject: Re[2]: New portion of improvements for Dual-Pivot > > >> Quicksort > > >> > > > Date: Tue, 18 May 2010 01:11:19 +0400 > > >> > > > > > >> > > > Sounds good! > > >> > > > Will consider too... > > >> > > > > > >> > > > Mon, 17 May 2010 22:24:11 +0700 ?????? ?? Dmytro Sheyko > > >> > > : > > >> > > > > > >> > > > > Hi, > > >> > > > > > > >> > > > > Regarding counting sort. We can check whether we should > > >> switch to > > >> > > counting sort only once in the beginning. > > >> > > > > > > >> > > > > > Date: Mon, 17 May 2010 17:30:37 +0400 > > >> > > > > > From: iaroslavski at mail.ru > > >> > > > > > Subject: Re: New portion of improvements for Dual-Pivot > > >> Quicksort > > >> > > > > > To: dmytro_sheyko at hotmail.com > > >> > > > > > CC: core-libs-dev at openjdk.java.net > > >> > > > > > > > >> > > > > > Hello, > > >> > > > > > > > >> > > > > > Thank you for review, I'll check and run tests again > with you > > >> > > changes. > > >> > > > > > > > >> > > > > > Thank you, > > >> > > > > > Vladimir > > >> > > > > > > > >> > > > > > Dmytro Sheyko wrote: > > >> > > > > > > Hello, > > >> > > > > > > > > >> > > > > > > More ideas. > > >> > > > > > > > > >> > > > > > > 1. We can use > > >> > > > > > > Double.doubleToRawLongBits instead of > > >> Double.doubleToLongBits and > > >> > > > > > > Float.floatToRawIntBits instead of Float.floatToIntBits. > > >> > > > > > > No need to handle NaN's because they all are placed to > > >> the end > > >> > > of array. > > >> > > > > > > > > >> > > > > > > 2. Note that > > >> > > > > > > Double.doubleToRawLongBits(+0.0) == 0L and > > >> > > > > > > Double.doubleToRawLongBits(-0.0) == Long.MIN_VALUE and > > >> > > > > > > Float.floatToRawIntBits(+0.0) == 0 and > > >> > > > > > > Float.floatToRawIntBits(-0.0) == Integer.MIN_VALUE. > > >> > > > > > > > > >> > > > > > > Comparing with is zero usually more efficient (or at > > >> least not > > >> > > worse) > > >> > > > > > > than with other values. Thus such pattern > > >> > > > > > > > > >> > > > > > > if (ak == 0.0f && NEGATIVE_ZERO == > Float.floatToIntBits(ak)) > > >> > > > > > > > > >> > > > > > > can be replaced with > > >> > > > > > > > > >> > > > > > > if (ak == 0.0f && Float.floatToIntBits(ak) < 0) > > >> > > > > > > > > >> > > > > > > 3. It would be more efficient to count negative zeros > after > > >> > > sorting. > > >> > > > > > > General sorting algorithm puts both negative and positive > > >> zeros > > >> > > together > > >> > > > > > > (but maybe not in right order). > > >> > > > > > > Therefore we have to process less elements because > > >> usually we > > >> > > have less > > >> > > > > > > zeros than other numbers. > > >> > > > > > > > > >> > > > > > > Thanks, > > >> > > > > > > Dmytro Sheyko > > >> > > > > > > > > >> > > > > > > > From: iaroslavski at mail.ru > > >> > > > > > > > To: dmytro_sheyko at hotmail.com; jjb at google.com > > >> > > > > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > >> > > > > > > > Subject: Re[6]: New portion of improvements for > Dual-Pivot > > >> > > Quicksort > > >> > > > > > > > Date: Fri, 14 May 2010 23:54:06 +0400 > > >> > > > > > > > > > >> > > > > > > > Hello, > > >> > > > > > > > > > >> > > > > > > > I've updated the class, please, review the changes. > > >> > > > > > > > > > >> > > > > > > > Vladimir > > >> > > > > > > > > > >> > > > > > > > Fri, 14 May 2010 01:48:11 +0700 ?????? ?? Dmytro Sheyko > > >> > > > > > > : > > >> > > > > > > > > > >> > > > > > > > > Yes. I prefer F (Find First zero using binary search) > > >> over > > >> > > C (Count > > >> > > > > > > negatives) and S (Smart Scan for zero). > > >> > > > > > > > > > > >> > > > > > > > > > From: iaroslavski at mail.ru > > >> > > > > > > > > > To: dmytro_sheyko at hotmail.com > > >> > > > > > > > > > CC: jjb at google.com; core-libs-dev at openjdk.java.net; > > >> > > > > > > iaroslavski at mail.ru > > >> > > > > > > > > > Subject: Re[4]: New portion of improvements for > > >> > > Dual-Pivot Quicksort > > >> > > > > > > > > > Date: Thu, 13 May 2010 21:34:54 +0400 > > >> > > > > > > > > > > > >> > > > > > > > > > Dmytro, > > >> > > > > > > > > > > > >> > > > > > > > > > I've tested your suggested variants, and found that > > >> case "C" > > >> > > > > > > > > > (very interesting approach to find first position > > >> of zero > > >> > > > > > > > > > by counting negative elements) works slower than > > >> original > > >> > > > > > > > > > or two other cases. > > >> > > > > > > > > > > > >> > > > > > > > > > Implementations "F" and "S" are very close to each > > >> other > > >> > > > > > > > > > and little bit faster than original. I prefer case > > >> "F": > > >> > > > > > > > > > it is shorter and more clear. Do you agree? > > >> > > > > > > > > > > > >> > > > > > > > > > I'll prepare updated DualPivotQuicksort file and > > >> send it > > >> > > > > > > > > > tomorrow. > > >> > > > > > > > > > > > >> > > > > > > > > > Thank you, > > >> > > > > > > > > > Vladimir > > >> > > > > > > > > > > > >> > > > > > > > > > Wed, 12 May 2010 17:04:52 +0700 ?????? ?? Dmytro > > >> Sheyko > > >> > > > > > > : > > >> > > > > > > > > > > > >> > > > > > > > > > > Vladimir, > > >> > > > > > > > > > > > > >> > > > > > > > > > > Your changes are good for me. > > >> > > > > > > > > > > > > >> > > > > > > > > > > Additionally I have some comments/proposals > > >> regarding > > >> > > dealing > > >> > > > > > > with negative zeros. > > >> > > > > > > > > > > > > >> > > > > > > > > > > 1. Scanning for the first zero we can avoid range > > >> check > > >> > > (i >= > > >> > > > > > > left) if we have at least one negative value. > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > 09:04:19 2010 > > >> > > > > > > > > > > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 > > >> 2010 > > >> > > > > > > > > > > @@ -1705,10 +1705,15 @@ > > >> > > > > > > > > > > } > > >> > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > >> > > > > > > > > > > + int zeroIndex = 0; > > >> > > > > > > > > > > > > >> > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == > > >> > > 0.0f; i--) { > > >> > > > > > > > > > > - zeroIndex = i; > > >> > > > > > > > > > > + if (a[left] < 0.0f) { > > >> > > > > > > > > > > + zeroIndex = findAnyZero(a, left, n); > > >> > > > > > > > > > > + > > >> > > > > > > > > > > + // there is at least one negative value, so > range > > >> > > check is > > >> > > > > > > not needed > > >> > > > > > > > > > > + for (int i = zeroIndex - 1; /*i >= left &&*/ > > >> a[i] == > > >> > > 0.0f; i--) { > > >> > > > > > > > > > > + zeroIndex = i; > > >> > > > > > > > > > > + } > > >> > > > > > > > > > > } > > >> > > > > > > > > > > > > >> > > > > > > > > > > // Turn the right number of positive zeros > back into > > >> > > negative zeros > > >> > > > > > > > > > > > > >> > > > > > > > > > > 2. We can find the position of the first zero by > > >> counting > > >> > > > > > > negative values during preprocessing phase. > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > 09:04:19 2010 > > >> > > > > > > > > > > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 > > >> 2010 > > >> > > > > > > > > > > @@ -1678,7 +1678,7 @@ > > >> > > > > > > > > > > * Phase 1: Count negative zeros and move NaNs to > > >> end of > > >> > > array. > > >> > > > > > > > > > > */ > > >> > > > > > > > > > > final int NEGATIVE_ZERO = > > >> Float.floatToIntBits(-0.0f); > > >> > > > > > > > > > > - int numNegativeZeros = 0; > > >> > > > > > > > > > > + int numNegativeZeros = 0, numNegativeValues = 0; > > >> > > > > > > > > > > int n = right; > > >> > > > > > > > > > > > > >> > > > > > > > > > > for (int k = left; k <= n; k++) { > > >> > > > > > > > > > > @@ -1689,6 +1689,8 @@ > > >> > > > > > > > > > > } else if (ak != ak) { // i.e., ak is NaN > > >> > > > > > > > > > > a[k--] = a[n]; > > >> > > > > > > > > > > a[n--] = Float.NaN; > > >> > > > > > > > > > > + } else if (ak < 0.0f) { > > >> > > > > > > > > > > + numNegativeValues++; > > >> > > > > > > > > > > } > > >> > > > > > > > > > > } > > >> > > > > > > > > > > > > >> > > > > > > > > > > @@ -1705,7 +1707,7 @@ > > >> > > > > > > > > > > } > > >> > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > >> > > > > > > > > > > + int zeroIndex = numNegativeValues; > > >> > > > > > > > > > > > > >> > > > > > > > > > > for (int i = zeroIndex - 1; i >= left && a[i] == > > >> 0.0f; > > >> > > i--) { > > >> > > > > > > > > > > zeroIndex = i; > > >> > > > > > > > > > > > > >> > > > > > > > > > > 3. We can use binary search to find the first > > >> zero and > > >> > > thus > > >> > > > > > > avoid linear scan. > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > 09:04:19 2010 > > >> > > > > > > > > > > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 > > >> 2010 > > >> > > > > > > > > > > @@ -1705,11 +1705,7 @@ > > >> > > > > > > > > > > } > > >> > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > >> > > > > > > > > > > - > > >> > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == > > >> > > 0.0f; i--) { > > >> > > > > > > > > > > - zeroIndex = i; > > >> > > > > > > > > > > - } > > >> > > > > > > > > > > + int zeroIndex = findFirstZero(a, left, n); > > >> > > > > > > > > > > > > >> > > > > > > > > > > // Turn the right number of positive zeros > back into > > >> > > negative zeros > > >> > > > > > > > > > > for (int i = zeroIndex, m = zeroIndex + > > >> > > numNegativeZeros; i < > > >> > > > > > > m; i++) { > > >> > > > > > > > > > > @@ -1718,7 +1714,7 @@ > > >> > > > > > > > > > > } > > >> > > > > > > > > > > > > >> > > > > > > > > > > /** > > >> > > > > > > > > > > - * Returns the index of some zero element in the > > >> > > specified > > >> > > > > > > range via > > >> > > > > > > > > > > + * Returns the index of the first zero element > > >> in the > > >> > > > > > > specified range via > > >> > > > > > > > > > > * binary search. The range is assumed to be > > >> sorted, and > > >> > > must > > >> > > > > > > contain > > >> > > > > > > > > > > * at least one zero. > > >> > > > > > > > > > > * > > >> > > > > > > > > > > @@ -1726,18 +1722,17 @@ > > >> > > > > > > > > > > * @param low the index of the first element, > > >> inclusive, > > >> > > to be > > >> > > > > > > searched > > >> > > > > > > > > > > * @param high the index of the last element, > > >> inclusive, > > >> > > to be > > >> > > > > > > searched > > >> > > > > > > > > > > */ > > >> > > > > > > > > > > - private static int findAnyZero(float[] a, > int low, > > >> > > int high) { > > >> > > > > > > > > > > - while (true) { > > >> > > > > > > > > > > + private static int findFirstZero(float[] a, int > > >> low, > > >> > > int high) { > > >> > > > > > > > > > > + while (low < high) { > > >> > > > > > > > > > > int middle = (low + high) >>> 1; > > >> > > > > > > > > > > float middleValue = a[middle]; > > >> > > > > > > > > > > > > >> > > > > > > > > > > if (middleValue < 0.0f) { > > >> > > > > > > > > > > low = middle + 1; > > >> > > > > > > > > > > - } else if (middleValue > 0.0f) { > > >> > > > > > > > > > > - high = middle - 1; > > >> > > > > > > > > > > - } else { // middleValue == 0.0f > > >> > > > > > > > > > > - return middle; > > >> > > > > > > > > > > + } else { // middleValue >= 0.0f > > >> > > > > > > > > > > + high = middle; > > >> > > > > > > > > > > } > > >> > > > > > > > > > > + return low; > > >> > > > > > > > > > > } > > >> > > > > > > > > > > } > > >> > > > > > > > > > > > > >> > > > > > > > > > > Counting negative values appeared more expensive > > >> than > > >> > > any other > > >> > > > > > > variants. > > >> > > > > > > > > > > The last proposal seems to me as efficient as the > > >> current > > >> > > > > > > solution is in its worst case - when we have only one > > >> negative > > >> > > zero (in > > >> > > > > > > the half of array). > > >> > > > > > > > > > > And it shows the best result if we have many > zeros. > > >> > > > > > > > > > > > > >> > > > > > > > > > > Regards, > > >> > > > > > > > > > > Dmytro Sheyko > > >> > > > > > > > > > > > > >> > > > > > > > > > > > From: iaroslavski at mail.ru > > >> > > > > > > > > > > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > >> > > > > > > > > > > > CC: core-libs-dev at openjdk.java.net; > > >> iaroslavski at mail.ru > > >> > > > > > > > > > > > Subject: Re[2]: New portion of improvements for > > >> > > Dual-Pivot > > >> > > > > > > Quicksort > > >> > > > > > > > > > > > Date: Sun, 9 May 2010 23:51:27 +0400 > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > Josh, > > >> > > > > > > > > > > > Dmytro, > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > I have done more thoroughly testing "great - > > >> less > 5 * > > >> > > > > > > seventh" vs. "less < e1 && great > e5", > > >> > > > > > > > > > > > and found that more symmetric code "less < e1 && > > >> > > great > e5" > > >> > > > > > > is little bit faster, ~0.5..0.7% > > >> > > > > > > > > > > > on both VMs. Other code has not been changed. > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > Please, take the latest version in attachment. > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > Vladimir > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua > > >> Bloch > > >> > > > > > > : > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > > Vladimir, > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > > > Old: > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > > >298 if (less < e1 && great > e5) { > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > > > New: > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > > >256 if (great - less > 5 * seventh) { > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > >Regards, > > >> > > > > > > > > > > > >Josh -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: DualPivotQuicksort.java URL: From jonathan.gibbons at oracle.com Sat May 22 00:33:10 2010 From: jonathan.gibbons at oracle.com (jonathan.gibbons at oracle.com) Date: Sat, 22 May 2010 00:33:10 +0000 Subject: hg: jdk7/tl/langtools: 6954901: langtools/test/Makefile should check for bin/javac(.exe) instead of lib/tools.jar Message-ID: <20100522003312.BE9C8444B6@hg.openjdk.java.net> Changeset: e9d66d392a8d Author: jjg Date: 2010-05-21 17:32 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/e9d66d392a8d 6954901: langtools/test/Makefile should check for bin/javac(.exe) instead of lib/tools.jar Reviewed-by: ohair ! test/Makefile From martinrb at google.com Sun May 23 19:07:47 2010 From: martinrb at google.com (Martin Buchholz) Date: Sun, 23 May 2010 12:07:47 -0700 Subject: Concatenated .gz files/streams In-Reply-To: <4BF5B57A.3050307@oracle.com> References: <4BF5B57A.3050307@oracle.com> Message-ID: First, let me apologize for my poor judgment back in 2006. Concatenated gzip members are clearly supported by rfc1952, the gzip command, and by the many votes for bug 4691425. The JDK should support this feature as well. One can argue this change doesn't go far enough, and that one should be able to perform operations that motivated the existence of the multiple member feature, like skip to the next gzip member and to inspect the filename and extra fields in the gzip header, but that's a much bigger change. Probably GZIPInputStream shouldn't extend InflaterInputStream, but too late for that. -- the returned values from readHeader and readTrailer should be documented. -- 174 int n = 10; I would write this kind of code as int n = 2 + 2 + 6; for clarity. -- Probably readHeader should call crc.reset() twice, before and after reading the header, and then remove all calls to crc.reset() after calling readHeader. -- typos: OutputStram jusr -- 38 int n = rnd.nextInt(100) % 10 + 1; Isn't this just rnd.nextInt(10) + 1? -- the test should close gzis. -- probably should do some cleanup on src, srcBAOS, srcBytes. src is written to srcBAOS, then turned back into a byte[], which seems pointless to me. -- Martin On Thu, May 20, 2010 at 15:19, Xueming Shen wrote: > Martin, > > Though there is different opinion that "it is not obvious that accepting > multiple .gz files concatenated > together is actually an improvement" back to 2006:-) ?it appears rfc1952 > clearly specifies "A gzip file > consists of a serious of "members"..." in its "File format" section[1], and > more importantly:-) some of > my new colleagues are very interested to have this rfe addressed because > there is real world product > actually still heavilly uses concatenated .gz files. So here is the webrev > of a reasonable fix and the test > case. (The test case only run against the output from GZIPOutputStream, I > did test on couple .gz files > from gzip, just don't want to introduce in gzip dependency into the test > case) > > http://cr.openjdk.java.net/~sherman/4691425/webrev/ > > -Sherman > > [1] http://www.gzip.org/zlib/rfc-gzip.html#file-format > From xueming.shen at oracle.com Sun May 23 19:47:03 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Sun, 23 May 2010 12:47:03 -0700 Subject: Concatenated .gz files/streams In-Reply-To: References: <4BF5B57A.3050307@oracle.com> Message-ID: <4BF98637.6090800@oracle.com> Martin Buchholz wrote: > One can argue this change doesn't go far enough, > and that one should be able to perform operations > that motivated the existence of the multiple member feature, > like skip to the next gzip member and to inspect the filename > and extra fields in the gzip header, but that's a much bigger > change. > > Probably GZIPInputStream shouldn't extend InflaterInputStream, > but too late for that. > One thing we might be able to do is to have a GZIPFile to provide access to those various header fields and individual member set, should request come in. Webrev has been updated accordingly. #int n = rnd.nextInt(100) % 10 + 1; should be just rnd.nextInt(10) + 1. I started with doing 100 of concatenated gz... #probably should do some cleanup on src, srcBAOS, srcBytes. #src is written to srcBAOS, then turned back into a byte[], #which seems pointless to me. I use the BAOS to concatenated the byte[] arrays (there are n of src arrays), don't want to handle it myself. Thanks, Sherman -- > the returned values from readHeader and readTrailer > should be documented. > > -- > > 174 int n = 10; > I would write this kind of code as > int n = 2 + 2 + 6; > for clarity. > > -- > Probably readHeader should call crc.reset() twice, > before and after reading the header, > and then remove all calls to crc.reset() after calling > readHeader. > -- > > typos: > OutputStram > jusr > -- > 38 int n = rnd.nextInt(100) % 10 + 1; > Isn't this just rnd.nextInt(10) + 1? > -- > the test should close gzis. > -- > probably should do some cleanup on src, srcBAOS, srcBytes. > src is written to srcBAOS, then turned back into a byte[], > which seems pointless to me. > -- > > From martinrb at google.com Sun May 23 22:35:54 2010 From: martinrb at google.com (Martin Buchholz) Date: Sun, 23 May 2010 15:35:54 -0700 Subject: Concatenated .gz files/streams In-Reply-To: <4BF98637.6090800@oracle.com> References: <4BF5B57A.3050307@oracle.com> <4BF98637.6090800@oracle.com> Message-ID: Thanks for the improvements. Everything looks good to me, but here are some additional suggestions: Rename n to "members" to make it a little clearer. 38 int n = rnd.nextInt(10) + 1; Also use a random size with the GZIPInputStream constructor 69 GZIPInputStream gzis = new GZIPInputStream( 70 new ByteArrayInputStream(dst), someotherrandomsize); I find this kind of code difficult to review. It's trickier than it looks. Martin On Sun, May 23, 2010 at 12:47, Xueming Shen wrote: > Martin Buchholz wrote: >> >> One can argue this change doesn't go far enough, >> and that one should be able to perform operations >> that motivated the existence of the multiple member feature, >> like skip to the next gzip member and to inspect the filename >> and extra fields in the gzip header, but that's a much bigger >> change. >> >> Probably GZIPInputStream shouldn't extend InflaterInputStream, >> but too late for that. >> > > One thing we might be able to do is to have a GZIPFile to provide access to > those > various header fields and individual member set, should request come in. > > Webrev has been updated accordingly. > > #int n = rnd.nextInt(100) % 10 + 1; > > should be just rnd.nextInt(10) + 1. I started with doing 100 of concatenated > gz... > > > #probably should do some cleanup on src, srcBAOS, srcBytes. > #src is written to srcBAOS, then turned back into a byte[], > #which seems pointless to me. > > I use the BAOS to concatenated the byte[] arrays (there are n of src > arrays), don't want to > handle it myself. > > Thanks, > Sherman > > -- > > >> the returned values from readHeader and readTrailer >> should be documented. >> ?-- >> >> 174 ? ? ? ? int n = 10; >> I would write this kind of code as >> int n = 2 + 2 + 6; >> for clarity. >> >> -- >> Probably readHeader should call crc.reset() twice, >> before and after reading the header, >> and then remove all calls to crc.reset() after calling >> readHeader. >> -- >> >> typos: >> OutputStram >> jusr >> -- >> ?38 ? ? ? ? ? ? int n = rnd.nextInt(100) % 10 + 1; >> Isn't this just rnd.nextInt(10) + 1? >> -- >> the test should close gzis. >> -- >> probably should do some cleanup on src, srcBAOS, srcBytes. >> src is written to srcBAOS, then turned back into a byte[], >> which seems pointless to me. >> -- >> >> > > From weijun.wang at sun.com Mon May 24 01:29:40 2010 From: weijun.wang at sun.com (weijun.wang at sun.com) Date: Mon, 24 May 2010 01:29:40 +0000 Subject: hg: jdk7/tl/jdk: 2 new changesets Message-ID: <20100524013013.6619A44542@hg.openjdk.java.net> Changeset: d01726854317 Author: weijun Date: 2010-05-24 09:28 +0800 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/d01726854317 6948803: CertPath validation regression caused by SHA1 replacement root and MD2 disable feature Reviewed-by: xuelei, mullan ! src/share/classes/sun/security/validator/PKIXValidator.java + test/sun/security/validator/CertReplace.java + test/sun/security/validator/certreplace.sh Changeset: c36617d0dae7 Author: weijun Date: 2010-05-24 09:28 +0800 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/c36617d0dae7 6954621: small error in 6948909 Reviewed-by: xuelei ! src/share/classes/sun/security/tools/JarSigner.java From weijun.wang at sun.com Mon May 24 01:38:27 2010 From: weijun.wang at sun.com (weijun.wang at sun.com) Date: Mon, 24 May 2010 01:38:27 +0000 Subject: hg: jdk7/tl/jdk: 2 new changesets Message-ID: <20100524013852.ACB9C44543@hg.openjdk.java.net> Changeset: ff9cc9789bb3 Author: weijun Date: 2010-05-24 09:37 +0800 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/ff9cc9789bb3 6882687: KerberosTime too imprecise Reviewed-by: valeriep ! src/share/classes/sun/security/krb5/internal/KerberosTime.java + test/sun/security/krb5/MicroTime.java Changeset: 625c75559b0d Author: weijun Date: 2010-05-24 09:37 +0800 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/625c75559b0d 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate Reviewed-by: mullan ! src/share/classes/sun/security/provider/X509Factory.java + test/java/security/cert/CertificateFactory/openssl/BadFooter.java From weijun.wang at sun.com Mon May 24 02:05:23 2010 From: weijun.wang at sun.com (weijun.wang at sun.com) Date: Mon, 24 May 2010 02:05:23 +0000 Subject: hg: jdk7/tl/jdk: 6932525: Incorrect encryption types of KDC_REQ_BODY of AS-REQ with pre-authentication Message-ID: <20100524020535.9A34644545@hg.openjdk.java.net> Changeset: ba95fd03440b Author: weijun Date: 2010-05-24 10:05 +0800 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/ba95fd03440b 6932525: Incorrect encryption types of KDC_REQ_BODY of AS-REQ with pre-authentication Reviewed-by: valeriep ! src/share/classes/sun/security/krb5/KrbAsReq.java ! test/sun/security/krb5/auto/KDC.java From xueming.shen at oracle.com Mon May 24 04:42:47 2010 From: xueming.shen at oracle.com (xueming.shen at oracle.com) Date: Mon, 24 May 2010 04:42:47 +0000 Subject: hg: jdk7/tl/jdk: 4691425: GZIPInputStream fails to read concatenated .gz files Message-ID: <20100524044301.91D0E44555@hg.openjdk.java.net> Changeset: 41a5722e6e10 Author: sherman Date: 2010-05-24 00:39 -0400 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/41a5722e6e10 4691425: GZIPInputStream fails to read concatenated .gz files Summary: to support concatenated .gz streams Reviewed-by: martin ! src/share/classes/java/util/zip/GZIPInputStream.java + test/java/util/zip/GZIP/GZIPInputStreamRead.java From ahughes at redhat.com Mon May 24 13:44:59 2010 From: ahughes at redhat.com (Andrew John Hughes) Date: Mon, 24 May 2010 14:44:59 +0100 Subject: Math.log(17197) produces inconsistent results between javac, jit, Math and StrictMath on various architectures. In-Reply-To: <4BFA7726.1030506@zafena.se> References: <4BFA7726.1030506@zafena.se> Message-ID: On 24 May 2010 13:55, Xerxes R?nby wrote: > Hi > > Im hoping to find someone who can enlighten me how to resolve a bug > where some hotspot JITs > fails the hotspot/test/compiler/6539464 jtreg regression test. > > The testcase looks like: > > public class Test { > ? ?static double log_value = 17197; > ? ?static double log_result = Math.log(log_value); > > ? ?public static void main(String[] args) throws Exception { > ? ? ? ?for (int i = 0; i < 1000000; i++) { > ? ? ? ? ? ?double log_result2 = Math.log(log_value); > ? ? ? ? ? ?if (log_result2 != log_result) { > ? ? ? ? ? ? ? ?throw new InternalError("Math.log produces inconsistent results: " + log_result2 + " != " + log_result); > ? ? ? ? ? ?} > ? ? ? ?} > ? ?} > } > > When running this testcase using various jvms / architectures i get varying results of the calculated log_result2 and log_result which > > ARCH+JVM combination ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? log_result (javac) ? ? ?log_result2 (jit) ? ? ? passes regression test? > ia32+OpenJDK Server VM (build 14.0-b16, mixed mode) ? ? ? ? ?9.752490228984199 ? ? ? 9.752490228984199 ? ? ? yes > arm+OpenJDK Shark VM (build 16.0-b13, mixed mode) ? ? ? ? ? ?9.75249022898412 ? ? ? ?9.752490228984199 ? ? ? no > x86_64+OpenJDK 64-Bit Server VM (build 14.0-b16, mixed mode) 9.75249022898412 ? ? ? ?9.752490228984199 ? ? ? no > > While trying to figure out whats the correct result for the log(17197) calculation i tested what StrictMath.log outputs: > StrictMath.log(17197) = 9.75249022898412 > > And in order to get an independent mathematically correct opinion of what log(17197) equals i asked wolfram alpha: > http://www.wolframalpha.com/input/?i=log%2817197%29 > log(17197) = 9.7524902289841994797298917760120602447583441794533189705223... > or in short 9.752490228984199 > > So we have a situation where javac, jit, Math and StrictMath generates inconsistent results. > How do we resolve this situation? > > Quoting the Math package java doc: > "If a method always has an error less than 0.5 ulps, the method always > ?returns the floating-point number nearest the exact result; such a > ?method is correctly rounded. ?A correctly rounded method is > ?generally the best a floating-point approximation can be; however, > ?it is impractical for many floating-point methods to be correctly > ?rounded. ?Instead, for the Math class, a larger error > ?bound of 1 or 2 ulps is allowed for certain methods" > > Would this quotation imply that both log(17197) calculation results above are correct ( 9.752490228984199 and 9.75249022898412 )? > If both calculations are correct then I propose that we should change the hotspot/test/compiler/6539464 jtreg regression test to make all > JVM's pass the test when they are within +- 1 ulps from the mathematically correct answer of: > 9.7524902289841994797298917760120602447583441794533189705223... > > Cheers and have a great day! > Xerxes > > Do x86 and x86_64 give the same results if you actually use the same version of HotSpot as you do on ARM? -- Andrew :-) Free Java Software Engineer Red Hat, Inc. (http://www.redhat.com) Support Free Java! Contribute to GNU Classpath and the OpenJDK http://www.gnu.org/software/classpath http://openjdk.java.net PGP Key: 94EFD9D8 (http://subkeys.pgp.net) Fingerprint: F8EF F1EA 401E 2E60 15FA 7927 142C 2591 94EF D9D8 From xueming.shen at oracle.com Mon May 24 18:38:34 2010 From: xueming.shen at oracle.com (Xueming Shen) Date: Mon, 24 May 2010 11:38:34 -0700 Subject: jar -i Message-ID: <4BFAC7AA.8080809@oracle.com> Martin, Another cleanup. The jar manual [1] clearly indicates the options "cuxti" are exclusive with each other. The check code was missed when the "i" was added in. http://cr.openjdk.java.net/~sherman/4690407/webrev Please help review. #Issue of "-i0" mentioned in the description (tracked in a separate CR#4823701) is no longer reproducible. Thanks, Sherman [1]http://java.sun.com/javase/6/docs/technotes/tools/solaris/jar.html From martinrb at google.com Mon May 24 19:04:58 2010 From: martinrb at google.com (Martin Buchholz) Date: Mon, 24 May 2010 12:04:58 -0700 Subject: jar -i In-Reply-To: <4BFAC7AA.8080809@oracle.com> References: <4BFAC7AA.8080809@oracle.com> Message-ID: Approved! Does this mean that the jar index feature may get some much needed love in the future? Martin On Mon, May 24, 2010 at 11:38, Xueming Shen wrote: > Martin, > > Another cleanup. The jar manual [1] clearly indicates the options "cuxti" > are exclusive with each > other. The check code was missed when the "i" was added in. > > http://cr.openjdk.java.net/~sherman/4690407/webrev > > Please help review. > > #Issue of "-i0" mentioned in the description (tracked in a separate > CR#4823701) is no longer reproducible. > > Thanks, > Sherman > > [1]http://java.sun.com/javase/6/docs/technotes/tools/solaris/jar.html > From xueming.shen at oracle.com Mon May 24 20:44:13 2010 From: xueming.shen at oracle.com (xueming.shen at oracle.com) Date: Mon, 24 May 2010 20:44:13 +0000 Subject: hg: jdk7/tl/jdk: 2 new changesets Message-ID: <20100524204439.666744458A@hg.openjdk.java.net> Changeset: 6df25b528926 Author: sherman Date: 2010-05-24 15:20 -0400 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/6df25b528926 4690407: JAR tool: option -i can't be combined with other options Summary: -i can't combined with cxut, do sanity check on options Reviewed-by: martin ! src/share/classes/sun/tools/jar/Main.java Changeset: d1cf79e27365 Author: sherman Date: 2010-05-24 16:41 -0400 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/d1cf79e27365 Merge From dmytro_sheyko at hotmail.com Tue May 25 06:36:54 2010 From: dmytro_sheyko at hotmail.com (Dmytro Sheyko) Date: Tue, 25 May 2010 13:36:54 +0700 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: <4BF69AFB.8060406@mail.ru> References: , , <4BF2AAEE.1040706@mail.ru>, <4BF3BFFD.8010007@mail.ru>,<4BF3C05C.7010300@mail.ru> , <4BF69AFB.8060406@mail.ru> Message-ID: That's great! Thank you. > Date: Fri, 21 May 2010 18:38:51 +0400 > From: iaroslavski at mail.ru > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > To: dmytro_sheyko at hotmail.com > CC: core-libs-dev at openjdk.java.net > > Hello, > > I prepared version with your changes "Skip the last negative > value (if any) or all leading negative" and with my optimization > for all types. I added two while loops before partitioning to > skip elements, less than pivot1 and greater than pivot2: > > if (pivot1 != pivot2) { > /* ... */ > a[e2] = a[less]; > a[e4] = a[great]; > > ++ while (a[++less] < pivot1); > ++ while (a[--great] > pivot2); > > /* ... */ > outer: > for (int k = less; k <= great; k++) { > ... > } > > Here is benchmark result (in compare with quicksort from JDK 6): > > client server > ------ ------ > previous version: 60.70% 48.20% > current version: 57.22% 46.18% > > So, we win 2-3% ! > > Thank you, > Vladimir > > Dmytro Sheyko wrote: > > Hi Vladimir, > > > > I tried to figure out why the testcase failed on my modification. It > > appeared that number of negative zeros were changed during general sort. > > As I can see you already fixed this issue. Well, my modification was > > based on assumption that we can speed up eliminating explicit array > > range checks. > > However, such assumption is wrong because Hotspot anyway emits range > > checks at its discretion and therefore processZeros generally does not > > work as fast as I expected. > > So complications I made are not worth doing. > > > > As for the latest code you posted. Doesn't it make sense to skip leading > > negative zeros before farther processing? In this case we avoid > > unnecessary assigning +0.0 and then -0.0 to the same location a[k] (i.e. > > where k == p). > > > > /* > > * Skip the last negative value (if any) or all leading negative > > zeros > > */ > > while (left <= right && Double.doubleToRawLongBits(a[left]) < 0) { > > left++; > > } > > > > for (int k = left + 1, p = left; k <= right; k++) { > > double ak = a[k]; > > if (ak != 0.0d) { > > return; > > } > > if (Double.doubleToRawLongBits(ak) < 0) { // ak is -0.0d > > a[k] = 0.0d; > > a[p++] = -0.0d; > > } > > } > > > > Thank you, > > Dmytro Sheyko > > > > > > > Date: Wed, 19 May 2010 14:41:32 +0400 > > > From: iaroslavski at mail.ru > > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > > To: dmytro_sheyko at hotmail.com > > > CC: core-libs-dev at openjdk.java.net > > > > > > resend the class with correct constructor > > > > > > Vladimir Iaroslavski wrote: > > > > Dmytro, > > > > > > > > Thank you for comments, I updated double method, did little bit > > > > javadoc changes and replaced in char/short/byte methods > > > > "fromIndex -> left", "toIndex-1 -> right", the code became > > > > consistent with main sort method and more compact. Also I use > > > > more usual "i--" and "i++" in for loops (instead of "--i", "++i. > > > > > > > > To accent the difference between float/double and other types, > > > > I put comment where it is important: > > > > > > > > /* > > > > * In spite of a[great] == pivot1, the assignment > > > > * a[less++] = pivot1 may be incorrect, if a[great] > > > > * and pivot1 are floating-point zeros of different > > > > * signs, therefore in float/double methods we have > > > > * to use more accurate assignment a[k] = a[great]. > > > > */ > > > > a[less++] = pivot1; > > > > > > > > and for double/float: > > > > > > > > /* > > > > ..... > > > > */ > > > > a[k] = a[great]; > > > > > > > > See updated version in attachment. > > > > > > > > Thank you, > > > > Vladimir > > > > > > > > Dmytro Sheyko wrote: > > > >> Vladimir, > > > >> > > > >> I can see that you changed sortNegZeroAndNaN(float[]...) but probably > > > >> forgot to change sortNegZeroAndNaN(double[]...). > > > >> > > > >> You really puzzled me with failed testcase and note that sorting > > > >> algorithm (without special attention to zeros) generally may change > > > >> number of negative zeros. > > > >> I will provide my comments later. > > > >> > > > >> As for counting sort, I think we should use single format style over > > > >> the file (unless we have valuable reason not to do this). I mean to > > > >> choose > > > >> 1) > > > >> if (toIndex - fromIndex > > > > >> COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > > > >> countingSort(a, fromIndex, toIndex); > > > >> return; > > > >> } > > > >> sort(a, fromIndex, toIndex - 1, true); > > > >> 2) > > > >> if (toIndex - fromIndex > > > > >> COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > > > >> countingSort(a, fromIndex, toIndex); > > > >> } else { > > > >> sort(a, fromIndex, toIndex - 1, true); > > > >> } > > > >> I prefer the second one. > > > >> > > > >> Thanks a lot, > > > >> Dmytro Sheyko > > > >> > > > >> > Date: Tue, 18 May 2010 18:57:50 +0400 > > > >> > From: iaroslavski at mail.ru > > > >> > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > > >> > To: dmytro_sheyko at hotmail.com > > > >> > CC: core-libs-dev at openjdk.java.net > > > >> > > > > >> > Hello, > > > >> > > > > >> > I've run your modification for counting sort, it real faster. > > > >> > I attached new version with your changes (I did little bit > > > >> > format it) and included my case with float/double. > > > >> > > > > >> > Note that you modification doesn't pass test from Sorting class, > > > >> > which I sent earlier. It fails on float/double test: > > > >> > > > > >> > Test #3: random = 666, len = 34, a = 0, g = 6, z = 9, n = 10, p = 9 > > > >> > > > > >> > I suggest shorter method (which is based on your idea to skip > > counting > > > >> > negative zeros on Phase 1.): I found find first zero index (or > > it will > > > >> > be index of first positive element if no zeros at all, or last > > > >> negative, > > > >> > if no positive and zero elements) and then swap negative zero to the > > > >> > beginning of the sub-range. > > > >> > > > > >> > int hi = right; > > > >> > > > > >> > while (left < hi) { > > > >> > int middle = (left + hi) >>> 1; > > > >> > float middleValue = a[middle]; > > > >> > > > > >> > if (middleValue < 0.0f) { > > > >> > left = middle + 1; > > > >> > } else { > > > >> > hi = middle; > > > >> > } > > > >> > } > > > >> > > > > >> > for (int k = left, p = left; k <= right; k++) { > > > >> > float ak = a[k]; > > > >> > if (ak != 0.0f) { > > > >> > return; > > > >> > } > > > >> > if (Float.floatToRawIntBits(ak) < 0) { // ak is -0.0f > > > >> > a[k] = +0.0f; > > > >> > a[p++] = -0.0f; > > > >> > } > > > >> > } > > > >> > > > > >> > Important note: in partitioning loop there are several places > > > >> > (marked by // !) where potential bug with -0.0 could be > > > >> > (when pivot and a[great] are zeros with different signs): > > > >> > > > > >> > if (a[great] == pivot1) { > > > >> > a[k] = a[less]; > > > >> > - a[less++] = pivot1; // ! > > > >> > + a[less++] = a[great]; > > > >> > } else { // pivot1 < a[great] < pivot2 > > > >> > a[k] = a[great]; > > > >> > } > > > >> > - a[great--] = pivot2; // ! > > > >> > + a[great--] = ak; > > > >> > } else if (ak == pivot1) { // Move a[k] to left part > > > >> > a[k] = a[less]; > > > >> > - a[less++] = pivot1; // ! > > > >> > + a[less++] = ak; > > > >> > } > > > >> > > > > >> > and the same in "Pivots are equal" branch. > > > >> > > > > >> > I did changes "pivot1/2 -> ak" in methods for all types > > > >> > and "pivot1 -> a[great]" in float/double sections only. > > > >> > > > > >> > Please, review format changes for counting sort and new version > > > >> > of Phase 3 for float/double. > > > >> > > > > >> > Thank you, > > > >> > Vladimir > > > >> > > > > >> > Dmytro Sheyko wrote: > > > >> > > Hi, > > > >> > > > > > >> > > About counting sort again. > > > >> > > > > > >> > > 1. This condition "i < count.length && k <= right" is excessive. > > > >> Any one > > > >> > > conjunct is enough. "k <= right" seems better. > > > >> > > 2. No need to calculate "short value = (short) (i + > > > >> Short.MIN_VALUE)" > > > >> > > when "count[i]" is zero. > > > >> > > 3. For signed primitives (byte and short) we would better loop > > > >> backward. > > > >> > > Thanks to "k >= fromIndex" condition we will quit looping earlier > > > >> > > assuming that typically we work with positive numbers. > > > >> > > For unsigned primitives (char) we would better loop forward > > because > > > >> > > typically we work with characters about zero (ASCII). > > > >> > > > > > >> > > - for (int i = 0, k = left; i < count.length && k <= right; i++) { > > > >> > > - short value = (short) (i + Short.MIN_VALUE); > > > >> > > - for (int s = count[i]; s > 0; s--) { > > > >> > > - a[k++] = value; > > > >> > > - } > > > >> > > - } > > > >> > > > > > >> > > + for (int i = NUM_SHORT_VALUES - 1, k = toIndex - 1; k >= > > > >> > > fromIndex; --i) { > > > >> > > + while (count[i] == 0) --i; > > > >> > > + short value = (short) (i + Short.MIN_VALUE); > > > >> > > + int s = count[i]; > > > >> > > + do { a[k--] = value; } while (--s > 0); > > > >> > > + } > > > >> > > > > > >> > > Thanks, > > > >> > > Dmytro Sheyko > > > >> > > > > > >> > > > From: iaroslavski at mail.ru > > > >> > > > To: dmytro_sheyko at hotmail.com > > > >> > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > >> > > > Subject: Re[2]: New portion of improvements for Dual-Pivot > > > >> Quicksort > > > >> > > > Date: Tue, 18 May 2010 01:11:19 +0400 > > > >> > > > > > > >> > > > Sounds good! > > > >> > > > Will consider too... > > > >> > > > > > > >> > > > Mon, 17 May 2010 22:24:11 +0700 ?????? ?? Dmytro Sheyko > > > >> > > : > > > >> > > > > > > >> > > > > Hi, > > > >> > > > > > > > >> > > > > Regarding counting sort. We can check whether we should > > > >> switch to > > > >> > > counting sort only once in the beginning. > > > >> > > > > > > > >> > > > > > Date: Mon, 17 May 2010 17:30:37 +0400 > > > >> > > > > > From: iaroslavski at mail.ru > > > >> > > > > > Subject: Re: New portion of improvements for Dual-Pivot > > > >> Quicksort > > > >> > > > > > To: dmytro_sheyko at hotmail.com > > > >> > > > > > CC: core-libs-dev at openjdk.java.net > > > >> > > > > > > > > >> > > > > > Hello, > > > >> > > > > > > > > >> > > > > > Thank you for review, I'll check and run tests again > > with you > > > >> > > changes. > > > >> > > > > > > > > >> > > > > > Thank you, > > > >> > > > > > Vladimir > > > >> > > > > > > > > >> > > > > > Dmytro Sheyko wrote: > > > >> > > > > > > Hello, > > > >> > > > > > > > > > >> > > > > > > More ideas. > > > >> > > > > > > > > > >> > > > > > > 1. We can use > > > >> > > > > > > Double.doubleToRawLongBits instead of > > > >> Double.doubleToLongBits and > > > >> > > > > > > Float.floatToRawIntBits instead of Float.floatToIntBits. > > > >> > > > > > > No need to handle NaN's because they all are placed to > > > >> the end > > > >> > > of array. > > > >> > > > > > > > > > >> > > > > > > 2. Note that > > > >> > > > > > > Double.doubleToRawLongBits(+0.0) == 0L and > > > >> > > > > > > Double.doubleToRawLongBits(-0.0) == Long.MIN_VALUE and > > > >> > > > > > > Float.floatToRawIntBits(+0.0) == 0 and > > > >> > > > > > > Float.floatToRawIntBits(-0.0) == Integer.MIN_VALUE. > > > >> > > > > > > > > > >> > > > > > > Comparing with is zero usually more efficient (or at > > > >> least not > > > >> > > worse) > > > >> > > > > > > than with other values. Thus such pattern > > > >> > > > > > > > > > >> > > > > > > if (ak == 0.0f && NEGATIVE_ZERO == > > Float.floatToIntBits(ak)) > > > >> > > > > > > > > > >> > > > > > > can be replaced with > > > >> > > > > > > > > > >> > > > > > > if (ak == 0.0f && Float.floatToIntBits(ak) < 0) > > > >> > > > > > > > > > >> > > > > > > 3. It would be more efficient to count negative zeros > > after > > > >> > > sorting. > > > >> > > > > > > General sorting algorithm puts both negative and positive > > > >> zeros > > > >> > > together > > > >> > > > > > > (but maybe not in right order). > > > >> > > > > > > Therefore we have to process less elements because > > > >> usually we > > > >> > > have less > > > >> > > > > > > zeros than other numbers. > > > >> > > > > > > > > > >> > > > > > > Thanks, > > > >> > > > > > > Dmytro Sheyko > > > >> > > > > > > > > > >> > > > > > > > From: iaroslavski at mail.ru > > > >> > > > > > > > To: dmytro_sheyko at hotmail.com; jjb at google.com > > > >> > > > > > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > >> > > > > > > > Subject: Re[6]: New portion of improvements for > > Dual-Pivot > > > >> > > Quicksort > > > >> > > > > > > > Date: Fri, 14 May 2010 23:54:06 +0400 > > > >> > > > > > > > > > > >> > > > > > > > Hello, > > > >> > > > > > > > > > > >> > > > > > > > I've updated the class, please, review the changes. > > > >> > > > > > > > > > > >> > > > > > > > Vladimir > > > >> > > > > > > > > > > >> > > > > > > > Fri, 14 May 2010 01:48:11 +0700 ?????? ?? Dmytro Sheyko > > > >> > > > > > > : > > > >> > > > > > > > > > > >> > > > > > > > > Yes. I prefer F (Find First zero using binary search) > > > >> over > > > >> > > C (Count > > > >> > > > > > > negatives) and S (Smart Scan for zero). > > > >> > > > > > > > > > > > >> > > > > > > > > > From: iaroslavski at mail.ru > > > >> > > > > > > > > > To: dmytro_sheyko at hotmail.com > > > >> > > > > > > > > > CC: jjb at google.com; core-libs-dev at openjdk.java.net; > > > >> > > > > > > iaroslavski at mail.ru > > > >> > > > > > > > > > Subject: Re[4]: New portion of improvements for > > > >> > > Dual-Pivot Quicksort > > > >> > > > > > > > > > Date: Thu, 13 May 2010 21:34:54 +0400 > > > >> > > > > > > > > > > > > >> > > > > > > > > > Dmytro, > > > >> > > > > > > > > > > > > >> > > > > > > > > > I've tested your suggested variants, and found that > > > >> case "C" > > > >> > > > > > > > > > (very interesting approach to find first position > > > >> of zero > > > >> > > > > > > > > > by counting negative elements) works slower than > > > >> original > > > >> > > > > > > > > > or two other cases. > > > >> > > > > > > > > > > > > >> > > > > > > > > > Implementations "F" and "S" are very close to each > > > >> other > > > >> > > > > > > > > > and little bit faster than original. I prefer case > > > >> "F": > > > >> > > > > > > > > > it is shorter and more clear. Do you agree? > > > >> > > > > > > > > > > > > >> > > > > > > > > > I'll prepare updated DualPivotQuicksort file and > > > >> send it > > > >> > > > > > > > > > tomorrow. > > > >> > > > > > > > > > > > > >> > > > > > > > > > Thank you, > > > >> > > > > > > > > > Vladimir > > > >> > > > > > > > > > > > > >> > > > > > > > > > Wed, 12 May 2010 17:04:52 +0700 ?????? ?? Dmytro > > > >> Sheyko > > > >> > > > > > > : > > > >> > > > > > > > > > > > > >> > > > > > > > > > > Vladimir, > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > Your changes are good for me. > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > Additionally I have some comments/proposals > > > >> regarding > > > >> > > dealing > > > >> > > > > > > with negative zeros. > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > 1. Scanning for the first zero we can avoid range > > > >> check > > > >> > > (i >= > > > >> > > > > > > left) if we have at least one negative value. > > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > > 09:04:19 2010 > > > >> > > > > > > > > > > +++ DualPivotQuicksortS.java Wed May 12 12:10:46 > > > >> 2010 > > > >> > > > > > > > > > > @@ -1705,10 +1705,15 @@ > > > >> > > > > > > > > > > } > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > >> > > > > > > > > > > + int zeroIndex = 0; > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == > > > >> > > 0.0f; i--) { > > > >> > > > > > > > > > > - zeroIndex = i; > > > >> > > > > > > > > > > + if (a[left] < 0.0f) { > > > >> > > > > > > > > > > + zeroIndex = findAnyZero(a, left, n); > > > >> > > > > > > > > > > + > > > >> > > > > > > > > > > + // there is at least one negative value, so > > range > > > >> > > check is > > > >> > > > > > > not needed > > > >> > > > > > > > > > > + for (int i = zeroIndex - 1; /*i >= left &&*/ > > > >> a[i] == > > > >> > > 0.0f; i--) { > > > >> > > > > > > > > > > + zeroIndex = i; > > > >> > > > > > > > > > > + } > > > >> > > > > > > > > > > } > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > // Turn the right number of positive zeros > > back into > > > >> > > negative zeros > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > 2. We can find the position of the first zero by > > > >> counting > > > >> > > > > > > negative values during preprocessing phase. > > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > > 09:04:19 2010 > > > >> > > > > > > > > > > +++ DualPivotQuicksortC.java Wed May 12 12:01:24 > > > >> 2010 > > > >> > > > > > > > > > > @@ -1678,7 +1678,7 @@ > > > >> > > > > > > > > > > * Phase 1: Count negative zeros and move NaNs to > > > >> end of > > > >> > > array. > > > >> > > > > > > > > > > */ > > > >> > > > > > > > > > > final int NEGATIVE_ZERO = > > > >> Float.floatToIntBits(-0.0f); > > > >> > > > > > > > > > > - int numNegativeZeros = 0; > > > >> > > > > > > > > > > + int numNegativeZeros = 0, numNegativeValues = 0; > > > >> > > > > > > > > > > int n = right; > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > for (int k = left; k <= n; k++) { > > > >> > > > > > > > > > > @@ -1689,6 +1689,8 @@ > > > >> > > > > > > > > > > } else if (ak != ak) { // i.e., ak is NaN > > > >> > > > > > > > > > > a[k--] = a[n]; > > > >> > > > > > > > > > > a[n--] = Float.NaN; > > > >> > > > > > > > > > > + } else if (ak < 0.0f) { > > > >> > > > > > > > > > > + numNegativeValues++; > > > >> > > > > > > > > > > } > > > >> > > > > > > > > > > } > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > @@ -1705,7 +1707,7 @@ > > > >> > > > > > > > > > > } > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > >> > > > > > > > > > > + int zeroIndex = numNegativeValues; > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > for (int i = zeroIndex - 1; i >= left && a[i] == > > > >> 0.0f; > > > >> > > i--) { > > > >> > > > > > > > > > > zeroIndex = i; > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > 3. We can use binary search to find the first > > > >> zero and > > > >> > > thus > > > >> > > > > > > avoid linear scan. > > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > > 09:04:19 2010 > > > >> > > > > > > > > > > +++ DualPivotQuicksortF.java Wed May 12 12:03:58 > > > >> 2010 > > > >> > > > > > > > > > > @@ -1705,11 +1705,7 @@ > > > >> > > > > > > > > > > } > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > >> > > > > > > > > > > - > > > >> > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && a[i] == > > > >> > > 0.0f; i--) { > > > >> > > > > > > > > > > - zeroIndex = i; > > > >> > > > > > > > > > > - } > > > >> > > > > > > > > > > + int zeroIndex = findFirstZero(a, left, n); > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > // Turn the right number of positive zeros > > back into > > > >> > > negative zeros > > > >> > > > > > > > > > > for (int i = zeroIndex, m = zeroIndex + > > > >> > > numNegativeZeros; i < > > > >> > > > > > > m; i++) { > > > >> > > > > > > > > > > @@ -1718,7 +1714,7 @@ > > > >> > > > > > > > > > > } > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > /** > > > >> > > > > > > > > > > - * Returns the index of some zero element in the > > > >> > > specified > > > >> > > > > > > range via > > > >> > > > > > > > > > > + * Returns the index of the first zero element > > > >> in the > > > >> > > > > > > specified range via > > > >> > > > > > > > > > > * binary search. The range is assumed to be > > > >> sorted, and > > > >> > > must > > > >> > > > > > > contain > > > >> > > > > > > > > > > * at least one zero. > > > >> > > > > > > > > > > * > > > >> > > > > > > > > > > @@ -1726,18 +1722,17 @@ > > > >> > > > > > > > > > > * @param low the index of the first element, > > > >> inclusive, > > > >> > > to be > > > >> > > > > > > searched > > > >> > > > > > > > > > > * @param high the index of the last element, > > > >> inclusive, > > > >> > > to be > > > >> > > > > > > searched > > > >> > > > > > > > > > > */ > > > >> > > > > > > > > > > - private static int findAnyZero(float[] a, > > int low, > > > >> > > int high) { > > > >> > > > > > > > > > > - while (true) { > > > >> > > > > > > > > > > + private static int findFirstZero(float[] a, int > > > >> low, > > > >> > > int high) { > > > >> > > > > > > > > > > + while (low < high) { > > > >> > > > > > > > > > > int middle = (low + high) >>> 1; > > > >> > > > > > > > > > > float middleValue = a[middle]; > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > if (middleValue < 0.0f) { > > > >> > > > > > > > > > > low = middle + 1; > > > >> > > > > > > > > > > - } else if (middleValue > 0.0f) { > > > >> > > > > > > > > > > - high = middle - 1; > > > >> > > > > > > > > > > - } else { // middleValue == 0.0f > > > >> > > > > > > > > > > - return middle; > > > >> > > > > > > > > > > + } else { // middleValue >= 0.0f > > > >> > > > > > > > > > > + high = middle; > > > >> > > > > > > > > > > } > > > >> > > > > > > > > > > + return low; > > > >> > > > > > > > > > > } > > > >> > > > > > > > > > > } > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > Counting negative values appeared more expensive > > > >> than > > > >> > > any other > > > >> > > > > > > variants. > > > >> > > > > > > > > > > The last proposal seems to me as efficient as the > > > >> current > > > >> > > > > > > solution is in its worst case - when we have only one > > > >> negative > > > >> > > zero (in > > > >> > > > > > > the half of array). > > > >> > > > > > > > > > > And it shows the best result if we have many > > zeros. > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > Regards, > > > >> > > > > > > > > > > Dmytro Sheyko > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > From: iaroslavski at mail.ru > > > >> > > > > > > > > > > > To: jjb at google.com; dmytro_sheyko at hotmail.com > > > >> > > > > > > > > > > > CC: core-libs-dev at openjdk.java.net; > > > >> iaroslavski at mail.ru > > > >> > > > > > > > > > > > Subject: Re[2]: New portion of improvements for > > > >> > > Dual-Pivot > > > >> > > > > > > Quicksort > > > >> > > > > > > > > > > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > > Josh, > > > >> > > > > > > > > > > > Dmytro, > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > > I have done more thoroughly testing "great - > > > >> less > 5 * > > > >> > > > > > > seventh" vs. "less < e1 && great > e5", > > > >> > > > > > > > > > > > and found that more symmetric code "less < e1 && > > > >> > > great > e5" > > > >> > > > > > > is little bit faster, ~0.5..0.7% > > > >> > > > > > > > > > > > on both VMs. Other code has not been changed. > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > > Please, take the latest version in attachment. > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > > Vladimir > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? Joshua > > > >> Bloch > > > >> > > > > > > : > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > > > Vladimir, > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > > > Old: > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > > >298 if (less < e1 && great > e5) { > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > > > New: > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > > >256 if (great - less > 5 * seventh) { > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > > >Regards, > > > >> > > > > > > > > > > > >Josh _________________________________________________________________ Hotmail: Free, trusted and rich email service. https://signup.live.com/signup.aspx?id=60969 -------------- next part -------------- An HTML attachment was scrubbed... URL: From iaroslavski at mail.ru Tue May 25 06:42:51 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Tue, 25 May 2010 10:42:51 +0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: <4BF2AAEE.1040706@mail.ru> <4BF3BFFD.8010007@mail.ru> <4BF3C05C.7010300@mail.ru> <4BF69AFB.8060406@mail.ru> Message-ID: <4BFB716B.4020107@mail.ru> I added more comments, please, review attached version. >> So, we win 2-3% ! On [partial] sorted inputs new version runs more faster than few percents: organ pipes this: 6896 prev: 7424 jdk7: 8018 jdk6: 12502 ascendant this: 2877 prev: 3845 jdk7: 4583 jdk6: 9019 descendant this: 3287 prev: 4110 jdk7: 4897 jdk6: 9132 Dmytro Sheyko wrote: > That's great! Thank you. > > > Date: Fri, 21 May 2010 18:38:51 +0400 > > From: iaroslavski at mail.ru > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > To: dmytro_sheyko at hotmail.com > > CC: core-libs-dev at openjdk.java.net > > > > Hello, > > > > I prepared version with your changes "Skip the last negative > > value (if any) or all leading negative" and with my optimization > > for all types. I added two while loops before partitioning to > > skip elements, less than pivot1 and greater than pivot2: > > > > if (pivot1 != pivot2) { > > /* ... */ > > a[e2] = a[less]; > > a[e4] = a[great]; > > > > ++ while (a[++less] < pivot1); > > ++ while (a[--great] > pivot2); > > > > /* ... */ > > outer: > > for (int k = less; k <= great; k++) { > > ... > > } > > > > Here is benchmark result (in compare with quicksort from JDK 6): > > > > client server > > ------ ------ > > previous version: 60.70% 48.20% > > current version: 57.22% 46.18% > > > > So, we win 2-3% ! > > > > Thank you, > > Vladimir > > > > Dmytro Sheyko wrote: > > > Hi Vladimir, > > > > > > I tried to figure out why the testcase failed on my modification. It > > > appeared that number of negative zeros were changed during general > sort. > > > As I can see you already fixed this issue. Well, my modification was > > > based on assumption that we can speed up eliminating explicit array > > > range checks. > > > However, such assumption is wrong because Hotspot anyway emits range > > > checks at its discretion and therefore processZeros generally does not > > > work as fast as I expected. > > > So complications I made are not worth doing. > > > > > > As for the latest code you posted. Doesn't it make sense to skip > leading > > > negative zeros before farther processing? In this case we avoid > > > unnecessary assigning +0.0 and then -0.0 to the same location a[k] > (i.e. > > > where k == p). > > > > > > /* > > > * Skip the last negative value (if any) or all leading negative > > > zeros > > > */ > > > while (left <= right && Double.doubleToRawLongBits(a[left]) < 0) { > > > left++; > > > } > > > > > > for (int k = left + 1, p = left; k <= right; k++) { > > > double ak = a[k]; > > > if (ak != 0.0d) { > > > return; > > > } > > > if (Double.doubleToRawLongBits(ak) < 0) { // ak is -0.0d > > > a[k] = 0.0d; > > > a[p++] = -0.0d; > > > } > > > } > > > > > > Thank you, > > > Dmytro Sheyko > > > > > > > > > > Date: Wed, 19 May 2010 14:41:32 +0400 > > > > From: iaroslavski at mail.ru > > > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > > > To: dmytro_sheyko at hotmail.com > > > > CC: core-libs-dev at openjdk.java.net > > > > > > > > resend the class with correct constructor > > > > > > > > Vladimir Iaroslavski wrote: > > > > > Dmytro, > > > > > > > > > > Thank you for comments, I updated double method, did little bit > > > > > javadoc changes and replaced in char/short/byte methods > > > > > "fromIndex -> left", "toIndex-1 -> right", the code became > > > > > consistent with main sort method and more compact. Also I use > > > > > more usual "i--" and "i++" in for loops (instead of "--i", "++i. > > > > > > > > > > To accent the difference between float/double and other types, > > > > > I put comment where it is important: > > > > > > > > > > /* > > > > > * In spite of a[great] == pivot1, the assignment > > > > > * a[less++] = pivot1 may be incorrect, if a[great] > > > > > * and pivot1 are floating-point zeros of different > > > > > * signs, therefore in float/double methods we have > > > > > * to use more accurate assignment a[k] = a[great]. > > > > > */ > > > > > a[less++] = pivot1; > > > > > > > > > > and for double/float: > > > > > > > > > > /* > > > > > ..... > > > > > */ > > > > > a[k] = a[great]; > > > > > > > > > > See updated version in attachment. > > > > > > > > > > Thank you, > > > > > Vladimir > > > > > > > > > > Dmytro Sheyko wrote: > > > > >> Vladimir, > > > > >> > > > > >> I can see that you changed sortNegZeroAndNaN(float[]...) but > probably > > > > >> forgot to change sortNegZeroAndNaN(double[]...). > > > > >> > > > > >> You really puzzled me with failed testcase and note that sorting > > > > >> algorithm (without special attention to zeros) generally may > change > > > > >> number of negative zeros. > > > > >> I will provide my comments later. > > > > >> > > > > >> As for counting sort, I think we should use single format > style over > > > > >> the file (unless we have valuable reason not to do this). I > mean to > > > > >> choose > > > > >> 1) > > > > >> if (toIndex - fromIndex > > > > > >> COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > > > > >> countingSort(a, fromIndex, toIndex); > > > > >> return; > > > > >> } > > > > >> sort(a, fromIndex, toIndex - 1, true); > > > > >> 2) > > > > >> if (toIndex - fromIndex > > > > > >> COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > > > > >> countingSort(a, fromIndex, toIndex); > > > > >> } else { > > > > >> sort(a, fromIndex, toIndex - 1, true); > > > > >> } > > > > >> I prefer the second one. > > > > >> > > > > >> Thanks a lot, > > > > >> Dmytro Sheyko > > > > >> > > > > >> > Date: Tue, 18 May 2010 18:57:50 +0400 > > > > >> > From: iaroslavski at mail.ru > > > > >> > Subject: Re: New portion of improvements for Dual-Pivot > Quicksort > > > > >> > To: dmytro_sheyko at hotmail.com > > > > >> > CC: core-libs-dev at openjdk.java.net > > > > >> > > > > > >> > Hello, > > > > >> > > > > > >> > I've run your modification for counting sort, it real faster. > > > > >> > I attached new version with your changes (I did little bit > > > > >> > format it) and included my case with float/double. > > > > >> > > > > > >> > Note that you modification doesn't pass test from Sorting class, > > > > >> > which I sent earlier. It fails on float/double test: > > > > >> > > > > > >> > Test #3: random = 666, len = 34, a = 0, g = 6, z = 9, n = > 10, p = 9 > > > > >> > > > > > >> > I suggest shorter method (which is based on your idea to skip > > > counting > > > > >> > negative zeros on Phase 1.): I found find first zero index (or > > > it will > > > > >> > be index of first positive element if no zeros at all, or last > > > > >> negative, > > > > >> > if no positive and zero elements) and then swap negative > zero to the > > > > >> > beginning of the sub-range. > > > > >> > > > > > >> > int hi = right; > > > > >> > > > > > >> > while (left < hi) { > > > > >> > int middle = (left + hi) >>> 1; > > > > >> > float middleValue = a[middle]; > > > > >> > > > > > >> > if (middleValue < 0.0f) { > > > > >> > left = middle + 1; > > > > >> > } else { > > > > >> > hi = middle; > > > > >> > } > > > > >> > } > > > > >> > > > > > >> > for (int k = left, p = left; k <= right; k++) { > > > > >> > float ak = a[k]; > > > > >> > if (ak != 0.0f) { > > > > >> > return; > > > > >> > } > > > > >> > if (Float.floatToRawIntBits(ak) < 0) { // ak is -0.0f > > > > >> > a[k] = +0.0f; > > > > >> > a[p++] = -0.0f; > > > > >> > } > > > > >> > } > > > > >> > > > > > >> > Important note: in partitioning loop there are several places > > > > >> > (marked by // !) where potential bug with -0.0 could be > > > > >> > (when pivot and a[great] are zeros with different signs): > > > > >> > > > > > >> > if (a[great] == pivot1) { > > > > >> > a[k] = a[less]; > > > > >> > - a[less++] = pivot1; // ! > > > > >> > + a[less++] = a[great]; > > > > >> > } else { // pivot1 < a[great] < pivot2 > > > > >> > a[k] = a[great]; > > > > >> > } > > > > >> > - a[great--] = pivot2; // ! > > > > >> > + a[great--] = ak; > > > > >> > } else if (ak == pivot1) { // Move a[k] to left part > > > > >> > a[k] = a[less]; > > > > >> > - a[less++] = pivot1; // ! > > > > >> > + a[less++] = ak; > > > > >> > } > > > > >> > > > > > >> > and the same in "Pivots are equal" branch. > > > > >> > > > > > >> > I did changes "pivot1/2 -> ak" in methods for all types > > > > >> > and "pivot1 -> a[great]" in float/double sections only. > > > > >> > > > > > >> > Please, review format changes for counting sort and new version > > > > >> > of Phase 3 for float/double. > > > > >> > > > > > >> > Thank you, > > > > >> > Vladimir > > > > >> > > > > > >> > Dmytro Sheyko wrote: > > > > >> > > Hi, > > > > >> > > > > > > >> > > About counting sort again. > > > > >> > > > > > > >> > > 1. This condition "i < count.length && k <= right" is > excessive. > > > > >> Any one > > > > >> > > conjunct is enough. "k <= right" seems better. > > > > >> > > 2. No need to calculate "short value = (short) (i + > > > > >> Short.MIN_VALUE)" > > > > >> > > when "count[i]" is zero. > > > > >> > > 3. For signed primitives (byte and short) we would better loop > > > > >> backward. > > > > >> > > Thanks to "k >= fromIndex" condition we will quit looping > earlier > > > > >> > > assuming that typically we work with positive numbers. > > > > >> > > For unsigned primitives (char) we would better loop forward > > > because > > > > >> > > typically we work with characters about zero (ASCII). > > > > >> > > > > > > >> > > - for (int i = 0, k = left; i < count.length && k <= > right; i++) { > > > > >> > > - short value = (short) (i + Short.MIN_VALUE); > > > > >> > > - for (int s = count[i]; s > 0; s--) { > > > > >> > > - a[k++] = value; > > > > >> > > - } > > > > >> > > - } > > > > >> > > > > > > >> > > + for (int i = NUM_SHORT_VALUES - 1, k = toIndex - 1; k >= > > > > >> > > fromIndex; --i) { > > > > >> > > + while (count[i] == 0) --i; > > > > >> > > + short value = (short) (i + Short.MIN_VALUE); > > > > >> > > + int s = count[i]; > > > > >> > > + do { a[k--] = value; } while (--s > 0); > > > > >> > > + } > > > > >> > > > > > > >> > > Thanks, > > > > >> > > Dmytro Sheyko > > > > >> > > > > > > >> > > > From: iaroslavski at mail.ru > > > > >> > > > To: dmytro_sheyko at hotmail.com > > > > >> > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > > >> > > > Subject: Re[2]: New portion of improvements for Dual-Pivot > > > > >> Quicksort > > > > >> > > > Date: Tue, 18 May 2010 01:11:19 +0400 > > > > >> > > > > > > > >> > > > Sounds good! > > > > >> > > > Will consider too... > > > > >> > > > > > > > >> > > > Mon, 17 May 2010 22:24:11 +0700 ?????? ?? Dmytro Sheyko > > > > >> > > : > > > > >> > > > > > > > >> > > > > Hi, > > > > >> > > > > > > > > >> > > > > Regarding counting sort. We can check whether we should > > > > >> switch to > > > > >> > > counting sort only once in the beginning. > > > > >> > > > > > > > > >> > > > > > Date: Mon, 17 May 2010 17:30:37 +0400 > > > > >> > > > > > From: iaroslavski at mail.ru > > > > >> > > > > > Subject: Re: New portion of improvements for Dual-Pivot > > > > >> Quicksort > > > > >> > > > > > To: dmytro_sheyko at hotmail.com > > > > >> > > > > > CC: core-libs-dev at openjdk.java.net > > > > >> > > > > > > > > > >> > > > > > Hello, > > > > >> > > > > > > > > > >> > > > > > Thank you for review, I'll check and run tests again > > > with you > > > > >> > > changes. > > > > >> > > > > > > > > > >> > > > > > Thank you, > > > > >> > > > > > Vladimir > > > > >> > > > > > > > > > >> > > > > > Dmytro Sheyko wrote: > > > > >> > > > > > > Hello, > > > > >> > > > > > > > > > > >> > > > > > > More ideas. > > > > >> > > > > > > > > > > >> > > > > > > 1. We can use > > > > >> > > > > > > Double.doubleToRawLongBits instead of > > > > >> Double.doubleToLongBits and > > > > >> > > > > > > Float.floatToRawIntBits instead of > Float.floatToIntBits. > > > > >> > > > > > > No need to handle NaN's because they all are placed to > > > > >> the end > > > > >> > > of array. > > > > >> > > > > > > > > > > >> > > > > > > 2. Note that > > > > >> > > > > > > Double.doubleToRawLongBits(+0.0) == 0L and > > > > >> > > > > > > Double.doubleToRawLongBits(-0.0) == Long.MIN_VALUE and > > > > >> > > > > > > Float.floatToRawIntBits(+0.0) == 0 and > > > > >> > > > > > > Float.floatToRawIntBits(-0.0) == Integer.MIN_VALUE. > > > > >> > > > > > > > > > > >> > > > > > > Comparing with is zero usually more efficient (or at > > > > >> least not > > > > >> > > worse) > > > > >> > > > > > > than with other values. Thus such pattern > > > > >> > > > > > > > > > > >> > > > > > > if (ak == 0.0f && NEGATIVE_ZERO == > > > Float.floatToIntBits(ak)) > > > > >> > > > > > > > > > > >> > > > > > > can be replaced with > > > > >> > > > > > > > > > > >> > > > > > > if (ak == 0.0f && Float.floatToIntBits(ak) < 0) > > > > >> > > > > > > > > > > >> > > > > > > 3. It would be more efficient to count negative zeros > > > after > > > > >> > > sorting. > > > > >> > > > > > > General sorting algorithm puts both negative and > positive > > > > >> zeros > > > > >> > > together > > > > >> > > > > > > (but maybe not in right order). > > > > >> > > > > > > Therefore we have to process less elements because > > > > >> usually we > > > > >> > > have less > > > > >> > > > > > > zeros than other numbers. > > > > >> > > > > > > > > > > >> > > > > > > Thanks, > > > > >> > > > > > > Dmytro Sheyko > > > > >> > > > > > > > > > > >> > > > > > > > From: iaroslavski at mail.ru > > > > >> > > > > > > > To: dmytro_sheyko at hotmail.com; jjb at google.com > > > > >> > > > > > > > CC: core-libs-dev at openjdk.java.net; > iaroslavski at mail.ru > > > > >> > > > > > > > Subject: Re[6]: New portion of improvements for > > > Dual-Pivot > > > > >> > > Quicksort > > > > >> > > > > > > > Date: Fri, 14 May 2010 23:54:06 +0400 > > > > >> > > > > > > > > > > > >> > > > > > > > Hello, > > > > >> > > > > > > > > > > > >> > > > > > > > I've updated the class, please, review the changes. > > > > >> > > > > > > > > > > > >> > > > > > > > Vladimir > > > > >> > > > > > > > > > > > >> > > > > > > > Fri, 14 May 2010 01:48:11 +0700 ?????? ?? Dmytro > Sheyko > > > > >> > > > > > > : > > > > >> > > > > > > > > > > > >> > > > > > > > > Yes. I prefer F (Find First zero using binary > search) > > > > >> over > > > > >> > > C (Count > > > > >> > > > > > > negatives) and S (Smart Scan for zero). > > > > >> > > > > > > > > > > > > >> > > > > > > > > > From: iaroslavski at mail.ru > > > > >> > > > > > > > > > To: dmytro_sheyko at hotmail.com > > > > >> > > > > > > > > > CC: jjb at google.com; > core-libs-dev at openjdk.java.net; > > > > >> > > > > > > iaroslavski at mail.ru > > > > >> > > > > > > > > > Subject: Re[4]: New portion of improvements for > > > > >> > > Dual-Pivot Quicksort > > > > >> > > > > > > > > > Date: Thu, 13 May 2010 21:34:54 +0400 > > > > >> > > > > > > > > > > > > > >> > > > > > > > > > Dmytro, > > > > >> > > > > > > > > > > > > > >> > > > > > > > > > I've tested your suggested variants, and > found that > > > > >> case "C" > > > > >> > > > > > > > > > (very interesting approach to find first > position > > > > >> of zero > > > > >> > > > > > > > > > by counting negative elements) works slower than > > > > >> original > > > > >> > > > > > > > > > or two other cases. > > > > >> > > > > > > > > > > > > > >> > > > > > > > > > Implementations "F" and "S" are very close > to each > > > > >> other > > > > >> > > > > > > > > > and little bit faster than original. I > prefer case > > > > >> "F": > > > > >> > > > > > > > > > it is shorter and more clear. Do you agree? > > > > >> > > > > > > > > > > > > > >> > > > > > > > > > I'll prepare updated DualPivotQuicksort file and > > > > >> send it > > > > >> > > > > > > > > > tomorrow. > > > > >> > > > > > > > > > > > > > >> > > > > > > > > > Thank you, > > > > >> > > > > > > > > > Vladimir > > > > >> > > > > > > > > > > > > > >> > > > > > > > > > Wed, 12 May 2010 17:04:52 +0700 ?????? ?? Dmytro > > > > >> Sheyko > > > > >> > > > > > > : > > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > Vladimir, > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > Your changes are good for me. > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > Additionally I have some comments/proposals > > > > >> regarding > > > > >> > > dealing > > > > >> > > > > > > with negative zeros. > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > 1. Scanning for the first zero we can > avoid range > > > > >> check > > > > >> > > (i >= > > > > >> > > > > > > left) if we have at least one negative value. > > > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > > > 09:04:19 2010 > > > > >> > > > > > > > > > > +++ DualPivotQuicksortS.java Wed May 12 > 12:10:46 > > > > >> 2010 > > > > >> > > > > > > > > > > @@ -1705,10 +1705,15 @@ > > > > >> > > > > > > > > > > } > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > >> > > > > > > > > > > + int zeroIndex = 0; > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && > a[i] == > > > > >> > > 0.0f; i--) { > > > > >> > > > > > > > > > > - zeroIndex = i; > > > > >> > > > > > > > > > > + if (a[left] < 0.0f) { > > > > >> > > > > > > > > > > + zeroIndex = findAnyZero(a, left, n); > > > > >> > > > > > > > > > > + > > > > >> > > > > > > > > > > + // there is at least one negative value, so > > > range > > > > >> > > check is > > > > >> > > > > > > not needed > > > > >> > > > > > > > > > > + for (int i = zeroIndex - 1; /*i >= left &&*/ > > > > >> a[i] == > > > > >> > > 0.0f; i--) { > > > > >> > > > > > > > > > > + zeroIndex = i; > > > > >> > > > > > > > > > > + } > > > > >> > > > > > > > > > > } > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > // Turn the right number of positive zeros > > > back into > > > > >> > > negative zeros > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > 2. We can find the position of the first > zero by > > > > >> counting > > > > >> > > > > > > negative values during preprocessing phase. > > > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > > > 09:04:19 2010 > > > > >> > > > > > > > > > > +++ DualPivotQuicksortC.java Wed May 12 > 12:01:24 > > > > >> 2010 > > > > >> > > > > > > > > > > @@ -1678,7 +1678,7 @@ > > > > >> > > > > > > > > > > * Phase 1: Count negative zeros and move > NaNs to > > > > >> end of > > > > >> > > array. > > > > >> > > > > > > > > > > */ > > > > >> > > > > > > > > > > final int NEGATIVE_ZERO = > > > > >> Float.floatToIntBits(-0.0f); > > > > >> > > > > > > > > > > - int numNegativeZeros = 0; > > > > >> > > > > > > > > > > + int numNegativeZeros = 0, > numNegativeValues = 0; > > > > >> > > > > > > > > > > int n = right; > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > for (int k = left; k <= n; k++) { > > > > >> > > > > > > > > > > @@ -1689,6 +1689,8 @@ > > > > >> > > > > > > > > > > } else if (ak != ak) { // i.e., ak is NaN > > > > >> > > > > > > > > > > a[k--] = a[n]; > > > > >> > > > > > > > > > > a[n--] = Float.NaN; > > > > >> > > > > > > > > > > + } else if (ak < 0.0f) { > > > > >> > > > > > > > > > > + numNegativeValues++; > > > > >> > > > > > > > > > > } > > > > >> > > > > > > > > > > } > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > @@ -1705,7 +1707,7 @@ > > > > >> > > > > > > > > > > } > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > >> > > > > > > > > > > + int zeroIndex = numNegativeValues; > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > for (int i = zeroIndex - 1; i >= left && > a[i] == > > > > >> 0.0f; > > > > >> > > i--) { > > > > >> > > > > > > > > > > zeroIndex = i; > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > 3. We can use binary search to find the first > > > > >> zero and > > > > >> > > thus > > > > >> > > > > > > avoid linear scan. > > > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > > > 09:04:19 2010 > > > > >> > > > > > > > > > > +++ DualPivotQuicksortF.java Wed May 12 > 12:03:58 > > > > >> 2010 > > > > >> > > > > > > > > > > @@ -1705,11 +1705,7 @@ > > > > >> > > > > > > > > > > } > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > >> > > > > > > > > > > - > > > > >> > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && > a[i] == > > > > >> > > 0.0f; i--) { > > > > >> > > > > > > > > > > - zeroIndex = i; > > > > >> > > > > > > > > > > - } > > > > >> > > > > > > > > > > + int zeroIndex = findFirstZero(a, left, n); > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > // Turn the right number of positive zeros > > > back into > > > > >> > > negative zeros > > > > >> > > > > > > > > > > for (int i = zeroIndex, m = zeroIndex + > > > > >> > > numNegativeZeros; i < > > > > >> > > > > > > m; i++) { > > > > >> > > > > > > > > > > @@ -1718,7 +1714,7 @@ > > > > >> > > > > > > > > > > } > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > /** > > > > >> > > > > > > > > > > - * Returns the index of some zero element > in the > > > > >> > > specified > > > > >> > > > > > > range via > > > > >> > > > > > > > > > > + * Returns the index of the first zero > element > > > > >> in the > > > > >> > > > > > > specified range via > > > > >> > > > > > > > > > > * binary search. The range is assumed to be > > > > >> sorted, and > > > > >> > > must > > > > >> > > > > > > contain > > > > >> > > > > > > > > > > * at least one zero. > > > > >> > > > > > > > > > > * > > > > >> > > > > > > > > > > @@ -1726,18 +1722,17 @@ > > > > >> > > > > > > > > > > * @param low the index of the first element, > > > > >> inclusive, > > > > >> > > to be > > > > >> > > > > > > searched > > > > >> > > > > > > > > > > * @param high the index of the last element, > > > > >> inclusive, > > > > >> > > to be > > > > >> > > > > > > searched > > > > >> > > > > > > > > > > */ > > > > >> > > > > > > > > > > - private static int findAnyZero(float[] a, > > > int low, > > > > >> > > int high) { > > > > >> > > > > > > > > > > - while (true) { > > > > >> > > > > > > > > > > + private static int findFirstZero(float[] > a, int > > > > >> low, > > > > >> > > int high) { > > > > >> > > > > > > > > > > + while (low < high) { > > > > >> > > > > > > > > > > int middle = (low + high) >>> 1; > > > > >> > > > > > > > > > > float middleValue = a[middle]; > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > if (middleValue < 0.0f) { > > > > >> > > > > > > > > > > low = middle + 1; > > > > >> > > > > > > > > > > - } else if (middleValue > 0.0f) { > > > > >> > > > > > > > > > > - high = middle - 1; > > > > >> > > > > > > > > > > - } else { // middleValue == 0.0f > > > > >> > > > > > > > > > > - return middle; > > > > >> > > > > > > > > > > + } else { // middleValue >= 0.0f > > > > >> > > > > > > > > > > + high = middle; > > > > >> > > > > > > > > > > } > > > > >> > > > > > > > > > > + return low; > > > > >> > > > > > > > > > > } > > > > >> > > > > > > > > > > } > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > Counting negative values appeared more > expensive > > > > >> than > > > > >> > > any other > > > > >> > > > > > > variants. > > > > >> > > > > > > > > > > The last proposal seems to me as efficient > as the > > > > >> current > > > > >> > > > > > > solution is in its worst case - when we have only one > > > > >> negative > > > > >> > > zero (in > > > > >> > > > > > > the half of array). > > > > >> > > > > > > > > > > And it shows the best result if we have many > > > zeros. > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > Regards, > > > > >> > > > > > > > > > > Dmytro Sheyko > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > > From: iaroslavski at mail.ru > > > > >> > > > > > > > > > > > To: jjb at google.com; > dmytro_sheyko at hotmail.com > > > > >> > > > > > > > > > > > CC: core-libs-dev at openjdk.java.net; > > > > >> iaroslavski at mail.ru > > > > >> > > > > > > > > > > > Subject: Re[2]: New portion of > improvements for > > > > >> > > Dual-Pivot > > > > >> > > > > > > Quicksort > > > > >> > > > > > > > > > > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > > Josh, > > > > >> > > > > > > > > > > > Dmytro, > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > > I have done more thoroughly testing "great - > > > > >> less > 5 * > > > > >> > > > > > > seventh" vs. "less < e1 && great > e5", > > > > >> > > > > > > > > > > > and found that more symmetric code "less > < e1 && > > > > >> > > great > e5" > > > > >> > > > > > > is little bit faster, ~0.5..0.7% > > > > >> > > > > > > > > > > > on both VMs. Other code has not been > changed. > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > > Please, take the latest version in > attachment. > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > > Vladimir > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? > Joshua > > > > >> Bloch > > > > >> > > > > > > : > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > > > Vladimir, > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > > > Old: > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > > >298 if (less < e1 && great > e5) { > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > > > New: > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > > >256 if (great - less > 5 * seventh) { > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > > >Regards, > > > > >> > > > > > > > > > > > >Josh -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: DualPivotQuicksort.java URL: From aph at redhat.com Tue May 25 08:47:16 2010 From: aph at redhat.com (Andrew Haley) Date: Tue, 25 May 2010 09:47:16 +0100 Subject: Math.log(17197) produces inconsistent results between javac, jit, Math and StrictMath on various architectures. In-Reply-To: <4BFB8C5F.4080500@zafena.se> References: <4BFA7726.1030506@zafena.se> <4BFB8C5F.4080500@zafena.se> Message-ID: <4BFB8E94.5060702@redhat.com> On 05/25/2010 09:37 AM, Xerxes R?nby wrote: > On 2010-05-24 20:12, Tom Rodriguez wrote: >> On May 24, 2010, at 5:55 AM, Xerxes R?nby wrote: >> >> >>> When running this testcase using various jvms / architectures i get varying results of the calculated log_result2 and log_result which >>> >>> ARCH+JVM combination log_result (javac) log_result2 (jit) passes regression test? >>> ia32+OpenJDK Server VM (build 14.0-b16, mixed mode) 9.752490228984199 9.752490228984199 yes >>> arm+OpenJDK Shark VM (build 16.0-b13, mixed mode) 9.75249022898412 9.752490228984199 no >>> x86_64+OpenJDK 64-Bit Server VM (build 14.0-b16, mixed mode) 9.75249022898412 9.752490228984199 no >>> >> The test applies to a bug which was fixed in hs17 so testing with hs14 is sure to fail on x86_64 which is where the bug was. The purpose of the test is to make sure that the value doesn't change over time which isn't allowed. In the original bug the compiler had an intrinsic for log but the interpreter wasn't using the same intrinsic so the interpreter and compiler could return different answers. So presumably if you test with hs17 x86_64 will be fine but I don't know what the problem would be with the ARM port of shark. Does it have intrinsics for Math.log? > > Yes ARM port of Shark uses a intrinsic for the Shark JIT. > The Shark JIT uses the LLVM provided math intrinsics for log calculations, > and the Shark Interpreter Zero lets the Math.log class method handle it > and the class in turn uses the StrictMath.log JNI c call internally. > > The reason why I get different results are of course because i use two > different implementations yet mathematically both valid approximations > (+- 1ulps). That doesn't really explain it, though. How come the LLVM log returns a different value from the C library? Andrew. From weijun.wang at sun.com Tue May 25 10:22:30 2010 From: weijun.wang at sun.com (weijun.wang at sun.com) Date: Tue, 25 May 2010 10:22:30 +0000 Subject: hg: jdk7/tl/jdk: 6948287: KDC test strange knvo Message-ID: <20100525102304.B6F86445B6@hg.openjdk.java.net> Changeset: 2306564dea3a Author: weijun Date: 2010-05-25 18:20 +0800 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/2306564dea3a 6948287: KDC test strange knvo Reviewed-by: xuelei ! test/sun/security/krb5/auto/KDC.java From xerxes at zafena.se Mon May 24 12:55:02 2010 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Mon, 24 May 2010 14:55:02 +0200 Subject: Math.log(17197) produces inconsistent results between javac, jit, Math and StrictMath on various architectures. Message-ID: <4BFA7726.1030506@zafena.se> Hi Im hoping to find someone who can enlighten me how to resolve a bug where some hotspot JITs fails the hotspot/test/compiler/6539464 jtreg regression test. The testcase looks like: public class Test { static double log_value = 17197; static double log_result = Math.log(log_value); public static void main(String[] args) throws Exception { for (int i = 0; i < 1000000; i++) { double log_result2 = Math.log(log_value); if (log_result2 != log_result) { throw new InternalError("Math.log produces inconsistent results: " + log_result2 + " != " + log_result); } } } } When running this testcase using various jvms / architectures i get varying results of the calculated log_result2 and log_result which ARCH+JVM combination log_result (javac) log_result2 (jit) passes regression test? ia32+OpenJDK Server VM (build 14.0-b16, mixed mode) 9.752490228984199 9.752490228984199 yes arm+OpenJDK Shark VM (build 16.0-b13, mixed mode) 9.75249022898412 9.752490228984199 no x86_64+OpenJDK 64-Bit Server VM (build 14.0-b16, mixed mode) 9.75249022898412 9.752490228984199 no While trying to figure out whats the correct result for the log(17197) calculation i tested what StrictMath.log outputs: StrictMath.log(17197) = 9.75249022898412 And in order to get an independent mathematically correct opinion of what log(17197) equals i asked wolfram alpha: http://www.wolframalpha.com/input/?i=log%2817197%29 log(17197) = 9.7524902289841994797298917760120602447583441794533189705223... or in short 9.752490228984199 So we have a situation where javac, jit, Math and StrictMath generates inconsistent results. How do we resolve this situation? Quoting the Math package java doc: "If a method always has an error less than 0.5 ulps, the method always returns the floating-point number nearest the exact result; such a method is correctly rounded. A correctly rounded method is generally the best a floating-point approximation can be; however, it is impractical for many floating-point methods to be correctly rounded. Instead, for the Math class, a larger error bound of 1 or 2 ulps is allowed for certain methods" Would this quotation imply that both log(17197) calculation results above are correct ( 9.752490228984199 and 9.75249022898412 )? If both calculations are correct then I propose that we should change the hotspot/test/compiler/6539464 jtreg regression test to make all JVM's pass the test when they are within +- 1 ulps from the mathematically correct answer of: 9.7524902289841994797298917760120602447583441794533189705223... Cheers and have a great day! Xerxes From xerxes at zafena.se Mon May 24 14:55:03 2010 From: xerxes at zafena.se (=?UTF-8?B?WGVyeGVzIFLDpW5ieQ==?=) Date: Mon, 24 May 2010 16:55:03 +0200 Subject: Math.log(17197) produces inconsistent results between javac, jit, Math and StrictMath on various architectures. In-Reply-To: References: <4BFA7726.1030506@zafena.se> Message-ID: <4BFA9347.8090509@zafena.se> On 2010-05-24 15:44, Andrew John Hughes wrote: > On 24 May 2010 13:55, Xerxes R?nby wrote: > >> Hi >> >> Im hoping to find someone who can enlighten me how to resolve a bug >> where some hotspot JITs >> fails the hotspot/test/compiler/6539464 jtreg regression test. >> >> The testcase looks like: >> >> public class Test { >> static double log_value = 17197; >> static double log_result = Math.log(log_value); >> >> public static void main(String[] args) throws Exception { >> for (int i = 0; i < 1000000; i++) { >> double log_result2 = Math.log(log_value); >> if (log_result2 != log_result) { >> throw new InternalError("Math.log produces inconsistent results: " + log_result2 + " != " + log_result); >> } >> } >> } >> } >> >> When running this testcase using various jvms / architectures i get varying results of the calculated log_result2 and log_result which >> >> ARCH+JVM combination log_result (javac) log_result2 (jit) passes regression test? >> ia32+OpenJDK Server VM (build 14.0-b16, mixed mode) 9.752490228984199 9.752490228984199 yes >> arm+OpenJDK Shark VM (build 16.0-b13, mixed mode) 9.75249022898412 9.752490228984199 no >> x86_64+OpenJDK 64-Bit Server VM (build 14.0-b16, mixed mode) 9.75249022898412 9.752490228984199 no >> >> While trying to figure out whats the correct result for the log(17197) calculation i tested what StrictMath.log outputs: >> StrictMath.log(17197) = 9.75249022898412 >> >> And in order to get an independent mathematically correct opinion of what log(17197) equals i asked wolfram alpha: >> http://www.wolframalpha.com/input/?i=log%2817197%29 >> log(17197) = 9.7524902289841994797298917760120602447583441794533189705223... >> or in short 9.752490228984199 >> >> So we have a situation where javac, jit, Math and StrictMath generates inconsistent results. >> How do we resolve this situation? >> >> Quoting the Math package java doc: >> "If a method always has an error less than 0.5 ulps, the method always >> returns the floating-point number nearest the exact result; such a >> method is correctly rounded. A correctly rounded method is >> generally the best a floating-point approximation can be; however, >> it is impractical for many floating-point methods to be correctly >> rounded. Instead, for the Math class, a larger error >> bound of 1 or 2 ulps is allowed for certain methods" >> >> Would this quotation imply that both log(17197) calculation results above are correct ( 9.752490228984199 and 9.75249022898412 )? >> If both calculations are correct then I propose that we should change the hotspot/test/compiler/6539464 jtreg regression test to make all >> JVM's pass the test when they are within +- 1 ulps from the mathematically correct answer of: >> 9.7524902289841994797298917760120602447583441794533189705223... >> >> Cheers and have a great day! >> Xerxes >> >> >> > Do x86 and x86_64 give the same results if you actually use the same > version of HotSpot as you do on ARM? > Im only able to test x86: But no javac still produces different ressult when compiling static double log_result = Math.log(log_value); and running javac on x86 and arm using the same version of hotspot: ARCH+JVM combination log_result (javac) log_result2 (jit) passes regression test? ia32+OpenJDK Shark VM (build 16.0-b13, mixed mode) 9.752490228984199 9.752490228984199 yes arm+OpenJDK Shark VM (build 16.0-b13, mixed mode) 9.75249022898412 9.752490228984199 no From tom.rodriguez at oracle.com Mon May 24 18:12:06 2010 From: tom.rodriguez at oracle.com (Tom Rodriguez) Date: Mon, 24 May 2010 11:12:06 -0700 Subject: Math.log(17197) produces inconsistent results between javac, jit, Math and StrictMath on various architectures. In-Reply-To: <4BFA7726.1030506@zafena.se> References: <4BFA7726.1030506@zafena.se> Message-ID: On May 24, 2010, at 5:55 AM, Xerxes R?nby wrote: > > When running this testcase using various jvms / architectures i get varying results of the calculated log_result2 and log_result which > > ARCH+JVM combination log_result (javac) log_result2 (jit) passes regression test? > ia32+OpenJDK Server VM (build 14.0-b16, mixed mode) 9.752490228984199 9.752490228984199 yes > arm+OpenJDK Shark VM (build 16.0-b13, mixed mode) 9.75249022898412 9.752490228984199 no > x86_64+OpenJDK 64-Bit Server VM (build 14.0-b16, mixed mode) 9.75249022898412 9.752490228984199 no The test applies to a bug which was fixed in hs17 so testing with hs14 is sure to fail on x86_64 which is where the bug was. The purpose of the test is to make sure that the value doesn't change over time which isn't allowed. In the original bug the compiler had an intrinsic for log but the interpreter wasn't using the same intrinsic so the interpreter and compiler could return different answers. So presumably if you test with hs17 x86_64 will be fine but I don't know what the problem would be with the ARM port of shark. Does it have intrinsics for Math.log? Also note that javac isn't producing the constant value since it's doesn't constant fold Math.log, let alone any other Math or StrictMath call. That value is computed by the class initializer which will run in the interpreter. tom > > While trying to figure out whats the correct result for the log(17197) calculation i tested what StrictMath.log outputs: > StrictMath.log(17197) = 9.75249022898412 > > And in order to get an independent mathematically correct opinion of what log(17197) equals i asked wolfram alpha: > http://www.wolframalpha.com/input/?i=log%2817197%29 > log(17197) = 9.7524902289841994797298917760120602447583441794533189705223... > or in short 9.752490228984199 > > So we have a situation where javac, jit, Math and StrictMath generates inconsistent results. > How do we resolve this situation? > > Quoting the Math package java doc: > "If a method always has an error less than 0.5 ulps, the method always > returns the floating-point number nearest the exact result; such a > method is correctly rounded. A correctly rounded method is > generally the best a floating-point approximation can be; however, > it is impractical for many floating-point methods to be correctly > rounded. Instead, for the Math class, a larger error > bound of 1 or 2 ulps is allowed for certain methods" > > Would this quotation imply that both log(17197) calculation results above are correct ( 9.752490228984199 and 9.75249022898412 )? > If both calculations are correct then I propose that we should change the hotspot/test/compiler/6539464 jtreg regression test to make all > JVM's pass the test when they are within +- 1 ulps from the mathematically correct answer of: > 9.7524902289841994797298917760120602447583441794533189705223... > > Cheers and have a great day! > Xerxes > From lana.steuck at oracle.com Mon May 24 19:19:21 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Mon, 24 May 2010 19:19:21 +0000 Subject: hg: jdk7/tl: 8 new changesets Message-ID: <20100524191921.DDCA74457C@hg.openjdk.java.net> Changeset: b7b4797303cb Author: mikejwre Date: 2010-05-06 18:25 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/rev/b7b4797303cb Added tag jdk7-b92 for changeset 5f5c33d417f3 ! .hgtags Changeset: aa4f995fb65e Author: prr Date: 2010-05-11 14:31 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/rev/aa4f995fb65e 6931180: Migration to recent versions of MS Platform SDK Summary: Changes to enable building JDK7 with Microsoft Visual Studio 2010 Reviewed-by: ohair, art, ccheung, dcubed ! README-builds.html Changeset: 5fc102ff48f0 Author: mikejwre Date: 2010-05-12 17:19 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/rev/5fc102ff48f0 Merge Changeset: ec423e5e725d Author: mikejwre Date: 2010-05-13 13:22 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/rev/ec423e5e725d Added tag jdk7-b93 for changeset 5fc102ff48f0 ! .hgtags Changeset: 2512c00f089f Author: prr Date: 2010-05-19 09:44 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/rev/2512c00f089f 6903970: VS2008/VS2010 build fails in make/sun/jkernel because of "afxres.h" missing Reviewed-by: ohair, art ! README-builds.html Changeset: be22d34852cd Author: prr Date: 2010-05-19 09:46 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/rev/be22d34852cd Merge Changeset: d7f35c61afa0 Author: mikejwre Date: 2010-05-19 20:16 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/rev/d7f35c61afa0 Merge Changeset: d923ba684bc4 Author: mikejwre Date: 2010-05-20 16:00 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/rev/d923ba684bc4 Added tag jdk7-b94 for changeset d7f35c61afa0 ! .hgtags From lana.steuck at oracle.com Mon May 24 19:19:26 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Mon, 24 May 2010 19:19:26 +0000 Subject: hg: jdk7/tl/corba: 7 new changesets Message-ID: <20100524191933.CA4444457D@hg.openjdk.java.net> Changeset: ae18df0d4767 Author: mikejwre Date: 2010-05-06 18:25 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/corba/rev/ae18df0d4767 Added tag jdk7-b92 for changeset 930582f667a1 ! .hgtags Changeset: ee2d8f1bef5b Author: prr Date: 2010-05-11 14:35 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/corba/rev/ee2d8f1bef5b 6931180: Migration to recent versions of MS Platform SDK Summary: Changes to enable building JDK7 with Microsoft Visual Studio 2010 Reviewed-by: ohair, art, ccheung, dcubed ! make/common/Defs-windows.gmk ! make/common/shared/Compiler-msvc.gmk ! make/common/shared/Defs-windows.gmk ! make/common/shared/Platform.gmk Changeset: 9718d624864c Author: mikejwre Date: 2010-05-12 17:19 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/corba/rev/9718d624864c Merge Changeset: f2ff4938cecd Author: mikejwre Date: 2010-05-13 13:22 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/corba/rev/f2ff4938cecd Added tag jdk7-b93 for changeset 9718d624864c ! .hgtags Changeset: f13708960583 Author: lana Date: 2010-05-11 16:34 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/corba/rev/f13708960583 Merge - make/sun/corba/core/Makefile - make/sun/corba/core/mapfile-vers - src/share/classes/com/sun/corba/se/internal/io/IIOPInputStream.java - src/share/classes/com/sun/corba/se/internal/io/IIOPOutputStream.java - src/share/classes/com/sun/corba/se/internal/io/LibraryManager.java - src/share/classes/com/sun/corba/se/internal/io/ObjectStreamClass.java - src/share/native/com/sun/corba/se/internal/io/ioser.c Changeset: 533c11186b44 Author: lana Date: 2010-05-19 12:25 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/corba/rev/533c11186b44 Merge - make/sun/corba/core/Makefile - make/sun/corba/core/mapfile-vers - src/share/classes/com/sun/corba/se/internal/io/IIOPInputStream.java - src/share/classes/com/sun/corba/se/internal/io/IIOPOutputStream.java - src/share/classes/com/sun/corba/se/internal/io/LibraryManager.java - src/share/classes/com/sun/corba/se/internal/io/ObjectStreamClass.java - src/share/native/com/sun/corba/se/internal/io/ioser.c Changeset: 06dbf406818c Author: mikejwre Date: 2010-05-20 16:00 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/corba/rev/06dbf406818c Added tag jdk7-b94 for changeset 533c11186b44 ! .hgtags From lana.steuck at oracle.com Mon May 24 19:21:38 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Mon, 24 May 2010 19:21:38 +0000 Subject: hg: jdk7/tl/hotspot: 74 new changesets Message-ID: <20100524192417.E8A794457E@hg.openjdk.java.net> Changeset: ef74d6d1ac1e Author: never Date: 2010-04-14 15:30 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/ef74d6d1ac1e 6938026: C2 compiler fails in Node::rematerialize()const Reviewed-by: twisti ! src/share/vm/opto/parse1.cpp Changeset: 9f5b60a14736 Author: never Date: 2010-04-15 18:14 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed Reviewed-by: twisti ! src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp ! src/cpu/x86/vm/c1_LIRAssembler_x86.cpp ! src/share/vm/asm/codeBuffer.hpp ! src/share/vm/c1/c1_Compilation.cpp ! src/share/vm/c1/c1_GraphBuilder.cpp ! src/share/vm/c1/c1_Instruction.hpp ! src/share/vm/c1/c1_LIR.cpp ! src/share/vm/c1/c1_LIR.hpp ! src/share/vm/c1/c1_LIRAssembler.cpp ! src/share/vm/c1/c1_LIRAssembler.hpp ! src/share/vm/c1/c1_LIRGenerator.cpp ! src/share/vm/code/nmethod.cpp ! src/share/vm/code/nmethod.hpp ! src/share/vm/runtime/sharedRuntime.cpp Changeset: f9271ff9d324 Author: twisti Date: 2010-04-15 02:40 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/f9271ff9d324 6941224: Improved stack overflow handling for Zero Summary: Adding stack overflow checking to Shark brought to light a bunch of deficiencies in Zero's stack overflow code. Reviewed-by: twisti Contributed-by: Gary Benson ! src/cpu/zero/vm/cppInterpreter_zero.cpp ! src/cpu/zero/vm/cppInterpreter_zero.hpp ! src/cpu/zero/vm/entryFrame_zero.hpp ! src/cpu/zero/vm/fakeStubFrame_zero.hpp ! src/cpu/zero/vm/interpreterFrame_zero.hpp ! src/cpu/zero/vm/interpreterRT_zero.cpp ! src/cpu/zero/vm/stack_zero.hpp ! src/cpu/zero/vm/stubGenerator_zero.cpp ! src/os_cpu/linux_zero/vm/thread_linux_zero.hpp ! src/share/vm/includeDB_zero Changeset: badea972a310 Author: twisti Date: 2010-04-16 00:52 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/badea972a310 Merge Changeset: a9584793da0f Author: twisti Date: 2010-04-15 03:13 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/a9584793da0f 6944028: 6940701 broke Zero Summary: The fix for 6940701 broke Zero. Reviewed-by: twisti Contributed-by: Gary Benson ! src/cpu/zero/vm/globals_zero.hpp Changeset: d32d2a2f62cd Author: twisti Date: 2010-04-16 02:59 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/d32d2a2f62cd Merge Changeset: aa9c266de52a Author: twisti Date: 2010-04-16 05:05 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/aa9c266de52a 6944473: 6941224 misses new files Summary: Two new files are missing in the push for 6941224. Reviewed-by: twisti Contributed-by: Gary Benson + src/cpu/zero/vm/stack_zero.cpp + src/cpu/zero/vm/stack_zero.inline.hpp Changeset: c544d979f886 Author: twisti Date: 2010-04-19 02:13 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/c544d979f886 6944503: Improved Zero crash dump Summary: With Zero on a GC crash the stack was dumped differently to other crashes. Reviewed-by: twisti Contributed-by: Gary Benson ! src/share/vm/utilities/vmError.cpp ! src/share/vm/utilities/vmError.hpp Changeset: bc32f286fae0 Author: never Date: 2010-04-20 13:26 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/bc32f286fae0 6945219: minor SA fixes Reviewed-by: twisti ! agent/src/os/linux/ps_core.c ! agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java ! agent/src/share/classes/sun/jvm/hotspot/HSDB.java ! agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpot.java ! agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeDisassembler.java ! agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java ! agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java ! agent/src/share/classes/sun/jvm/hotspot/runtime/SignatureIterator.java ! agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java ! agent/src/share/classes/sun/jvm/hotspot/ui/FrameWrapper.java ! agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java ! agent/src/share/classes/sun/jvm/hotspot/utilities/Assert.java Changeset: ba07d5be2d51 Author: jrose Date: 2010-04-21 01:13 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/ba07d5be2d51 Merge Changeset: 0bfd3fb24150 Author: jmasa Date: 2010-04-13 13:52 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit. Summary: Ensure a full GC that clears SoftReferences before throwing an out-of-memory Reviewed-by: ysr, jcoomes ! src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp ! src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp ! src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp ! src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp ! src/share/vm/gc_implementation/g1/g1MarkSweep.cpp ! src/share/vm/gc_implementation/includeDB_gc_parallelScavenge ! src/share/vm/gc_implementation/includeDB_gc_serial ! src/share/vm/gc_implementation/parNew/parNewGeneration.cpp ! src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp ! src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp ! src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp ! src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp ! src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.cpp ! src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp ! src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp ! src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp ! src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp ! src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp ! src/share/vm/gc_implementation/shared/adaptiveSizePolicy.hpp ! src/share/vm/gc_implementation/shared/vmGCOperations.hpp ! src/share/vm/gc_interface/collectedHeap.hpp ! src/share/vm/memory/collectorPolicy.cpp ! src/share/vm/memory/collectorPolicy.hpp ! src/share/vm/memory/defNewGeneration.cpp ! src/share/vm/memory/genCollectedHeap.cpp ! src/share/vm/memory/genMarkSweep.cpp Changeset: 7666957bc44d Author: tonyp Date: 2010-03-30 15:43 -0400 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/7666957bc44d 6937142: G1: improvements to debugging output (S-M) Summary: Various fixes to the G1 debugging output. Reviewed-by: johnc, iveresov ! src/share/vm/gc_implementation/g1/concurrentMark.cpp ! src/share/vm/gc_implementation/g1/concurrentMark.hpp ! src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp ! src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp ! src/share/vm/gc_implementation/g1/heapRegion.cpp Changeset: 5dbd9300cf9c Author: johnc Date: 2010-04-15 15:52 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/5dbd9300cf9c 6943926: G1: Integer overflow during heap region verification Summary: The expression that calculates the live bytes for a heap region can overflow for a suitably large humongous region/object. Cache the object size in a suitably sized local variable so that the expression is converted to a wider type. Reviewed-by: tonyp, jmasa, iveresov, apetrusenko ! src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Changeset: f9ec1e4bbb44 Author: tonyp Date: 2010-04-15 18:45 -0400 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/f9ec1e4bbb44 6939027: G1: assertion failure during the concurrent phase of cleanup Summary: The outgoing region map is not maintained properly and it's causing an assert failure. Given that we don't actually use it, I'm removing it. I'm piggy-backing a small change on this which removes a message that it's printed before a Full GC when DisableExplicitGC is set. Reviewed-by: apetrusenko, ysr ! src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp ! src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp ! src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp Changeset: 79e419e5ea3b Author: apetrusenko Date: 2010-04-16 08:48 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/79e419e5ea3b 6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize Summary: Replaces the G1-specific parameter with the existing ones that are used by the other GCs (YoungPLABSize and OldPLABSize) Reviewed-by: tonyp, johnc ! src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp ! src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp ! src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp ! src/share/vm/gc_implementation/g1/g1_globals.hpp Changeset: bdb5361c461c Author: kevinw Date: 2010-04-16 17:36 +0100 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/bdb5361c461c 6897143: Stress test crashes during HeapInspection using ParallelGC. Summary: ensure_parsability() must be called even if GC_locker prevents GC. Reviewed-by: ysr, chrisphi ! src/share/vm/gc_implementation/shared/vmGCOperations.cpp Changeset: 6ecb6e6de3d6 Author: kevinw Date: 2010-04-19 05:40 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/6ecb6e6de3d6 Merge Changeset: 1316cec51b4d Author: johnc Date: 2010-04-22 10:02 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/1316cec51b4d 6819061: G1: eliminate serial Other times that are proportional to the collection set length 6871109: G1: remove the concept of the scan only prefix Summary: Removed scan only regions and associated code. The young portion of the collection set is now constructed incrementally - when a young region is retired as the current allocation region it is added to the collection set. Reviewed-by: apetrusenko, iveresov, tonyp ! src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp ! src/share/vm/gc_implementation/g1/concurrentMark.hpp ! src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp ! src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp ! src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp ! src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp ! src/share/vm/gc_implementation/g1/g1_globals.hpp ! src/share/vm/gc_implementation/g1/heapRegion.cpp ! src/share/vm/gc_implementation/g1/heapRegion.hpp ! src/share/vm/gc_implementation/g1/survRateGroup.cpp ! src/share/vm/gc_implementation/g1/survRateGroup.hpp ! src/share/vm/services/g1MemoryPool.cpp Changeset: 454ff03c0daf Author: tonyp Date: 2010-04-26 18:01 -0400 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/454ff03c0daf Merge Changeset: d7f654633cfe Author: never Date: 2010-04-26 11:27 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/d7f654633cfe 6946040: add intrinsic for short and char reverseBytes Reviewed-by: never, twisti Contributed-by: Hiroshi Yamauchi ! make/linux/makefiles/adlc.make ! make/solaris/makefiles/adlc.make ! src/cpu/sparc/vm/assembler_sparc.hpp ! src/cpu/sparc/vm/sparc.ad ! src/cpu/x86/vm/x86_32.ad ! src/cpu/x86/vm/x86_64.ad ! src/share/vm/adlc/formssel.cpp ! src/share/vm/classfile/vmSymbols.hpp ! src/share/vm/opto/classes.hpp ! src/share/vm/opto/library_call.cpp ! src/share/vm/opto/subnode.hpp + test/compiler/6431242/Test.java + test/compiler/6946040/TestCharShortByteSwap.java Changeset: b4776199210f Author: never Date: 2010-04-26 23:59 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/b4776199210f 6943485: JVMTI always on capabilities change code generation too much Reviewed-by: twisti, dcubed ! src/share/vm/c1/c1_Compilation.cpp ! src/share/vm/c1/c1_Compilation.hpp ! src/share/vm/c1/c1_GraphBuilder.cpp ! src/share/vm/c1/c1_LinearScan.cpp ! src/share/vm/c1/c1_globals.hpp ! src/share/vm/ci/bcEscapeAnalyzer.cpp ! src/share/vm/ci/ciEnv.cpp ! src/share/vm/ci/ciEnv.hpp ! src/share/vm/opto/c2compiler.cpp ! src/share/vm/opto/compile.cpp ! src/share/vm/opto/compile.hpp ! src/share/vm/opto/graphKit.cpp ! src/share/vm/prims/jvmtiExport.cpp ! src/share/vm/prims/jvmtiExport.hpp ! src/share/vm/prims/jvmtiManageCapabilities.cpp Changeset: 314e17ca2c23 Author: iveresov Date: 2010-04-27 11:19 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/314e17ca2c23 6946892: c1 shouldn't sign-extend to upper 32bits on x64 Summary: c1 does sign-extension when it loads ints and shorts from memory to 64-bit registers. This causes problems for c2 because it relies on the fact the int passed in a 64-bit register is zero-extended. Reviewed-by: never ! src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Changeset: 90acda19b80f Author: jrose Date: 2010-04-29 00:03 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/90acda19b80f Merge Changeset: 7b03170e1fcb Author: trims Date: 2010-04-29 15:18 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/7b03170e1fcb Merge Changeset: 310cdbc35535 Author: trims Date: 2010-04-29 15:47 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/310cdbc35535 6948636: Bump the HS18 build number to 04 Summary: Update the HS18 build number to 04 Reviewed-by: jcoomes ! make/hotspot_version Changeset: e3fa0cc77f74 Author: trims Date: 2010-05-04 12:23 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/e3fa0cc77f74 Merge Changeset: 3221d1887d30 Author: trims Date: 2010-05-04 12:25 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/3221d1887d30 Added tag hs18-b03 for changeset 25f53b53aaa3 ! .hgtags Changeset: fd3de7134574 Author: mikejwre Date: 2010-05-06 18:25 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/fd3de7134574 Added tag jdk7-b92 for changeset 3221d1887d30 ! .hgtags Changeset: fb57d4cf76c2 Author: prr Date: 2010-05-11 14:35 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/fb57d4cf76c2 6931180: Migration to recent versions of MS Platform SDK 6951582: Build problems on win64 Summary: Changes to enable building JDK7 with Microsoft Visual Studio 2010 Reviewed-by: ohair, art, ccheung, dcubed ! make/windows/build_vm_def.sh ! make/windows/makefiles/compile.make ! make/windows/makefiles/defs.make ! make/windows/makefiles/sanity.make ! src/share/vm/gc_implementation/g1/heapRegion.cpp ! src/share/vm/runtime/sharedRuntimeTrig.cpp Changeset: 9d865fc2f644 Author: mikejwre Date: 2010-05-12 17:19 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/9d865fc2f644 Merge Changeset: 62c1088d26fc Author: mikejwre Date: 2010-05-13 13:22 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/62c1088d26fc Added tag jdk7-b93 for changeset 9d865fc2f644 ! .hgtags Changeset: 615a9d95d265 Author: johnc Date: 2010-04-27 18:13 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/615a9d95d265 6946056: assert((intptr_t) sp()<=(intptr_t) result,"result must>=than stack pointer"), frame_x86.cpp:295 Summary: frame::interpreter_frame_monitor_end() will spuriously assert for a frame that spans 0x80000000. Cast values to intptr_t* (rather than intptr_t) so that an unsigned pointer compare is performed. Reviewed-by: never, jcoomes, pbk ! src/cpu/x86/vm/frame_x86.cpp Changeset: cff162798819 Author: jcoomes Date: 2009-10-11 16:19 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/cff162798819 6888953: some calls to function-like macros are missing semicolons Reviewed-by: pbk, kvn ! src/cpu/sparc/vm/assembler_sparc.cpp ! src/cpu/x86/vm/assembler_x86.cpp ! src/cpu/x86/vm/c1_LIRAssembler_x86.cpp ! src/share/vm/adlc/output_c.cpp ! src/share/vm/classfile/dictionary.cpp ! src/share/vm/classfile/loaderConstraints.cpp ! src/share/vm/classfile/resolutionErrors.cpp ! src/share/vm/code/nmethod.cpp ! src/share/vm/compiler/compileBroker.hpp ! src/share/vm/compiler/compileLog.cpp ! src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp ! src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp ! src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp ! src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp ! src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp ! src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp ! src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp ! src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp ! src/share/vm/interpreter/oopMapCache.cpp ! src/share/vm/interpreter/templateInterpreter.cpp ! src/share/vm/memory/blockOffsetTable.cpp ! src/share/vm/memory/heapInspection.cpp ! src/share/vm/oops/generateOopMap.cpp ! src/share/vm/oops/klassVtable.cpp ! src/share/vm/opto/node.cpp ! src/share/vm/opto/output.cpp ! src/share/vm/opto/phaseX.hpp ! src/share/vm/prims/forte.cpp ! src/share/vm/runtime/frame.cpp ! src/share/vm/runtime/vmThread.cpp ! src/share/vm/utilities/xmlstream.cpp Changeset: f03d0a26bf83 Author: jcoomes Date: 2010-04-22 13:23 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/f03d0a26bf83 6888954: argument formatting for assert() and friends Reviewed-by: kvn, twisti, apetrusenko, never, dcubed ! src/cpu/sparc/vm/assembler_sparc.hpp ! src/os/linux/vm/os_linux.cpp ! src/os/solaris/vm/os_solaris.cpp ! src/os/solaris/vm/threadCritical_solaris.cpp ! src/os/windows/vm/os_windows.cpp ! src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp ! src/os_cpu/linux_x86/vm/os_linux_x86.cpp ! src/share/vm/asm/assembler.cpp ! src/share/vm/classfile/classFileParser.cpp ! src/share/vm/code/exceptionHandlerTable.cpp ! src/share/vm/code/nmethod.cpp ! src/share/vm/code/stubs.cpp ! src/share/vm/code/vtableStubs.cpp ! src/share/vm/interpreter/bytecodeInterpreter.cpp ! src/share/vm/interpreter/bytecodes.cpp ! src/share/vm/oops/instanceKlass.cpp ! src/share/vm/oops/instanceKlassKlass.cpp ! src/share/vm/oops/klassVtable.cpp ! src/share/vm/opto/idealGraphPrinter.cpp ! src/share/vm/opto/output.cpp ! src/share/vm/prims/jni.cpp ! src/share/vm/runtime/globals.hpp ! src/share/vm/runtime/memprofiler.cpp ! src/share/vm/runtime/mutex.cpp ! src/share/vm/runtime/mutexLocker.cpp ! src/share/vm/runtime/os.cpp ! src/share/vm/runtime/safepoint.cpp ! src/share/vm/runtime/signature.cpp ! src/share/vm/runtime/stubRoutines.cpp ! src/share/vm/runtime/vmThread.cpp ! src/share/vm/utilities/debug.cpp ! src/share/vm/utilities/debug.hpp ! src/share/vm/utilities/exceptions.cpp ! src/share/vm/utilities/macros.hpp ! src/share/vm/utilities/vmError.cpp ! src/share/vm/utilities/vmError.hpp + test/runtime/6888954/vmerrors.sh Changeset: befdf73d6b82 Author: tonyp Date: 2010-05-03 16:31 -0400 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/befdf73d6b82 Merge ! src/cpu/sparc/vm/assembler_sparc.hpp ! src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Changeset: 731bcbe3c9c4 Author: trims Date: 2010-05-06 12:46 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/731bcbe3c9c4 6950438: Add 6u18 and 6u20 release values explicitly to jprt.properties file Summary: modify jprt.properties to allow JPRT to use 6u18 and 6u18 targets Reviewed-by: ohair ! make/jprt.properties Changeset: 5dabb4e73380 Author: trims Date: 2010-05-06 13:03 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/5dabb4e73380 Merge Changeset: 80ccc94456b2 Author: trims Date: 2010-05-07 15:12 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/80ccc94456b2 Merge Changeset: 359375cb7de6 Author: trims Date: 2010-05-07 15:13 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/359375cb7de6 Added tag hs18-b04 for changeset 310cdbc35535 ! .hgtags Changeset: e8e83be27dd7 Author: never Date: 2010-05-10 14:58 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/e8e83be27dd7 6951190: assert(!klass_is_exact(),"only non-exact klass") while building JDK Reviewed-by: kvn ! src/share/vm/opto/library_call.cpp Changeset: 96d554193f72 Author: coleenp Date: 2010-04-19 18:58 -0400 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/96d554193f72 6944822: Fix for 6938627 exposes problem with hard-coded buffer sizes Summary: Make tmpdir buffer sizes MAX_PATH+1 Reviewed-by: dholmes, coleenp Contributed-by: andreas.kohn at fredhopper.com ! src/os/linux/vm/attachListener_linux.cpp ! src/os/linux/vm/os_linux.cpp ! src/os/solaris/vm/attachListener_solaris.cpp Changeset: 77261afdc5f2 Author: coleenp Date: 2010-05-04 15:12 -0400 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/77261afdc5f2 6935118: UseCompressedOops modification in methodOopDesc::sort_methods() causes JCK timeout Summary: Add comparison functions for compressed oops to use bubblesort. Reviewed-by: never, coleenp Contributed-by: volker.simonis at gmail.com ! src/share/vm/oops/methodOop.cpp + test/runtime/6925573/SortMethodsTest.java Changeset: f43b5e9f7881 Author: kamg Date: 2010-05-05 09:28 -0400 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/f43b5e9f7881 6949118: jvm.dll shows the company name as Sun Microsystems Summary: Changed to "Oracle Corporation" Reviewed-by: coleenp, dcubed ! make/hotspot_distro Changeset: 3fca8e9cd36a Author: dcubed Date: 2010-05-05 16:39 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/3fca8e9cd36a Merge ! src/os/linux/vm/os_linux.cpp Changeset: 4ad4e0ee3779 Author: dcubed Date: 2010-05-10 13:09 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/4ad4e0ee3779 Merge Changeset: 2ad074ba8456 Author: dcubed Date: 2010-05-11 17:41 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/2ad074ba8456 Merge Changeset: c640000b7cc1 Author: twisti Date: 2010-04-29 06:30 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/c640000b7cc1 6829193: JSR 292 needs to support SPARC Summary: There are unimplemented portions of the hotspot code for method handles and invokedynamic specific to SPARC. Reviewed-by: kvn, never, jrose ! src/cpu/sparc/vm/assembler_sparc.cpp ! src/cpu/sparc/vm/assembler_sparc.hpp ! src/cpu/sparc/vm/assembler_sparc.inline.hpp ! src/cpu/sparc/vm/interp_masm_sparc.cpp ! src/cpu/sparc/vm/interp_masm_sparc.hpp ! src/cpu/sparc/vm/interpreter_sparc.cpp ! src/cpu/sparc/vm/methodHandles_sparc.cpp ! src/cpu/sparc/vm/stubGenerator_sparc.cpp ! src/cpu/sparc/vm/templateInterpreter_sparc.cpp ! src/cpu/sparc/vm/templateTable_sparc.cpp ! src/cpu/x86/vm/assembler_x86.cpp ! src/cpu/x86/vm/assembler_x86.hpp ! src/cpu/x86/vm/methodHandles_x86.cpp ! src/share/vm/prims/methodHandles.hpp Changeset: ae8f909e5fc7 Author: iveresov Date: 2010-04-29 17:53 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/ae8f909e5fc7 6948602: Disable use of SSE4.2 in String.indexOf intrinsic until 6942326 is fixed Summary: Disable the use of pcmpestri until it can be guaranteed that the load doesn't cross in to the uncommited space. See 6942326. Reviewed-by: never, kvn ! src/share/vm/opto/library_call.cpp Changeset: 0c5b3cf3c1f5 Author: twisti Date: 2010-04-30 04:27 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/0c5b3cf3c1f5 6939182: Zero JNI handles fix Summary: Zero will exit with an error when invoked with -Xcheck:jni. Reviewed-by: twisti, kamg Contributed-by: Gary Benson ! src/cpu/zero/vm/cppInterpreter_zero.cpp ! src/cpu/zero/vm/frame_zero.cpp ! src/cpu/zero/vm/frame_zero.hpp ! src/cpu/zero/vm/frame_zero.inline.hpp ! src/cpu/zero/vm/javaFrameAnchor_zero.hpp ! src/cpu/zero/vm/stack_zero.cpp ! src/cpu/zero/vm/stack_zero.hpp ! src/os_cpu/linux_zero/vm/thread_linux_zero.hpp Changeset: 2338d41fbd81 Author: twisti Date: 2010-04-30 08:37 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/2338d41fbd81 6943304: remove tagged stack interpreter Reviewed-by: coleenp, never, gbenson ! src/cpu/sparc/vm/assembler_sparc.cpp ! src/cpu/sparc/vm/cppInterpreter_sparc.hpp ! src/cpu/sparc/vm/frame_sparc.cpp ! src/cpu/sparc/vm/interp_masm_sparc.cpp ! src/cpu/sparc/vm/interp_masm_sparc.hpp ! src/cpu/sparc/vm/interpreterRT_sparc.cpp ! src/cpu/sparc/vm/interpreter_sparc.hpp ! src/cpu/sparc/vm/methodHandles_sparc.cpp ! src/cpu/sparc/vm/sharedRuntime_sparc.cpp ! src/cpu/sparc/vm/stubGenerator_sparc.cpp ! src/cpu/sparc/vm/templateInterpreter_sparc.cpp ! src/cpu/sparc/vm/templateInterpreter_sparc.hpp ! src/cpu/sparc/vm/templateTable_sparc.cpp ! src/cpu/x86/vm/assembler_x86.cpp ! src/cpu/x86/vm/cppInterpreter_x86.hpp ! src/cpu/x86/vm/frame_x86.cpp ! src/cpu/x86/vm/interp_masm_x86_32.cpp ! src/cpu/x86/vm/interp_masm_x86_32.hpp ! src/cpu/x86/vm/interp_masm_x86_64.cpp ! src/cpu/x86/vm/interp_masm_x86_64.hpp ! src/cpu/x86/vm/interpreterRT_x86_32.cpp ! src/cpu/x86/vm/interpreterRT_x86_64.cpp ! src/cpu/x86/vm/interpreter_x86.hpp ! src/cpu/x86/vm/interpreter_x86_32.cpp ! src/cpu/x86/vm/methodHandles_x86.cpp ! src/cpu/x86/vm/sharedRuntime_x86_32.cpp ! src/cpu/x86/vm/sharedRuntime_x86_64.cpp ! src/cpu/x86/vm/stubGenerator_x86_32.cpp ! src/cpu/x86/vm/stubGenerator_x86_64.cpp ! src/cpu/x86/vm/templateInterpreter_x86.hpp ! src/cpu/x86/vm/templateInterpreter_x86_32.cpp ! src/cpu/x86/vm/templateInterpreter_x86_64.cpp ! src/cpu/x86/vm/templateTable_x86_32.cpp ! src/cpu/x86/vm/templateTable_x86_64.cpp ! src/cpu/zero/vm/interpreter_zero.hpp ! src/os_cpu/linux_x86/vm/globals_linux_x86.hpp ! src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp ! src/share/vm/interpreter/abstractInterpreter.hpp ! src/share/vm/interpreter/bytecodeInterpreter.cpp ! src/share/vm/interpreter/interpreterRuntime.cpp ! src/share/vm/oops/methodOop.cpp ! src/share/vm/prims/methodHandles.hpp ! src/share/vm/runtime/arguments.cpp ! src/share/vm/runtime/frame.cpp ! src/share/vm/runtime/frame.hpp ! src/share/vm/runtime/globals.hpp ! src/share/vm/runtime/javaCalls.cpp ! src/share/vm/runtime/javaCalls.hpp ! src/share/vm/runtime/sharedRuntime.cpp ! src/share/vm/runtime/vframe.cpp ! src/share/vm/runtime/vframeArray.cpp Changeset: cd5dbf694d45 Author: jrose Date: 2010-05-01 02:42 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/cd5dbf694d45 6939134: JSR 292 adjustments to method handle invocation Summary: split MethodHandle.invoke into invokeExact and invokeGeneric; also clean up JVM-to-Java interfaces Reviewed-by: twisti ! src/cpu/sparc/vm/methodHandles_sparc.cpp ! src/cpu/x86/vm/methodHandles_x86.cpp ! src/share/vm/c1/c1_LIR.hpp ! src/share/vm/ci/ciEnv.cpp ! src/share/vm/ci/ciObjectFactory.cpp ! src/share/vm/ci/ciSymbol.cpp ! src/share/vm/ci/ciSymbol.hpp ! src/share/vm/classfile/classFileParser.cpp ! src/share/vm/classfile/dictionary.cpp ! src/share/vm/classfile/dictionary.hpp ! src/share/vm/classfile/javaClasses.cpp ! src/share/vm/classfile/javaClasses.hpp ! src/share/vm/classfile/systemDictionary.cpp ! src/share/vm/classfile/systemDictionary.hpp ! src/share/vm/classfile/vmSymbols.hpp ! src/share/vm/includeDB_core ! src/share/vm/interpreter/interpreterRuntime.cpp ! src/share/vm/interpreter/linkResolver.cpp ! src/share/vm/memory/universe.cpp ! src/share/vm/oops/cpCacheOop.cpp ! src/share/vm/oops/cpCacheOop.hpp ! src/share/vm/oops/methodKlass.cpp ! src/share/vm/oops/methodOop.cpp ! src/share/vm/oops/methodOop.hpp ! src/share/vm/opto/bytecodeInfo.cpp ! src/share/vm/prims/methodHandleWalk.cpp ! src/share/vm/prims/methodHandles.cpp ! src/share/vm/prims/methodHandles.hpp ! src/share/vm/runtime/sharedRuntime.cpp Changeset: 2ffde6cfe049 Author: jrose Date: 2010-05-01 21:57 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/2ffde6cfe049 6939196: method handle signatures off the boot class path get linkage errors Summary: Adjust MethodType lookup logic to search off the BCP, but not to cache those results Reviewed-by: twisti ! src/share/vm/classfile/systemDictionary.cpp ! src/share/vm/classfile/systemDictionary.hpp ! src/share/vm/interpreter/linkResolver.cpp ! src/share/vm/interpreter/linkResolver.hpp ! src/share/vm/prims/methodHandles.cpp ! src/share/vm/runtime/signature.cpp ! src/share/vm/runtime/signature.hpp Changeset: 68d6683eaef7 Author: twisti Date: 2010-05-04 02:33 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/68d6683eaef7 6949423: remove tagged stack interpreter for Zero Summary: Missed Zero changes for 6943304. Reviewed-by: twisti Contributed-by: Gary Benson ! src/cpu/zero/vm/interpreter_zero.hpp ! src/share/vm/interpreter/bytecodeInterpreter.cpp ! src/share/vm/interpreter/bytecodeInterpreter.hpp Changeset: d6e880569997 Author: twisti Date: 2010-05-05 05:57 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/d6e880569997 6949830: 6939134 broke Zero Summary: The commit for 6939134 broke Zero. Reviewed-by: twisti Contributed-by: Gary Benson ! src/cpu/zero/vm/methodHandles_zero.cpp Changeset: 348346af6676 Author: twisti Date: 2010-05-06 02:09 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/348346af6676 6950178: Zero stack improvements Summary: Moves the logic for determining the size of the Zero stack into the ZeroStack class. Reviewed-by: twisti Contributed-by: Gary Benson ! src/cpu/zero/vm/stack_zero.cpp ! src/cpu/zero/vm/stack_zero.hpp ! src/cpu/zero/vm/stack_zero.inline.hpp ! src/cpu/zero/vm/stubGenerator_zero.cpp ! src/share/vm/includeDB_zero Changeset: 6cfbdb113e52 Author: twisti Date: 2010-05-07 04:20 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/6cfbdb113e52 6950617: Zero/Shark interface updates Summary: Zero needs a couple of new methods to allow Shark to access the new frame anchor field. Reviewed-by: twisti Contributed-by: Gary Benson ! src/cpu/zero/vm/frame_zero.cpp ! src/cpu/zero/vm/frame_zero.hpp ! src/cpu/zero/vm/javaFrameAnchor_zero.hpp ! src/os_cpu/linux_zero/vm/thread_linux_zero.hpp Changeset: df736661d0c8 Author: jrose Date: 2010-05-11 15:19 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/df736661d0c8 Merge ! src/cpu/sparc/vm/assembler_sparc.cpp ! src/cpu/sparc/vm/assembler_sparc.hpp ! src/cpu/x86/vm/assembler_x86.cpp ! src/cpu/x86/vm/frame_x86.cpp ! src/share/vm/classfile/classFileParser.cpp ! src/share/vm/classfile/dictionary.cpp ! src/share/vm/interpreter/bytecodeInterpreter.cpp ! src/share/vm/opto/library_call.cpp ! src/share/vm/runtime/frame.cpp ! src/share/vm/runtime/globals.hpp ! src/share/vm/runtime/signature.cpp Changeset: 22af4ce8dba1 Author: twisti Date: 2010-05-12 03:49 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/22af4ce8dba1 6951784: Zero deoptimizer changes Summary: The way Zero currently handles deoptimization can lead to methods being freed while they are still being executed. Reviewed-by: twisti Contributed-by: Gary Benson ! src/cpu/zero/vm/cppInterpreter_zero.cpp ! src/cpu/zero/vm/cppInterpreter_zero.hpp ! src/cpu/zero/vm/entry_zero.hpp Changeset: ef1a1d051971 Author: jrose Date: 2010-05-12 22:06 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/ef1a1d051971 Merge ! src/share/vm/oops/methodOop.cpp Changeset: 2fb8834f4446 Author: trims Date: 2010-05-13 14:35 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/2fb8834f4446 Merge Changeset: eefa1a6f1582 Author: trims Date: 2010-05-13 14:47 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/eefa1a6f1582 6952178: Fork HS18 to HS19 - renumber Major and build numbers of JVM Summary: Update the Major and build numbers for HS19 fork Reviewed-by: jcoomes ! make/hotspot_version Changeset: 3bfae429e2cf Author: ysr Date: 2010-05-03 10:24 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/3bfae429e2cf 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT Summary: On sun4v/CMT avoid use of memset() in BOT updates so as to prevent concurrent BOT readers from seeing the phantom zeros arising from memset()'s use of BIS. Reviewed-by: jmasa, johnc, minqi, poonam, tonyp ! src/cpu/sparc/vm/vm_version_sparc.cpp ! src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp ! src/share/vm/memory/blockOffsetTable.hpp ! src/share/vm/runtime/globals.hpp Changeset: 7145628c2fa2 Author: tonyp Date: 2010-05-03 17:23 -0400 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/7145628c2fa2 Merge Changeset: bb843ebc7c55 Author: ysr Date: 2010-05-03 20:19 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/bb843ebc7c55 6919638: CMS: ExplicitGCInvokesConcurrent misinteracts with gc locker Summary: GC-locker induced concurrent full gc should be asynchronous; policy now controlled by a separate flag, which defaults to false. Reviewed-by: jmasa ! src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp ! src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp ! src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp ! src/share/vm/memory/genCollectedHeap.cpp ! src/share/vm/runtime/globals.hpp Changeset: a8127dc669ba Author: ysr Date: 2010-05-10 12:31 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/a8127dc669ba 6951188: CMS: move PromotionInfo into its own file Summary: Moved PromotionInfo and friends into new files promotionInfo.{h,c}pp from their previous compactibleFreeListSpace.{h,c}pp home. Reviewed-by: apetrusenko ! src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp ! src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp ! src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp + src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp + src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.hpp ! src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep Changeset: 67d74f7a15d9 Author: jcoomes Date: 2010-05-12 10:28 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/67d74f7a15d9 6951923: some uses of fatal1 were missed by 6888954 Reviewed-by: jcoomes Contributed-by: Gary Benson ! src/os_cpu/linux_zero/vm/os_linux_zero.cpp Changeset: 8bfe9058ca46 Author: jcoomes Date: 2010-05-13 13:05 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/8bfe9058ca46 Merge ! src/share/vm/runtime/globals.hpp Changeset: 093432aa7573 Author: trims Date: 2010-05-13 17:10 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/093432aa7573 Merge Changeset: 5488b2963a50 Author: trims Date: 2010-05-18 14:10 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/5488b2963a50 Merge ! .hgtags Changeset: daf617c34be6 Author: prr Date: 2010-05-19 10:21 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/daf617c34be6 6953588: hotspot\src\share\vm\interpreter\bytecodes.cpp doesn't compile with VS2010 on AMD64 Reviewed-by: dcubed ! src/share/vm/interpreter/bytecodes.cpp Changeset: d38f45079fe9 Author: mikejwre Date: 2010-05-19 20:16 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/d38f45079fe9 Merge ! src/share/vm/interpreter/bytecodes.cpp Changeset: b1f1fb382940 Author: mikejwre Date: 2010-05-20 16:00 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/b1f1fb382940 Added tag jdk7-b94 for changeset d38f45079fe9 ! .hgtags Changeset: 215de60567b1 Author: trims Date: 2010-05-21 14:01 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/215de60567b1 Added tag hs19-b01 for changeset 8bfe9058ca46 ! .hgtags Changeset: 91d861ba858d Author: trims Date: 2010-05-21 14:03 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/91d861ba858d Merge ! .hgtags From lana.steuck at oracle.com Mon May 24 19:28:26 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Mon, 24 May 2010 19:28:26 +0000 Subject: hg: jdk7/tl/jaxp: 3 new changesets Message-ID: <20100524192826.7034E4457F@hg.openjdk.java.net> Changeset: c725ca829c5a Author: mikejwre Date: 2010-05-06 18:26 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jaxp/rev/c725ca829c5a Added tag jdk7-b92 for changeset e6a40e4bb104 ! .hgtags Changeset: 2de307cd3b4e Author: mikejwre Date: 2010-05-13 13:22 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jaxp/rev/2de307cd3b4e Added tag jdk7-b93 for changeset c725ca829c5a ! .hgtags Changeset: 67921863774c Author: mikejwre Date: 2010-05-20 16:00 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jaxp/rev/67921863774c Added tag jdk7-b94 for changeset 2de307cd3b4e ! .hgtags From lana.steuck at oracle.com Mon May 24 19:28:30 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Mon, 24 May 2010 19:28:30 +0000 Subject: hg: jdk7/tl/jaxws: 3 new changesets Message-ID: <20100524192830.173D244580@hg.openjdk.java.net> Changeset: 797bef191975 Author: mikejwre Date: 2010-05-06 18:26 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jaxws/rev/797bef191975 Added tag jdk7-b92 for changeset df7c033f6a11 ! .hgtags Changeset: 8515e093efd1 Author: mikejwre Date: 2010-05-13 13:22 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jaxws/rev/8515e093efd1 Added tag jdk7-b93 for changeset 797bef191975 ! .hgtags Changeset: 3d5bc8c32313 Author: mikejwre Date: 2010-05-20 16:00 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jaxws/rev/3d5bc8c32313 Added tag jdk7-b94 for changeset 8515e093efd1 ! .hgtags From lana.steuck at oracle.com Mon May 24 19:29:23 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Mon, 24 May 2010 19:29:23 +0000 Subject: hg: jdk7/tl/jdk: 25 new changesets Message-ID: <20100524193456.1668E44581@hg.openjdk.java.net> Changeset: fa09af0e5b7c Author: mikejwre Date: 2010-05-06 18:26 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/fa09af0e5b7c Added tag jdk7-b92 for changeset f2dce7210cc0 ! .hgtags Changeset: 7bbb5f3b6eed Author: prr Date: 2010-05-11 14:36 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/7bbb5f3b6eed 6931180: Migration to recent versions of MS Platform SDK 6944048: VS2010 build failure in make/com/sun/java/pack: missing unpack200.exe.manifest 6944015: VS2010 build failure in awt_TextArea.cpp: ambiguous call to abs() 6936319: JDK build fails in awt_DnDDS.cpp with Visual Studio 2008/Platform SDK 7 6944516: Windows L&F is broken in SwingSet2, when JDK is built with the recent Windows SDK Summary: Changes to enable building JDK7 with Microsoft Visual Studio 2010 Reviewed-by: ohair, art, ccheung, dcubed ! make/com/sun/java/pack/Makefile ! make/common/Defs-windows.gmk ! make/common/Modules.gmk ! make/common/Release.gmk ! make/common/shared/Compiler-msvc.gmk ! make/common/shared/Defs-versions.gmk ! make/common/shared/Defs-windows.gmk ! make/common/shared/Platform.gmk ! src/share/bin/main.c ! src/windows/bin/java_md.c ! src/windows/native/sun/jkernel/DownloadDialog.cpp ! src/windows/native/sun/jkernel/DownloadHelper.cpp ! src/windows/native/sun/jkernel/stdafx.h ! src/windows/native/sun/windows/awt_DesktopProperties.cpp ! src/windows/native/sun/windows/awt_DnDDS.cpp ! src/windows/native/sun/windows/awt_TextArea.cpp Changeset: 219b84b9533a Author: mikejwre Date: 2010-05-12 17:19 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/219b84b9533a Merge Changeset: d352cd74ef71 Author: mikejwre Date: 2010-05-13 13:22 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/d352cd74ef71 Added tag jdk7-b93 for changeset 219b84b9533a ! .hgtags Changeset: 0c3c502b9a84 Author: art Date: 2010-04-27 18:08 +0400 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/0c3c502b9a84 6880336: SwingWorker deadlocks due one thread in the swingworker-pool Reviewed-by: dcherepanov, alexp ! src/share/classes/javax/swing/SwingWorker.java + test/javax/swing/SwingWorker/6880336/NestedWorkers.java Changeset: 5eccce06fed5 Author: anthony Date: 2010-04-28 17:16 +0400 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/5eccce06fed5 6913179: The java.awt.FileDialog should use native GTK file chooser on linux distros Summary: Introduce a GTK-based alternative implementation of the FileDialogPeer on X11 Reviewed-by: anthony, peterz Contributed-by: Costantino Cerbo ! make/sun/xawt/FILES_c_unix.gmk ! make/sun/xawt/FILES_export_unix.gmk ! make/sun/xawt/mapfile-vers ! src/solaris/classes/sun/awt/UNIXToolkit.java + src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java ! src/solaris/classes/sun/awt/X11/XToolkit.java ! src/solaris/native/sun/awt/awt_UNIXToolkit.c ! src/solaris/native/sun/awt/gtk2_interface.c ! src/solaris/native/sun/awt/gtk2_interface.h + src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c + src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.h ! src/solaris/native/sun/awt/swing_GTKEngine.c ! src/solaris/native/sun/awt/swing_GTKStyle.c Changeset: 78537b37b7de Author: lana Date: 2010-04-30 17:03 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/78537b37b7de Merge - make/tools/CharsetMapping/Big5.c2b ! src/solaris/classes/sun/awt/X11/XToolkit.java Changeset: 32f3993fdb3e Author: lana Date: 2010-05-11 16:33 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/32f3993fdb3e Merge Changeset: c8d91032070f Author: peytoia Date: 2010-04-21 10:34 +0900 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/c8d91032070f 6943963: NumericShaper with ARABIC doesn't shape digits correctly after calling another instance Reviewed-by: okutsu ! src/share/classes/java/awt/font/NumericShaper.java ! test/java/awt/font/NumericShaper/MTTest.java ! test/java/awt/font/NumericShaper/ShapingTest.java Changeset: 489b22337422 Author: rupashka Date: 2010-04-21 18:12 +0400 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/489b22337422 6945316: The Win32ShellFolderManager2.isFileSystemRoot can throw NPE Reviewed-by: alexp ! src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java + test/javax/swing/JFileChooser/6945316/bug6945316.java Changeset: ff11655cf75b Author: alexp Date: 2010-04-29 18:38 +0400 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/ff11655cf75b 6899413: Fix for CR #6878399 should be refactored Reviewed-by: peterz ! src/share/classes/javax/swing/JEditorPane.java ! src/share/classes/javax/swing/JList.java ! src/share/classes/javax/swing/JTable.java ! src/share/classes/javax/swing/JTextField.java ! src/share/classes/javax/swing/JTree.java ! src/share/classes/javax/swing/SwingUtilities.java ! src/share/classes/javax/swing/text/JTextComponent.java Changeset: d5b94f5b3c3a Author: alexp Date: 2010-04-29 18:56 +0400 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/d5b94f5b3c3a 6899453: Remove unnecessary methods from LayerUI Reviewed-by: peterz ! src/share/classes/javax/swing/plaf/LayerUI.java Changeset: 0f5ef61eea9e Author: alexp Date: 2010-04-29 19:07 +0400 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/0f5ef61eea9e 6899405: Specification for JLayer.setLayerEventMask() should mention that eventDispatch() might not be called Reviewed-by: peterz ! src/share/classes/javax/swing/JLayer.java ! src/share/classes/javax/swing/plaf/LayerUI.java Changeset: e266071daf0d Author: lana Date: 2010-04-30 11:03 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/e266071daf0d Merge - make/tools/CharsetMapping/Big5.c2b Changeset: 042eb92f89ad Author: peterz Date: 2010-05-06 12:57 +0400 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/042eb92f89ad 6919629: Nimbus L&F Nimbus.Overrides option leaks significant amounts of memory Reviewed-by: rupashka ! src/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java + test/javax/swing/plaf/nimbus/Test6919629.java Changeset: c34d92f8304b Author: lana Date: 2010-05-11 16:34 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/c34d92f8304b Merge Changeset: c533a177ef64 Author: lana Date: 2010-05-11 16:35 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/c533a177ef64 Merge Changeset: 238023f36777 Author: anthony Date: 2010-05-18 19:35 +0400 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/238023f36777 6953275: Many Swing tests are failing because of a GTK lib Reviewed-by: art, dcherepanov ! src/solaris/native/sun/awt/gtk2_interface.c ! src/solaris/native/sun/awt/gtk2_interface.h Changeset: ac527b9eca58 Author: lana Date: 2010-05-18 11:29 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/ac527b9eca58 Merge Changeset: 2aefa7aaf517 Author: lana Date: 2010-05-19 12:27 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/2aefa7aaf517 Merge Changeset: 416cfd5c6ca9 Author: prr Date: 2010-05-19 09:45 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/416cfd5c6ca9 6903970: VS2008/VS2010 build fails in make/sun/jkernel because of "afxres.h" missing Reviewed-by: ohair, art ! make/common/shared/Defs-windows.gmk ! make/sun/jkernel/Makefile Changeset: 7a1873e045cb Author: prr Date: 2010-05-19 09:46 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/7a1873e045cb Merge Changeset: cf44386c8fe3 Author: mikejwre Date: 2010-05-19 20:16 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/cf44386c8fe3 Merge Changeset: 1ad7fbef48d0 Author: mikejwre Date: 2010-05-20 16:00 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/1ad7fbef48d0 Added tag jdk7-b94 for changeset cf44386c8fe3 ! .hgtags Changeset: dd41a79890c3 Author: lana Date: 2010-05-24 09:06 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/dd41a79890c3 Merge ! make/common/shared/Platform.gmk From lana.steuck at oracle.com Mon May 24 19:42:46 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Mon, 24 May 2010 19:42:46 +0000 Subject: hg: jdk7/tl/langtools: 6 new changesets Message-ID: <20100524194302.0398144582@hg.openjdk.java.net> Changeset: 683cd1f6bc4b Author: mikejwre Date: 2010-05-06 18:26 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/683cd1f6bc4b Added tag jdk7-b92 for changeset 98cba5876cb5 ! .hgtags Changeset: e224d437e84a Author: mikejwre Date: 2010-05-13 13:22 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/e224d437e84a Added tag jdk7-b93 for changeset 683cd1f6bc4b ! .hgtags Changeset: 1cb2b5acc291 Author: lana Date: 2010-05-11 16:36 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/1cb2b5acc291 Merge Changeset: bb3d7c75a56d Author: lana Date: 2010-05-19 12:28 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/bb3d7c75a56d Merge Changeset: 67cac01ed62a Author: mikejwre Date: 2010-05-20 16:00 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/67cac01ed62a Added tag jdk7-b94 for changeset bb3d7c75a56d ! .hgtags Changeset: 16efe627290e Author: lana Date: 2010-05-24 09:07 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/16efe627290e Merge From xerxes at zafena.se Tue May 25 08:37:51 2010 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Tue, 25 May 2010 10:37:51 +0200 Subject: Math.log(17197) produces inconsistent results between javac, jit, Math and StrictMath on various architectures. In-Reply-To: References: <4BFA7726.1030506@zafena.se> Message-ID: <4BFB8C5F.4080500@zafena.se> On 2010-05-24 20:12, Tom Rodriguez wrote: > On May 24, 2010, at 5:55 AM, Xerxes R?nby wrote: > > >> When running this testcase using various jvms / architectures i get varying results of the calculated log_result2 and log_result which >> >> ARCH+JVM combination log_result (javac) log_result2 (jit) passes regression test? >> ia32+OpenJDK Server VM (build 14.0-b16, mixed mode) 9.752490228984199 9.752490228984199 yes >> arm+OpenJDK Shark VM (build 16.0-b13, mixed mode) 9.75249022898412 9.752490228984199 no >> x86_64+OpenJDK 64-Bit Server VM (build 14.0-b16, mixed mode) 9.75249022898412 9.752490228984199 no >> > The test applies to a bug which was fixed in hs17 so testing with hs14 is sure to fail on x86_64 which is where the bug was. The purpose of the test is to make sure that the value doesn't change over time which isn't allowed. In the original bug the compiler had an intrinsic for log but the interpreter wasn't using the same intrinsic so the interpreter and compiler could return different answers. So presumably if you test with hs17 x86_64 will be fine but I don't know what the problem would be with the ARM port of shark. Does it have intrinsics for Math.log? Yes ARM port of Shark uses a intrinsic for the Shark JIT. The Shark JIT uses the LLVM provided math intrinsics for log calculations, and the Shark Interpreter Zero lets the Math.log class method handle it and the class in turn uses the StrictMath.log JNI c call internally. The reason why I get different results are of course because i use two different implementations yet mathematically both valid approximations (+- 1ulps). > Also note that javac isn't producing the constant value since it's doesn't constant fold Math.log, let alone any other Math or StrictMath call. That value is computed by the class initializer which will run in the interpreter. > > tom > Thanks again for this heads up that the static value are calculated at runtime by the interpreter and not constant folded, it makes the problem crystal. We do now have enough information to sort out the bug http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=500 by making the Shark JIT call the same intrinsic as the StrictMath c library provides, or the other way around. Cheers and have a great day! Xerxes > >> While trying to figure out whats the correct result for the log(17197) calculation i tested what StrictMath.log outputs: >> StrictMath.log(17197) = 9.75249022898412 >> >> And in order to get an independent mathematically correct opinion of what log(17197) equals i asked wolfram alpha: >> http://www.wolframalpha.com/input/?i=log%2817197%29 >> log(17197) = 9.7524902289841994797298917760120602447583441794533189705223... >> or in short 9.752490228984199 >> >> So we have a situation where javac, jit, Math and StrictMath generates inconsistent results. >> How do we resolve this situation? >> >> Quoting the Math package java doc: >> "If a method always has an error less than 0.5 ulps, the method always >> returns the floating-point number nearest the exact result; such a >> method is correctly rounded. A correctly rounded method is >> generally the best a floating-point approximation can be; however, >> it is impractical for many floating-point methods to be correctly >> rounded. Instead, for the Math class, a larger error >> bound of 1 or 2 ulps is allowed for certain methods" >> >> Would this quotation imply that both log(17197) calculation results above are correct ( 9.752490228984199 and 9.75249022898412 )? >> If both calculations are correct then I propose that we should change the hotspot/test/compiler/6539464 jtreg regression test to make all >> JVM's pass the test when they are within +- 1 ulps from the mathematically correct answer of: >> 9.7524902289841994797298917760120602447583441794533189705223... >> >> Cheers and have a great day! >> Xerxes >> >> > From christos at zoulas.com Tue May 25 20:50:20 2010 From: christos at zoulas.com (Christos Zoulas) Date: Tue, 25 May 2010 16:50:20 -0400 Subject: Math.log(17197) produces inconsistent results between javac, jit, Math and StrictMath on various architectures. In-Reply-To: <4BFA9347.8090509@zafena.se> from =?UTF-8?B?WGVyeGVzIFLDpW5ieQ==?= (May 24, 4:55pm) Message-ID: <20100525205020.4759456425@rebar.astron.com> On May 24, 4:55pm, xerxes at zafena.se (=?UTF-8?B?WGVyeGVzIFLDpW5ieQ==?=) wrote: -- Subject: Re: Math.log(17197) produces inconsistent results between javac, | Im only able to test x86: | | But no javac still produces different ressult when compiling | | static double log_result = Math.log(log_value); | | and running javac on x86 and arm using the same version of hotspot: I have encountered this only on x86_64. x86 indeed works. The bug was introduced in jdk 1.6. christos From jonathan.gibbons at oracle.com Tue May 25 22:41:02 2010 From: jonathan.gibbons at oracle.com (jonathan.gibbons at oracle.com) Date: Tue, 25 May 2010 22:41:02 +0000 Subject: hg: jdk7/tl/jdk: 6934615: Relative classpaths in jarfile manifests are handled inefficiently by rmic Message-ID: <20100525224125.C178046E13@hg.openjdk.java.net> Changeset: dfa98add4ad0 Author: jjg Date: 2010-05-25 15:39 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/dfa98add4ad0 6934615: Relative classpaths in jarfile manifests are handled inefficiently by rmic Reviewed-by: darcy ! src/share/classes/sun/rmi/rmic/BatchEnvironment.java ! test/sun/rmi/rmic/manifestClassPath/run.sh From dmytro_sheyko at hotmail.com Wed May 26 09:24:09 2010 From: dmytro_sheyko at hotmail.com (Dmytro Sheyko) Date: Wed, 26 May 2010 16:24:09 +0700 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: <4BFB716B.4020107@mail.ru> References: , , <4BF2AAEE.1040706@mail.ru>, <4BF3BFFD.8010007@mail.ru>,<4BF3C05C.7010300@mail.ru> , <4BF69AFB.8060406@mail.ru> , <4BFB716B.4020107@mail.ru> Message-ID: Hi Vladimir, As for me, everything seems good. Returning to the theoretical background, could you estimate number of comparison and assignments? These should be less than in your initial version. Also have you considered 7-comparison sort for sorting 5 pivot candidates instead of 9-comparison sorting network? Thank you, Dmytro Sheyko > Date: Tue, 25 May 2010 10:42:51 +0400 > From: iaroslavski at mail.ru > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > To: dmytro_sheyko at hotmail.com > CC: core-libs-dev at openjdk.java.net > > I added more comments, please, review attached version. > > >> So, we win 2-3% ! > > On [partial] sorted inputs new version runs more faster than few percents: > > organ pipes > this: 6896 > prev: 7424 > jdk7: 8018 > jdk6: 12502 > > ascendant > this: 2877 > prev: 3845 > jdk7: 4583 > jdk6: 9019 > > descendant > this: 3287 > prev: 4110 > jdk7: 4897 > jdk6: 9132 > > Dmytro Sheyko wrote: > > That's great! Thank you. > > > > > Date: Fri, 21 May 2010 18:38:51 +0400 > > > From: iaroslavski at mail.ru > > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > > To: dmytro_sheyko at hotmail.com > > > CC: core-libs-dev at openjdk.java.net > > > > > > Hello, > > > > > > I prepared version with your changes "Skip the last negative > > > value (if any) or all leading negative" and with my optimization > > > for all types. I added two while loops before partitioning to > > > skip elements, less than pivot1 and greater than pivot2: > > > > > > if (pivot1 != pivot2) { > > > /* ... */ > > > a[e2] = a[less]; > > > a[e4] = a[great]; > > > > > > ++ while (a[++less] < pivot1); > > > ++ while (a[--great] > pivot2); > > > > > > /* ... */ > > > outer: > > > for (int k = less; k <= great; k++) { > > > ... > > > } > > > > > > Here is benchmark result (in compare with quicksort from JDK 6): > > > > > > client server > > > ------ ------ > > > previous version: 60.70% 48.20% > > > current version: 57.22% 46.18% > > > > > > So, we win 2-3% ! > > > > > > Thank you, > > > Vladimir > > > > > > Dmytro Sheyko wrote: > > > > Hi Vladimir, > > > > > > > > I tried to figure out why the testcase failed on my modification. It > > > > appeared that number of negative zeros were changed during general > > sort. > > > > As I can see you already fixed this issue. Well, my modification was > > > > based on assumption that we can speed up eliminating explicit array > > > > range checks. > > > > However, such assumption is wrong because Hotspot anyway emits range > > > > checks at its discretion and therefore processZeros generally does not > > > > work as fast as I expected. > > > > So complications I made are not worth doing. > > > > > > > > As for the latest code you posted. Doesn't it make sense to skip > > leading > > > > negative zeros before farther processing? In this case we avoid > > > > unnecessary assigning +0.0 and then -0.0 to the same location a[k] > > (i.e. > > > > where k == p). > > > > > > > > /* > > > > * Skip the last negative value (if any) or all leading negative > > > > zeros > > > > */ > > > > while (left <= right && Double.doubleToRawLongBits(a[left]) < 0) { > > > > left++; > > > > } > > > > > > > > for (int k = left + 1, p = left; k <= right; k++) { > > > > double ak = a[k]; > > > > if (ak != 0.0d) { > > > > return; > > > > } > > > > if (Double.doubleToRawLongBits(ak) < 0) { // ak is -0.0d > > > > a[k] = 0.0d; > > > > a[p++] = -0.0d; > > > > } > > > > } > > > > > > > > Thank you, > > > > Dmytro Sheyko > > > > > > > > > > > > > Date: Wed, 19 May 2010 14:41:32 +0400 > > > > > From: iaroslavski at mail.ru > > > > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > > > > To: dmytro_sheyko at hotmail.com > > > > > CC: core-libs-dev at openjdk.java.net > > > > > > > > > > resend the class with correct constructor > > > > > > > > > > Vladimir Iaroslavski wrote: > > > > > > Dmytro, > > > > > > > > > > > > Thank you for comments, I updated double method, did little bit > > > > > > javadoc changes and replaced in char/short/byte methods > > > > > > "fromIndex -> left", "toIndex-1 -> right", the code became > > > > > > consistent with main sort method and more compact. Also I use > > > > > > more usual "i--" and "i++" in for loops (instead of "--i", "++i. > > > > > > > > > > > > To accent the difference between float/double and other types, > > > > > > I put comment where it is important: > > > > > > > > > > > > /* > > > > > > * In spite of a[great] == pivot1, the assignment > > > > > > * a[less++] = pivot1 may be incorrect, if a[great] > > > > > > * and pivot1 are floating-point zeros of different > > > > > > * signs, therefore in float/double methods we have > > > > > > * to use more accurate assignment a[k] = a[great]. > > > > > > */ > > > > > > a[less++] = pivot1; > > > > > > > > > > > > and for double/float: > > > > > > > > > > > > /* > > > > > > ..... > > > > > > */ > > > > > > a[k] = a[great]; > > > > > > > > > > > > See updated version in attachment. > > > > > > > > > > > > Thank you, > > > > > > Vladimir > > > > > > > > > > > > Dmytro Sheyko wrote: > > > > > >> Vladimir, > > > > > >> > > > > > >> I can see that you changed sortNegZeroAndNaN(float[]...) but > > probably > > > > > >> forgot to change sortNegZeroAndNaN(double[]...). > > > > > >> > > > > > >> You really puzzled me with failed testcase and note that sorting > > > > > >> algorithm (without special attention to zeros) generally may > > change > > > > > >> number of negative zeros. > > > > > >> I will provide my comments later. > > > > > >> > > > > > >> As for counting sort, I think we should use single format > > style over > > > > > >> the file (unless we have valuable reason not to do this). I > > mean to > > > > > >> choose > > > > > >> 1) > > > > > >> if (toIndex - fromIndex > > > > > > >> COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > > > > > >> countingSort(a, fromIndex, toIndex); > > > > > >> return; > > > > > >> } > > > > > >> sort(a, fromIndex, toIndex - 1, true); > > > > > >> 2) > > > > > >> if (toIndex - fromIndex > > > > > > >> COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > > > > > >> countingSort(a, fromIndex, toIndex); > > > > > >> } else { > > > > > >> sort(a, fromIndex, toIndex - 1, true); > > > > > >> } > > > > > >> I prefer the second one. > > > > > >> > > > > > >> Thanks a lot, > > > > > >> Dmytro Sheyko > > > > > >> > > > > > >> > Date: Tue, 18 May 2010 18:57:50 +0400 > > > > > >> > From: iaroslavski at mail.ru > > > > > >> > Subject: Re: New portion of improvements for Dual-Pivot > > Quicksort > > > > > >> > To: dmytro_sheyko at hotmail.com > > > > > >> > CC: core-libs-dev at openjdk.java.net > > > > > >> > > > > > > >> > Hello, > > > > > >> > > > > > > >> > I've run your modification for counting sort, it real faster. > > > > > >> > I attached new version with your changes (I did little bit > > > > > >> > format it) and included my case with float/double. > > > > > >> > > > > > > >> > Note that you modification doesn't pass test from Sorting class, > > > > > >> > which I sent earlier. It fails on float/double test: > > > > > >> > > > > > > >> > Test #3: random = 666, len = 34, a = 0, g = 6, z = 9, n = > > 10, p = 9 > > > > > >> > > > > > > >> > I suggest shorter method (which is based on your idea to skip > > > > counting > > > > > >> > negative zeros on Phase 1.): I found find first zero index (or > > > > it will > > > > > >> > be index of first positive element if no zeros at all, or last > > > > > >> negative, > > > > > >> > if no positive and zero elements) and then swap negative > > zero to the > > > > > >> > beginning of the sub-range. > > > > > >> > > > > > > >> > int hi = right; > > > > > >> > > > > > > >> > while (left < hi) { > > > > > >> > int middle = (left + hi) >>> 1; > > > > > >> > float middleValue = a[middle]; > > > > > >> > > > > > > >> > if (middleValue < 0.0f) { > > > > > >> > left = middle + 1; > > > > > >> > } else { > > > > > >> > hi = middle; > > > > > >> > } > > > > > >> > } > > > > > >> > > > > > > >> > for (int k = left, p = left; k <= right; k++) { > > > > > >> > float ak = a[k]; > > > > > >> > if (ak != 0.0f) { > > > > > >> > return; > > > > > >> > } > > > > > >> > if (Float.floatToRawIntBits(ak) < 0) { // ak is -0.0f > > > > > >> > a[k] = +0.0f; > > > > > >> > a[p++] = -0.0f; > > > > > >> > } > > > > > >> > } > > > > > >> > > > > > > >> > Important note: in partitioning loop there are several places > > > > > >> > (marked by // !) where potential bug with -0.0 could be > > > > > >> > (when pivot and a[great] are zeros with different signs): > > > > > >> > > > > > > >> > if (a[great] == pivot1) { > > > > > >> > a[k] = a[less]; > > > > > >> > - a[less++] = pivot1; // ! > > > > > >> > + a[less++] = a[great]; > > > > > >> > } else { // pivot1 < a[great] < pivot2 > > > > > >> > a[k] = a[great]; > > > > > >> > } > > > > > >> > - a[great--] = pivot2; // ! > > > > > >> > + a[great--] = ak; > > > > > >> > } else if (ak == pivot1) { // Move a[k] to left part > > > > > >> > a[k] = a[less]; > > > > > >> > - a[less++] = pivot1; // ! > > > > > >> > + a[less++] = ak; > > > > > >> > } > > > > > >> > > > > > > >> > and the same in "Pivots are equal" branch. > > > > > >> > > > > > > >> > I did changes "pivot1/2 -> ak" in methods for all types > > > > > >> > and "pivot1 -> a[great]" in float/double sections only. > > > > > >> > > > > > > >> > Please, review format changes for counting sort and new version > > > > > >> > of Phase 3 for float/double. > > > > > >> > > > > > > >> > Thank you, > > > > > >> > Vladimir > > > > > >> > > > > > > >> > Dmytro Sheyko wrote: > > > > > >> > > Hi, > > > > > >> > > > > > > > >> > > About counting sort again. > > > > > >> > > > > > > > >> > > 1. This condition "i < count.length && k <= right" is > > excessive. > > > > > >> Any one > > > > > >> > > conjunct is enough. "k <= right" seems better. > > > > > >> > > 2. No need to calculate "short value = (short) (i + > > > > > >> Short.MIN_VALUE)" > > > > > >> > > when "count[i]" is zero. > > > > > >> > > 3. For signed primitives (byte and short) we would better loop > > > > > >> backward. > > > > > >> > > Thanks to "k >= fromIndex" condition we will quit looping > > earlier > > > > > >> > > assuming that typically we work with positive numbers. > > > > > >> > > For unsigned primitives (char) we would better loop forward > > > > because > > > > > >> > > typically we work with characters about zero (ASCII). > > > > > >> > > > > > > > >> > > - for (int i = 0, k = left; i < count.length && k <= > > right; i++) { > > > > > >> > > - short value = (short) (i + Short.MIN_VALUE); > > > > > >> > > - for (int s = count[i]; s > 0; s--) { > > > > > >> > > - a[k++] = value; > > > > > >> > > - } > > > > > >> > > - } > > > > > >> > > > > > > > >> > > + for (int i = NUM_SHORT_VALUES - 1, k = toIndex - 1; k >= > > > > > >> > > fromIndex; --i) { > > > > > >> > > + while (count[i] == 0) --i; > > > > > >> > > + short value = (short) (i + Short.MIN_VALUE); > > > > > >> > > + int s = count[i]; > > > > > >> > > + do { a[k--] = value; } while (--s > 0); > > > > > >> > > + } > > > > > >> > > > > > > > >> > > Thanks, > > > > > >> > > Dmytro Sheyko > > > > > >> > > > > > > > >> > > > From: iaroslavski at mail.ru > > > > > >> > > > To: dmytro_sheyko at hotmail.com > > > > > >> > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > > > >> > > > Subject: Re[2]: New portion of improvements for Dual-Pivot > > > > > >> Quicksort > > > > > >> > > > Date: Tue, 18 May 2010 01:11:19 +0400 > > > > > >> > > > > > > > > >> > > > Sounds good! > > > > > >> > > > Will consider too... > > > > > >> > > > > > > > > >> > > > Mon, 17 May 2010 22:24:11 +0700 ?????? ?? Dmytro Sheyko > > > > > >> > > : > > > > > >> > > > > > > > > >> > > > > Hi, > > > > > >> > > > > > > > > > >> > > > > Regarding counting sort. We can check whether we should > > > > > >> switch to > > > > > >> > > counting sort only once in the beginning. > > > > > >> > > > > > > > > > >> > > > > > Date: Mon, 17 May 2010 17:30:37 +0400 > > > > > >> > > > > > From: iaroslavski at mail.ru > > > > > >> > > > > > Subject: Re: New portion of improvements for Dual-Pivot > > > > > >> Quicksort > > > > > >> > > > > > To: dmytro_sheyko at hotmail.com > > > > > >> > > > > > CC: core-libs-dev at openjdk.java.net > > > > > >> > > > > > > > > > > >> > > > > > Hello, > > > > > >> > > > > > > > > > > >> > > > > > Thank you for review, I'll check and run tests again > > > > with you > > > > > >> > > changes. > > > > > >> > > > > > > > > > > >> > > > > > Thank you, > > > > > >> > > > > > Vladimir > > > > > >> > > > > > > > > > > >> > > > > > Dmytro Sheyko wrote: > > > > > >> > > > > > > Hello, > > > > > >> > > > > > > > > > > > >> > > > > > > More ideas. > > > > > >> > > > > > > > > > > > >> > > > > > > 1. We can use > > > > > >> > > > > > > Double.doubleToRawLongBits instead of > > > > > >> Double.doubleToLongBits and > > > > > >> > > > > > > Float.floatToRawIntBits instead of > > Float.floatToIntBits. > > > > > >> > > > > > > No need to handle NaN's because they all are placed to > > > > > >> the end > > > > > >> > > of array. > > > > > >> > > > > > > > > > > > >> > > > > > > 2. Note that > > > > > >> > > > > > > Double.doubleToRawLongBits(+0.0) == 0L and > > > > > >> > > > > > > Double.doubleToRawLongBits(-0.0) == Long.MIN_VALUE and > > > > > >> > > > > > > Float.floatToRawIntBits(+0.0) == 0 and > > > > > >> > > > > > > Float.floatToRawIntBits(-0.0) == Integer.MIN_VALUE. > > > > > >> > > > > > > > > > > > >> > > > > > > Comparing with is zero usually more efficient (or at > > > > > >> least not > > > > > >> > > worse) > > > > > >> > > > > > > than with other values. Thus such pattern > > > > > >> > > > > > > > > > > > >> > > > > > > if (ak == 0.0f && NEGATIVE_ZERO == > > > > Float.floatToIntBits(ak)) > > > > > >> > > > > > > > > > > > >> > > > > > > can be replaced with > > > > > >> > > > > > > > > > > > >> > > > > > > if (ak == 0.0f && Float.floatToIntBits(ak) < 0) > > > > > >> > > > > > > > > > > > >> > > > > > > 3. It would be more efficient to count negative zeros > > > > after > > > > > >> > > sorting. > > > > > >> > > > > > > General sorting algorithm puts both negative and > > positive > > > > > >> zeros > > > > > >> > > together > > > > > >> > > > > > > (but maybe not in right order). > > > > > >> > > > > > > Therefore we have to process less elements because > > > > > >> usually we > > > > > >> > > have less > > > > > >> > > > > > > zeros than other numbers. > > > > > >> > > > > > > > > > > > >> > > > > > > Thanks, > > > > > >> > > > > > > Dmytro Sheyko > > > > > >> > > > > > > > > > > > >> > > > > > > > From: iaroslavski at mail.ru > > > > > >> > > > > > > > To: dmytro_sheyko at hotmail.com; jjb at google.com > > > > > >> > > > > > > > CC: core-libs-dev at openjdk.java.net; > > iaroslavski at mail.ru > > > > > >> > > > > > > > Subject: Re[6]: New portion of improvements for > > > > Dual-Pivot > > > > > >> > > Quicksort > > > > > >> > > > > > > > Date: Fri, 14 May 2010 23:54:06 +0400 > > > > > >> > > > > > > > > > > > > >> > > > > > > > Hello, > > > > > >> > > > > > > > > > > > > >> > > > > > > > I've updated the class, please, review the changes. > > > > > >> > > > > > > > > > > > > >> > > > > > > > Vladimir > > > > > >> > > > > > > > > > > > > >> > > > > > > > Fri, 14 May 2010 01:48:11 +0700 ?????? ?? Dmytro > > Sheyko > > > > > >> > > > > > > : > > > > > >> > > > > > > > > > > > > >> > > > > > > > > Yes. I prefer F (Find First zero using binary > > search) > > > > > >> over > > > > > >> > > C (Count > > > > > >> > > > > > > negatives) and S (Smart Scan for zero). > > > > > >> > > > > > > > > > > > > > >> > > > > > > > > > From: iaroslavski at mail.ru > > > > > >> > > > > > > > > > To: dmytro_sheyko at hotmail.com > > > > > >> > > > > > > > > > CC: jjb at google.com; > > core-libs-dev at openjdk.java.net; > > > > > >> > > > > > > iaroslavski at mail.ru > > > > > >> > > > > > > > > > Subject: Re[4]: New portion of improvements for > > > > > >> > > Dual-Pivot Quicksort > > > > > >> > > > > > > > > > Date: Thu, 13 May 2010 21:34:54 +0400 > > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > Dmytro, > > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > I've tested your suggested variants, and > > found that > > > > > >> case "C" > > > > > >> > > > > > > > > > (very interesting approach to find first > > position > > > > > >> of zero > > > > > >> > > > > > > > > > by counting negative elements) works slower than > > > > > >> original > > > > > >> > > > > > > > > > or two other cases. > > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > Implementations "F" and "S" are very close > > to each > > > > > >> other > > > > > >> > > > > > > > > > and little bit faster than original. I > > prefer case > > > > > >> "F": > > > > > >> > > > > > > > > > it is shorter and more clear. Do you agree? > > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > I'll prepare updated DualPivotQuicksort file and > > > > > >> send it > > > > > >> > > > > > > > > > tomorrow. > > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > Thank you, > > > > > >> > > > > > > > > > Vladimir > > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > Wed, 12 May 2010 17:04:52 +0700 ?????? ?? Dmytro > > > > > >> Sheyko > > > > > >> > > > > > > : > > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > > Vladimir, > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > Your changes are good for me. > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > Additionally I have some comments/proposals > > > > > >> regarding > > > > > >> > > dealing > > > > > >> > > > > > > with negative zeros. > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > 1. Scanning for the first zero we can > > avoid range > > > > > >> check > > > > > >> > > (i >= > > > > > >> > > > > > > left) if we have at least one negative value. > > > > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > > > > 09:04:19 2010 > > > > > >> > > > > > > > > > > +++ DualPivotQuicksortS.java Wed May 12 > > 12:10:46 > > > > > >> 2010 > > > > > >> > > > > > > > > > > @@ -1705,10 +1705,15 @@ > > > > > >> > > > > > > > > > > } > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > > > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > >> > > > > > > > > > > + int zeroIndex = 0; > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && > > a[i] == > > > > > >> > > 0.0f; i--) { > > > > > >> > > > > > > > > > > - zeroIndex = i; > > > > > >> > > > > > > > > > > + if (a[left] < 0.0f) { > > > > > >> > > > > > > > > > > + zeroIndex = findAnyZero(a, left, n); > > > > > >> > > > > > > > > > > + > > > > > >> > > > > > > > > > > + // there is at least one negative value, so > > > > range > > > > > >> > > check is > > > > > >> > > > > > > not needed > > > > > >> > > > > > > > > > > + for (int i = zeroIndex - 1; /*i >= left &&*/ > > > > > >> a[i] == > > > > > >> > > 0.0f; i--) { > > > > > >> > > > > > > > > > > + zeroIndex = i; > > > > > >> > > > > > > > > > > + } > > > > > >> > > > > > > > > > > } > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > // Turn the right number of positive zeros > > > > back into > > > > > >> > > negative zeros > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > 2. We can find the position of the first > > zero by > > > > > >> counting > > > > > >> > > > > > > negative values during preprocessing phase. > > > > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > > > > 09:04:19 2010 > > > > > >> > > > > > > > > > > +++ DualPivotQuicksortC.java Wed May 12 > > 12:01:24 > > > > > >> 2010 > > > > > >> > > > > > > > > > > @@ -1678,7 +1678,7 @@ > > > > > >> > > > > > > > > > > * Phase 1: Count negative zeros and move > > NaNs to > > > > > >> end of > > > > > >> > > array. > > > > > >> > > > > > > > > > > */ > > > > > >> > > > > > > > > > > final int NEGATIVE_ZERO = > > > > > >> Float.floatToIntBits(-0.0f); > > > > > >> > > > > > > > > > > - int numNegativeZeros = 0; > > > > > >> > > > > > > > > > > + int numNegativeZeros = 0, > > numNegativeValues = 0; > > > > > >> > > > > > > > > > > int n = right; > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > for (int k = left; k <= n; k++) { > > > > > >> > > > > > > > > > > @@ -1689,6 +1689,8 @@ > > > > > >> > > > > > > > > > > } else if (ak != ak) { // i.e., ak is NaN > > > > > >> > > > > > > > > > > a[k--] = a[n]; > > > > > >> > > > > > > > > > > a[n--] = Float.NaN; > > > > > >> > > > > > > > > > > + } else if (ak < 0.0f) { > > > > > >> > > > > > > > > > > + numNegativeValues++; > > > > > >> > > > > > > > > > > } > > > > > >> > > > > > > > > > > } > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > @@ -1705,7 +1707,7 @@ > > > > > >> > > > > > > > > > > } > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > > > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > >> > > > > > > > > > > + int zeroIndex = numNegativeValues; > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > for (int i = zeroIndex - 1; i >= left && > > a[i] == > > > > > >> 0.0f; > > > > > >> > > i--) { > > > > > >> > > > > > > > > > > zeroIndex = i; > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > 3. We can use binary search to find the first > > > > > >> zero and > > > > > >> > > thus > > > > > >> > > > > > > avoid linear scan. > > > > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > > > > 09:04:19 2010 > > > > > >> > > > > > > > > > > +++ DualPivotQuicksortF.java Wed May 12 > > 12:03:58 > > > > > >> 2010 > > > > > >> > > > > > > > > > > @@ -1705,11 +1705,7 @@ > > > > > >> > > > > > > > > > > } > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > > > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > >> > > > > > > > > > > - > > > > > >> > > > > > > > > > > - for (int i = zeroIndex - 1; i >= left && > > a[i] == > > > > > >> > > 0.0f; i--) { > > > > > >> > > > > > > > > > > - zeroIndex = i; > > > > > >> > > > > > > > > > > - } > > > > > >> > > > > > > > > > > + int zeroIndex = findFirstZero(a, left, n); > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > // Turn the right number of positive zeros > > > > back into > > > > > >> > > negative zeros > > > > > >> > > > > > > > > > > for (int i = zeroIndex, m = zeroIndex + > > > > > >> > > numNegativeZeros; i < > > > > > >> > > > > > > m; i++) { > > > > > >> > > > > > > > > > > @@ -1718,7 +1714,7 @@ > > > > > >> > > > > > > > > > > } > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > /** > > > > > >> > > > > > > > > > > - * Returns the index of some zero element > > in the > > > > > >> > > specified > > > > > >> > > > > > > range via > > > > > >> > > > > > > > > > > + * Returns the index of the first zero > > element > > > > > >> in the > > > > > >> > > > > > > specified range via > > > > > >> > > > > > > > > > > * binary search. The range is assumed to be > > > > > >> sorted, and > > > > > >> > > must > > > > > >> > > > > > > contain > > > > > >> > > > > > > > > > > * at least one zero. > > > > > >> > > > > > > > > > > * > > > > > >> > > > > > > > > > > @@ -1726,18 +1722,17 @@ > > > > > >> > > > > > > > > > > * @param low the index of the first element, > > > > > >> inclusive, > > > > > >> > > to be > > > > > >> > > > > > > searched > > > > > >> > > > > > > > > > > * @param high the index of the last element, > > > > > >> inclusive, > > > > > >> > > to be > > > > > >> > > > > > > searched > > > > > >> > > > > > > > > > > */ > > > > > >> > > > > > > > > > > - private static int findAnyZero(float[] a, > > > > int low, > > > > > >> > > int high) { > > > > > >> > > > > > > > > > > - while (true) { > > > > > >> > > > > > > > > > > + private static int findFirstZero(float[] > > a, int > > > > > >> low, > > > > > >> > > int high) { > > > > > >> > > > > > > > > > > + while (low < high) { > > > > > >> > > > > > > > > > > int middle = (low + high) >>> 1; > > > > > >> > > > > > > > > > > float middleValue = a[middle]; > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > if (middleValue < 0.0f) { > > > > > >> > > > > > > > > > > low = middle + 1; > > > > > >> > > > > > > > > > > - } else if (middleValue > 0.0f) { > > > > > >> > > > > > > > > > > - high = middle - 1; > > > > > >> > > > > > > > > > > - } else { // middleValue == 0.0f > > > > > >> > > > > > > > > > > - return middle; > > > > > >> > > > > > > > > > > + } else { // middleValue >= 0.0f > > > > > >> > > > > > > > > > > + high = middle; > > > > > >> > > > > > > > > > > } > > > > > >> > > > > > > > > > > + return low; > > > > > >> > > > > > > > > > > } > > > > > >> > > > > > > > > > > } > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > Counting negative values appeared more > > expensive > > > > > >> than > > > > > >> > > any other > > > > > >> > > > > > > variants. > > > > > >> > > > > > > > > > > The last proposal seems to me as efficient > > as the > > > > > >> current > > > > > >> > > > > > > solution is in its worst case - when we have only one > > > > > >> negative > > > > > >> > > zero (in > > > > > >> > > > > > > the half of array). > > > > > >> > > > > > > > > > > And it shows the best result if we have many > > > > zeros. > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > Regards, > > > > > >> > > > > > > > > > > Dmytro Sheyko > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > > From: iaroslavski at mail.ru > > > > > >> > > > > > > > > > > > To: jjb at google.com; > > dmytro_sheyko at hotmail.com > > > > > >> > > > > > > > > > > > CC: core-libs-dev at openjdk.java.net; > > > > > >> iaroslavski at mail.ru > > > > > >> > > > > > > > > > > > Subject: Re[2]: New portion of > > improvements for > > > > > >> > > Dual-Pivot > > > > > >> > > > > > > Quicksort > > > > > >> > > > > > > > > > > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > > Josh, > > > > > >> > > > > > > > > > > > Dmytro, > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > > I have done more thoroughly testing "great - > > > > > >> less > 5 * > > > > > >> > > > > > > seventh" vs. "less < e1 && great > e5", > > > > > >> > > > > > > > > > > > and found that more symmetric code "less > > < e1 && > > > > > >> > > great > e5" > > > > > >> > > > > > > is little bit faster, ~0.5..0.7% > > > > > >> > > > > > > > > > > > on both VMs. Other code has not been > > changed. > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > > Please, take the latest version in > > attachment. > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > > Vladimir > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > > Tue, 4 May 2010 21:57:42 -0700 ?????? ?? > > Joshua > > > > > >> Bloch > > > > > >> > > > > > > : > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > > > Vladimir, > > > > > >> > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > > Old: > > > > > >> > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > >298 if (less < e1 && great > e5) { > > > > > >> > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > > New: > > > > > >> > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > >256 if (great - less > 5 * seventh) { > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > > >Regards, > > > > > >> > > > > > > > > > > > >Josh _________________________________________________________________ Your E-mail and More On-the-Go. Get Windows Live Hotmail Free. https://signup.live.com/signup.aspx?id=60969 -------------- next part -------------- An HTML attachment was scrubbed... URL: From iaroslavski at mail.ru Wed May 26 12:12:17 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Wed, 26 May 2010 16:12:17 +0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: <4BF2AAEE.1040706@mail.ru> <4BF3BFFD.8010007@mail.ru> <4BF3C05C.7010300@mail.ru> <4BF69AFB.8060406@mail.ru> <4BFB716B.4020107@mail.ru> Message-ID: <4BFD1021.1030404@mail.ru> Hello Dmytro, Theoretical investigations are based on simple model, which doesn't take into account many optimizations like "equal pivots", "scan equal to pivots", etc. Model based on the implementation will be too complex to be analyzed. But it is easy to count comparisons and assignments, if I change them by functions with counter. Also I tried to write 7-comparison sort, but the code was too long (a lot of inner if-then-else) instead of 9 compact lines. Do you have suggestion how to implement a nice 7-comparison sort? I tried also selection and bubble sorts, but insertion sort shows better time. Josh, Could you please review the last changes (especially javadoc and comments)? Thank you, Vladimir Dmytro Sheyko wrote: > Hi Vladimir, > > As for me, everything seems good. > > Returning to the theoretical background, could you estimate number of > comparison and assignments? These should be less than in your initial > version. > > Also have you considered 7-comparison sort for sorting 5 pivot > candidates instead of 9-comparison sorting network? > > Thank you, > Dmytro Sheyko > > > Date: Tue, 25 May 2010 10:42:51 +0400 > > From: iaroslavski at mail.ru > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > To: dmytro_sheyko at hotmail.com > > CC: core-libs-dev at openjdk.java.net > > > > I added more comments, please, review attached version. > > > > >> So, we win 2-3% ! > > > > On [partial] sorted inputs new version runs more faster than few > percents: > > > > organ pipes > > this: 6896 > > prev: 7424 > > jdk7: 8018 > > jdk6: 12502 > > > > ascendant > > this: 2877 > > prev: 3845 > > jdk7: 4583 > > jdk6: 9019 > > > > descendant > > this: 3287 > > prev: 4110 > > jdk7: 4897 > > jdk6: 9132 > > > > Dmytro Sheyko wrote: > > > That's great! Thank you. > > > > > > > Date: Fri, 21 May 2010 18:38:51 +0400 > > > > From: iaroslavski at mail.ru > > > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > > > To: dmytro_sheyko at hotmail.com > > > > CC: core-libs-dev at openjdk.java.net > > > > > > > > Hello, > > > > > > > > I prepared version with your changes "Skip the last negative > > > > value (if any) or all leading negative" and with my optimization > > > > for all types. I added two while loops before partitioning to > > > > skip elements, less than pivot1 and greater than pivot2: > > > > > > > > if (pivot1 != pivot2) { > > > > /* ... */ > > > > a[e2] = a[less]; > > > > a[e4] = a[great]; > > > > > > > > ++ while (a[++less] < pivot1); > > > > ++ while (a[--great] > pivot2); > > > > > > > > /* ... */ > > > > outer: > > > > for (int k = less; k <= great; k++) { > > > > ... > > > > } > > > > > > > > Here is benchmark result (in compare with quicksort from JDK 6): > > > > > > > > client server > > > > ------ ------ > > > > previous version: 60.70% 48.20% > > > > current version: 57.22% 46.18% > > > > > > > > So, we win 2-3% ! > > > > > > > > Thank you, > > > > Vladimir > > > > > > > > Dmytro Sheyko wrote: > > > > > Hi Vladimir, > > > > > > > > > > I tried to figure out why the testcase failed on my > modification. It > > > > > appeared that number of negative zeros were changed during general > > > sort. > > > > > As I can see you already fixed this issue. Well, my > modification was > > > > > based on assumption that we can speed up eliminating explicit array > > > > > range checks. > > > > > However, such assumption is wrong because Hotspot anyway emits > range > > > > > checks at its discretion and therefore processZeros generally > does not > > > > > work as fast as I expected. > > > > > So complications I made are not worth doing. > > > > > > > > > > As for the latest code you posted. Doesn't it make sense to skip > > > leading > > > > > negative zeros before farther processing? In this case we avoid > > > > > unnecessary assigning +0.0 and then -0.0 to the same location a[k] > > > (i.e. > > > > > where k == p). > > > > > > > > > > /* > > > > > * Skip the last negative value (if any) or all leading negative > > > > > zeros > > > > > */ > > > > > while (left <= right && Double.doubleToRawLongBits(a[left]) < 0) { > > > > > left++; > > > > > } > > > > > > > > > > for (int k = left + 1, p = left; k <= right; k++) { > > > > > double ak = a[k]; > > > > > if (ak != 0.0d) { > > > > > return; > > > > > } > > > > > if (Double.doubleToRawLongBits(ak) < 0) { // ak is -0.0d > > > > > a[k] = 0.0d; > > > > > a[p++] = -0.0d; > > > > > } > > > > > } > > > > > > > > > > Thank you, > > > > > Dmytro Sheyko > > > > > > > > > > > > > > > > Date: Wed, 19 May 2010 14:41:32 +0400 > > > > > > From: iaroslavski at mail.ru > > > > > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > > > > > To: dmytro_sheyko at hotmail.com > > > > > > CC: core-libs-dev at openjdk.java.net > > > > > > > > > > > > resend the class with correct constructor > > > > > > > > > > > > Vladimir Iaroslavski wrote: > > > > > > > Dmytro, > > > > > > > > > > > > > > Thank you for comments, I updated double method, did little bit > > > > > > > javadoc changes and replaced in char/short/byte methods > > > > > > > "fromIndex -> left", "toIndex-1 -> right", the code became > > > > > > > consistent with main sort method and more compact. Also I use > > > > > > > more usual "i--" and "i++" in for loops (instead of "--i", > "++i. > > > > > > > > > > > > > > To accent the difference between float/double and other types, > > > > > > > I put comment where it is important: > > > > > > > > > > > > > > /* > > > > > > > * In spite of a[great] == pivot1, the assignment > > > > > > > * a[less++] = pivot1 may be incorrect, if a[great] > > > > > > > * and pivot1 are floating-point zeros of different > > > > > > > * signs, therefore in float/double methods we have > > > > > > > * to use more accurate assignment a[k] = a[great]. > > > > > > > */ > > > > > > > a[less++] = pivot1; > > > > > > > > > > > > > > and for double/float: > > > > > > > > > > > > > > /* > > > > > > > ..... > > > > > > > */ > > > > > > > a[k] = a[great]; > > > > > > > > > > > > > > See updated version in attachment. > > > > > > > > > > > > > > Thank you, > > > > > > > Vladimir > > > > > > > > > > > > > > Dmytro Sheyko wrote: > > > > > > >> Vladimir, > > > > > > >> > > > > > > >> I can see that you changed sortNegZeroAndNaN(float[]...) but > > > probably > > > > > > >> forgot to change sortNegZeroAndNaN(double[]...). > > > > > > >> > > > > > > >> You really puzzled me with failed testcase and note that > sorting > > > > > > >> algorithm (without special attention to zeros) generally may > > > change > > > > > > >> number of negative zeros. > > > > > > >> I will provide my comments later. > > > > > > >> > > > > > > >> As for counting sort, I think we should use single format > > > style over > > > > > > >> the file (unless we have valuable reason not to do this). I > > > mean to > > > > > > >> choose > > > > > > >> 1) > > > > > > >> if (toIndex - fromIndex > > > > > > > >> COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > > > > > > >> countingSort(a, fromIndex, toIndex); > > > > > > >> return; > > > > > > >> } > > > > > > >> sort(a, fromIndex, toIndex - 1, true); > > > > > > >> 2) > > > > > > >> if (toIndex - fromIndex > > > > > > > >> COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > > > > > > >> countingSort(a, fromIndex, toIndex); > > > > > > >> } else { > > > > > > >> sort(a, fromIndex, toIndex - 1, true); > > > > > > >> } > > > > > > >> I prefer the second one. > > > > > > >> > > > > > > >> Thanks a lot, > > > > > > >> Dmytro Sheyko > > > > > > >> > > > > > > >> > Date: Tue, 18 May 2010 18:57:50 +0400 > > > > > > >> > From: iaroslavski at mail.ru > > > > > > >> > Subject: Re: New portion of improvements for Dual-Pivot > > > Quicksort > > > > > > >> > To: dmytro_sheyko at hotmail.com > > > > > > >> > CC: core-libs-dev at openjdk.java.net > > > > > > >> > > > > > > > >> > Hello, > > > > > > >> > > > > > > > >> > I've run your modification for counting sort, it real > faster. > > > > > > >> > I attached new version with your changes (I did little bit > > > > > > >> > format it) and included my case with float/double. > > > > > > >> > > > > > > > >> > Note that you modification doesn't pass test from > Sorting class, > > > > > > >> > which I sent earlier. It fails on float/double test: > > > > > > >> > > > > > > > >> > Test #3: random = 666, len = 34, a = 0, g = 6, z = 9, n = > > > 10, p = 9 > > > > > > >> > > > > > > > >> > I suggest shorter method (which is based on your idea to > skip > > > > > counting > > > > > > >> > negative zeros on Phase 1.): I found find first zero > index (or > > > > > it will > > > > > > >> > be index of first positive element if no zeros at all, > or last > > > > > > >> negative, > > > > > > >> > if no positive and zero elements) and then swap negative > > > zero to the > > > > > > >> > beginning of the sub-range. > > > > > > >> > > > > > > > >> > int hi = right; > > > > > > >> > > > > > > > >> > while (left < hi) { > > > > > > >> > int middle = (left + hi) >>> 1; > > > > > > >> > float middleValue = a[middle]; > > > > > > >> > > > > > > > >> > if (middleValue < 0.0f) { > > > > > > >> > left = middle + 1; > > > > > > >> > } else { > > > > > > >> > hi = middle; > > > > > > >> > } > > > > > > >> > } > > > > > > >> > > > > > > > >> > for (int k = left, p = left; k <= right; k++) { > > > > > > >> > float ak = a[k]; > > > > > > >> > if (ak != 0.0f) { > > > > > > >> > return; > > > > > > >> > } > > > > > > >> > if (Float.floatToRawIntBits(ak) < 0) { // ak is -0.0f > > > > > > >> > a[k] = +0.0f; > > > > > > >> > a[p++] = -0.0f; > > > > > > >> > } > > > > > > >> > } > > > > > > >> > > > > > > > >> > Important note: in partitioning loop there are several > places > > > > > > >> > (marked by // !) where potential bug with -0.0 could be > > > > > > >> > (when pivot and a[great] are zeros with different signs): > > > > > > >> > > > > > > > >> > if (a[great] == pivot1) { > > > > > > >> > a[k] = a[less]; > > > > > > >> > - a[less++] = pivot1; // ! > > > > > > >> > + a[less++] = a[great]; > > > > > > >> > } else { // pivot1 < a[great] < pivot2 > > > > > > >> > a[k] = a[great]; > > > > > > >> > } > > > > > > >> > - a[great--] = pivot2; // ! > > > > > > >> > + a[great--] = ak; > > > > > > >> > } else if (ak == pivot1) { // Move a[k] to left part > > > > > > >> > a[k] = a[less]; > > > > > > >> > - a[less++] = pivot1; // ! > > > > > > >> > + a[less++] = ak; > > > > > > >> > } > > > > > > >> > > > > > > > >> > and the same in "Pivots are equal" branch. > > > > > > >> > > > > > > > >> > I did changes "pivot1/2 -> ak" in methods for all types > > > > > > >> > and "pivot1 -> a[great]" in float/double sections only. > > > > > > >> > > > > > > > >> > Please, review format changes for counting sort and new > version > > > > > > >> > of Phase 3 for float/double. > > > > > > >> > > > > > > > >> > Thank you, > > > > > > >> > Vladimir > > > > > > >> > > > > > > > >> > Dmytro Sheyko wrote: > > > > > > >> > > Hi, > > > > > > >> > > > > > > > > >> > > About counting sort again. > > > > > > >> > > > > > > > > >> > > 1. This condition "i < count.length && k <= right" is > > > excessive. > > > > > > >> Any one > > > > > > >> > > conjunct is enough. "k <= right" seems better. > > > > > > >> > > 2. No need to calculate "short value = (short) (i + > > > > > > >> Short.MIN_VALUE)" > > > > > > >> > > when "count[i]" is zero. > > > > > > >> > > 3. For signed primitives (byte and short) we would > better loop > > > > > > >> backward. > > > > > > >> > > Thanks to "k >= fromIndex" condition we will quit looping > > > earlier > > > > > > >> > > assuming that typically we work with positive numbers. > > > > > > >> > > For unsigned primitives (char) we would better loop > forward > > > > > because > > > > > > >> > > typically we work with characters about zero (ASCII). > > > > > > >> > > > > > > > > >> > > - for (int i = 0, k = left; i < count.length && k <= > > > right; i++) { > > > > > > >> > > - short value = (short) (i + Short.MIN_VALUE); > > > > > > >> > > - for (int s = count[i]; s > 0; s--) { > > > > > > >> > > - a[k++] = value; > > > > > > >> > > - } > > > > > > >> > > - } > > > > > > >> > > > > > > > > >> > > + for (int i = NUM_SHORT_VALUES - 1, k = toIndex - 1; k >= > > > > > > >> > > fromIndex; --i) { > > > > > > >> > > + while (count[i] == 0) --i; > > > > > > >> > > + short value = (short) (i + Short.MIN_VALUE); > > > > > > >> > > + int s = count[i]; > > > > > > >> > > + do { a[k--] = value; } while (--s > 0); > > > > > > >> > > + } > > > > > > >> > > > > > > > > >> > > Thanks, > > > > > > >> > > Dmytro Sheyko > > > > > > >> > > > > > > > > >> > > > From: iaroslavski at mail.ru > > > > > > >> > > > To: dmytro_sheyko at hotmail.com > > > > > > >> > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > > > > >> > > > Subject: Re[2]: New portion of improvements for > Dual-Pivot > > > > > > >> Quicksort > > > > > > >> > > > Date: Tue, 18 May 2010 01:11:19 +0400 > > > > > > >> > > > > > > > > > >> > > > Sounds good! > > > > > > >> > > > Will consider too... > > > > > > >> > > > > > > > > > >> > > > Mon, 17 May 2010 22:24:11 +0700 ?????? ?? Dmytro Sheyko > > > > > > >> > > : > > > > > > >> > > > > > > > > > >> > > > > Hi, > > > > > > >> > > > > > > > > > > >> > > > > Regarding counting sort. We can check whether we > should > > > > > > >> switch to > > > > > > >> > > counting sort only once in the beginning. > > > > > > >> > > > > > > > > > > >> > > > > > Date: Mon, 17 May 2010 17:30:37 +0400 > > > > > > >> > > > > > From: iaroslavski at mail.ru > > > > > > >> > > > > > Subject: Re: New portion of improvements for > Dual-Pivot > > > > > > >> Quicksort > > > > > > >> > > > > > To: dmytro_sheyko at hotmail.com > > > > > > >> > > > > > CC: core-libs-dev at openjdk.java.net > > > > > > >> > > > > > > > > > > > >> > > > > > Hello, > > > > > > >> > > > > > > > > > > > >> > > > > > Thank you for review, I'll check and run tests again > > > > > with you > > > > > > >> > > changes. > > > > > > >> > > > > > > > > > > > >> > > > > > Thank you, > > > > > > >> > > > > > Vladimir > > > > > > >> > > > > > > > > > > > >> > > > > > Dmytro Sheyko wrote: > > > > > > >> > > > > > > Hello, > > > > > > >> > > > > > > > > > > > > >> > > > > > > More ideas. > > > > > > >> > > > > > > > > > > > > >> > > > > > > 1. We can use > > > > > > >> > > > > > > Double.doubleToRawLongBits instead of > > > > > > >> Double.doubleToLongBits and > > > > > > >> > > > > > > Float.floatToRawIntBits instead of > > > Float.floatToIntBits. > > > > > > >> > > > > > > No need to handle NaN's because they all are > placed to > > > > > > >> the end > > > > > > >> > > of array. > > > > > > >> > > > > > > > > > > > > >> > > > > > > 2. Note that > > > > > > >> > > > > > > Double.doubleToRawLongBits(+0.0) == 0L and > > > > > > >> > > > > > > Double.doubleToRawLongBits(-0.0) == > Long.MIN_VALUE and > > > > > > >> > > > > > > Float.floatToRawIntBits(+0.0) == 0 and > > > > > > >> > > > > > > Float.floatToRawIntBits(-0.0) == > Integer.MIN_VALUE. > > > > > > >> > > > > > > > > > > > > >> > > > > > > Comparing with is zero usually more efficient > (or at > > > > > > >> least not > > > > > > >> > > worse) > > > > > > >> > > > > > > than with other values. Thus such pattern > > > > > > >> > > > > > > > > > > > > >> > > > > > > if (ak == 0.0f && NEGATIVE_ZERO == > > > > > Float.floatToIntBits(ak)) > > > > > > >> > > > > > > > > > > > > >> > > > > > > can be replaced with > > > > > > >> > > > > > > > > > > > > >> > > > > > > if (ak == 0.0f && Float.floatToIntBits(ak) < 0) > > > > > > >> > > > > > > > > > > > > >> > > > > > > 3. It would be more efficient to count > negative zeros > > > > > after > > > > > > >> > > sorting. > > > > > > >> > > > > > > General sorting algorithm puts both negative and > > > positive > > > > > > >> zeros > > > > > > >> > > together > > > > > > >> > > > > > > (but maybe not in right order). > > > > > > >> > > > > > > Therefore we have to process less elements because > > > > > > >> usually we > > > > > > >> > > have less > > > > > > >> > > > > > > zeros than other numbers. > > > > > > >> > > > > > > > > > > > > >> > > > > > > Thanks, > > > > > > >> > > > > > > Dmytro Sheyko > > > > > > >> > > > > > > > > > > > > >> > > > > > > > From: iaroslavski at mail.ru > > > > > > >> > > > > > > > To: dmytro_sheyko at hotmail.com; jjb at google.com > > > > > > >> > > > > > > > CC: core-libs-dev at openjdk.java.net; > > > iaroslavski at mail.ru > > > > > > >> > > > > > > > Subject: Re[6]: New portion of improvements for > > > > > Dual-Pivot > > > > > > >> > > Quicksort > > > > > > >> > > > > > > > Date: Fri, 14 May 2010 23:54:06 +0400 > > > > > > >> > > > > > > > > > > > > > >> > > > > > > > Hello, > > > > > > >> > > > > > > > > > > > > > >> > > > > > > > I've updated the class, please, review the > changes. > > > > > > >> > > > > > > > > > > > > > >> > > > > > > > Vladimir > > > > > > >> > > > > > > > > > > > > > >> > > > > > > > Fri, 14 May 2010 01:48:11 +0700 ?????? ?? > Dmytro > > > Sheyko > > > > > > >> > > > > > > : > > > > > > >> > > > > > > > > > > > > > >> > > > > > > > > Yes. I prefer F (Find First zero using binary > > > search) > > > > > > >> over > > > > > > >> > > C (Count > > > > > > >> > > > > > > negatives) and S (Smart Scan for zero). > > > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > From: iaroslavski at mail.ru > > > > > > >> > > > > > > > > > To: dmytro_sheyko at hotmail.com > > > > > > >> > > > > > > > > > CC: jjb at google.com; > > > core-libs-dev at openjdk.java.net; > > > > > > >> > > > > > > iaroslavski at mail.ru > > > > > > >> > > > > > > > > > Subject: Re[4]: New portion of > improvements for > > > > > > >> > > Dual-Pivot Quicksort > > > > > > >> > > > > > > > > > Date: Thu, 13 May 2010 21:34:54 +0400 > > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > Dmytro, > > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > I've tested your suggested variants, and > > > found that > > > > > > >> case "C" > > > > > > >> > > > > > > > > > (very interesting approach to find first > > > position > > > > > > >> of zero > > > > > > >> > > > > > > > > > by counting negative elements) works > slower than > > > > > > >> original > > > > > > >> > > > > > > > > > or two other cases. > > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > Implementations "F" and "S" are very close > > > to each > > > > > > >> other > > > > > > >> > > > > > > > > > and little bit faster than original. I > > > prefer case > > > > > > >> "F": > > > > > > >> > > > > > > > > > it is shorter and more clear. Do you agree? > > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > I'll prepare updated DualPivotQuicksort > file and > > > > > > >> send it > > > > > > >> > > > > > > > > > tomorrow. > > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > Thank you, > > > > > > >> > > > > > > > > > Vladimir > > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > Wed, 12 May 2010 17:04:52 +0700 ?????? > ?? Dmytro > > > > > > >> Sheyko > > > > > > >> > > > > > > : > > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > Vladimir, > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > Your changes are good for me. > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > Additionally I have some > comments/proposals > > > > > > >> regarding > > > > > > >> > > dealing > > > > > > >> > > > > > > with negative zeros. > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > 1. Scanning for the first zero we can > > > avoid range > > > > > > >> check > > > > > > >> > > (i >= > > > > > > >> > > > > > > left) if we have at least one negative value. > > > > > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > > > > > 09:04:19 2010 > > > > > > >> > > > > > > > > > > +++ DualPivotQuicksortS.java Wed May 12 > > > 12:10:46 > > > > > > >> 2010 > > > > > > >> > > > > > > > > > > @@ -1705,10 +1705,15 @@ > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > > > > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > >> > > > > > > > > > > + int zeroIndex = 0; > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > - for (int i = zeroIndex - 1; i >= > left && > > > a[i] == > > > > > > >> > > 0.0f; i--) { > > > > > > >> > > > > > > > > > > - zeroIndex = i; > > > > > > >> > > > > > > > > > > + if (a[left] < 0.0f) { > > > > > > >> > > > > > > > > > > + zeroIndex = findAnyZero(a, left, n); > > > > > > >> > > > > > > > > > > + > > > > > > >> > > > > > > > > > > + // there is at least one negative > value, so > > > > > range > > > > > > >> > > check is > > > > > > >> > > > > > > not needed > > > > > > >> > > > > > > > > > > + for (int i = zeroIndex - 1; /*i >= > left &&*/ > > > > > > >> a[i] == > > > > > > >> > > 0.0f; i--) { > > > > > > >> > > > > > > > > > > + zeroIndex = i; > > > > > > >> > > > > > > > > > > + } > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > // Turn the right number of positive zeros > > > > > back into > > > > > > >> > > negative zeros > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > 2. We can find the position of the first > > > zero by > > > > > > >> counting > > > > > > >> > > > > > > negative values during preprocessing phase. > > > > > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > > > > > 09:04:19 2010 > > > > > > >> > > > > > > > > > > +++ DualPivotQuicksortC.java Wed May 12 > > > 12:01:24 > > > > > > >> 2010 > > > > > > >> > > > > > > > > > > @@ -1678,7 +1678,7 @@ > > > > > > >> > > > > > > > > > > * Phase 1: Count negative zeros and move > > > NaNs to > > > > > > >> end of > > > > > > >> > > array. > > > > > > >> > > > > > > > > > > */ > > > > > > >> > > > > > > > > > > final int NEGATIVE_ZERO = > > > > > > >> Float.floatToIntBits(-0.0f); > > > > > > >> > > > > > > > > > > - int numNegativeZeros = 0; > > > > > > >> > > > > > > > > > > + int numNegativeZeros = 0, > > > numNegativeValues = 0; > > > > > > >> > > > > > > > > > > int n = right; > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > for (int k = left; k <= n; k++) { > > > > > > >> > > > > > > > > > > @@ -1689,6 +1689,8 @@ > > > > > > >> > > > > > > > > > > } else if (ak != ak) { // i.e., ak is NaN > > > > > > >> > > > > > > > > > > a[k--] = a[n]; > > > > > > >> > > > > > > > > > > a[n--] = Float.NaN; > > > > > > >> > > > > > > > > > > + } else if (ak < 0.0f) { > > > > > > >> > > > > > > > > > > + numNegativeValues++; > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > @@ -1705,7 +1707,7 @@ > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > > > > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > >> > > > > > > > > > > + int zeroIndex = numNegativeValues; > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > for (int i = zeroIndex - 1; i >= left && > > > a[i] == > > > > > > >> 0.0f; > > > > > > >> > > i--) { > > > > > > >> > > > > > > > > > > zeroIndex = i; > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > 3. We can use binary search to find > the first > > > > > > >> zero and > > > > > > >> > > thus > > > > > > >> > > > > > > avoid linear scan. > > > > > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > > > > > 09:04:19 2010 > > > > > > >> > > > > > > > > > > +++ DualPivotQuicksortF.java Wed May 12 > > > 12:03:58 > > > > > > >> 2010 > > > > > > >> > > > > > > > > > > @@ -1705,11 +1705,7 @@ > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > > > > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > >> > > > > > > > > > > - > > > > > > >> > > > > > > > > > > - for (int i = zeroIndex - 1; i >= > left && > > > a[i] == > > > > > > >> > > 0.0f; i--) { > > > > > > >> > > > > > > > > > > - zeroIndex = i; > > > > > > >> > > > > > > > > > > - } > > > > > > >> > > > > > > > > > > + int zeroIndex = findFirstZero(a, > left, n); > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > // Turn the right number of positive zeros > > > > > back into > > > > > > >> > > negative zeros > > > > > > >> > > > > > > > > > > for (int i = zeroIndex, m = zeroIndex + > > > > > > >> > > numNegativeZeros; i < > > > > > > >> > > > > > > m; i++) { > > > > > > >> > > > > > > > > > > @@ -1718,7 +1714,7 @@ > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > /** > > > > > > >> > > > > > > > > > > - * Returns the index of some zero > element > > > in the > > > > > > >> > > specified > > > > > > >> > > > > > > range via > > > > > > >> > > > > > > > > > > + * Returns the index of the first zero > > > element > > > > > > >> in the > > > > > > >> > > > > > > specified range via > > > > > > >> > > > > > > > > > > * binary search. The range is assumed > to be > > > > > > >> sorted, and > > > > > > >> > > must > > > > > > >> > > > > > > contain > > > > > > >> > > > > > > > > > > * at least one zero. > > > > > > >> > > > > > > > > > > * > > > > > > >> > > > > > > > > > > @@ -1726,18 +1722,17 @@ > > > > > > >> > > > > > > > > > > * @param low the index of the first > element, > > > > > > >> inclusive, > > > > > > >> > > to be > > > > > > >> > > > > > > searched > > > > > > >> > > > > > > > > > > * @param high the index of the last > element, > > > > > > >> inclusive, > > > > > > >> > > to be > > > > > > >> > > > > > > searched > > > > > > >> > > > > > > > > > > */ > > > > > > >> > > > > > > > > > > - private static int > findAnyZero(float[] a, > > > > > int low, > > > > > > >> > > int high) { > > > > > > >> > > > > > > > > > > - while (true) { > > > > > > >> > > > > > > > > > > + private static int > findFirstZero(float[] > > > a, int > > > > > > >> low, > > > > > > >> > > int high) { > > > > > > >> > > > > > > > > > > + while (low < high) { > > > > > > >> > > > > > > > > > > int middle = (low + high) >>> 1; > > > > > > >> > > > > > > > > > > float middleValue = a[middle]; > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > if (middleValue < 0.0f) { > > > > > > >> > > > > > > > > > > low = middle + 1; > > > > > > >> > > > > > > > > > > - } else if (middleValue > 0.0f) { > > > > > > >> > > > > > > > > > > - high = middle - 1; > > > > > > >> > > > > > > > > > > - } else { // middleValue == 0.0f > > > > > > >> > > > > > > > > > > - return middle; > > > > > > >> > > > > > > > > > > + } else { // middleValue >= 0.0f > > > > > > >> > > > > > > > > > > + high = middle; > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > + return low; > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > Counting negative values appeared more > > > expensive > > > > > > >> than > > > > > > >> > > any other > > > > > > >> > > > > > > variants. > > > > > > >> > > > > > > > > > > The last proposal seems to me as > efficient > > > as the > > > > > > >> current > > > > > > >> > > > > > > solution is in its worst case - when we have > only one > > > > > > >> negative > > > > > > >> > > zero (in > > > > > > >> > > > > > > the half of array). > > > > > > >> > > > > > > > > > > And it shows the best result if we > have many > > > > > zeros. > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > Regards, > > > > > > >> > > > > > > > > > > Dmytro Sheyko > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > > From: iaroslavski at mail.ru > > > > > > >> > > > > > > > > > > > To: jjb at google.com; > > > dmytro_sheyko at hotmail.com > > > > > > >> > > > > > > > > > > > CC: core-libs-dev at openjdk.java.net; > > > > > > >> iaroslavski at mail.ru > > > > > > >> > > > > > > > > > > > Subject: Re[2]: New portion of > > > improvements for > > > > > > >> > > Dual-Pivot > > > > > > >> > > > > > > Quicksort > > > > > > >> > > > > > > > > > > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > > > > >> > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > Josh, > > > > > > >> > > > > > > > > > > > Dmytro, > > > > > > >> > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > I have done more thoroughly testing > "great - > > > > > > >> less > 5 * > > > > > > >> > > > > > > seventh" vs. "less < e1 && great > e5", > > > > > > >> > > > > > > > > > > > and found that more symmetric code > "less > > > < e1 && > > > > > > >> > > great > e5" > > > > > > >> > > > > > > is little bit faster, ~0.5..0.7% > > > > > > >> > > > > > > > > > > > on both VMs. Other code has not been > > > changed. > > > > > > >> > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > Please, take the latest version in > > > attachment. > > > > > > >> > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > Vladimir > > > > > > >> > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > Tue, 4 May 2010 21:57:42 -0700 > ?????? ?? > > > Joshua > > > > > > >> Bloch > > > > > > >> > > > > > > : > > > > > > >> > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > > Vladimir, > > > > > > >> > > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > > Old: > > > > > > >> > > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > >298 if (less < e1 && great > e5) { > > > > > > >> > > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > > New: > > > > > > >> > > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > >256 if (great - less > 5 * seventh) { > > > > > > >> > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > >Regards, > > > > > > >> > > > > > > > > > > > >Josh From weijun.wang at sun.com Thu May 27 09:27:24 2010 From: weijun.wang at sun.com (weijun.wang at sun.com) Date: Thu, 27 May 2010 09:27:24 +0000 Subject: hg: jdk7/tl/jdk: 6955783: ServiceUnavailableException caught even the secondary DNS is available Message-ID: <20100527092748.468EE46E44@hg.openjdk.java.net> Changeset: d5939d20b762 Author: weijun Date: 2010-05-27 17:24 +0800 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/d5939d20b762 6955783: ServiceUnavailableException caught even the secondary DNS is available Reviewed-by: vinnie ! src/share/classes/com/sun/jndi/dns/DnsClient.java From forax at univ-mlv.fr Thu May 27 14:07:59 2010 From: forax at univ-mlv.fr (=?windows-1252?Q?R=E9mi_Forax?=) Date: Thu, 27 May 2010 16:07:59 +0200 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: , , , , , , <4BF2AAEE.1040706@mail.ru>, , <4BF3B8F5.1010409@univ-mlv.fr> Message-ID: <4BFE7CBF.3070405@univ-mlv.fr> Le 20/05/2010 13:25, Dmytro Sheyko a ?crit : > Hi Remi, > > I believe that it is up to javac to generate compact and > interpretation-efficient bytecode. No, javac is dumb, at least, when it translates instructions. And JITs love that. > But anyway the first case seems to as acceptable as the second one. So > I don't care which style is used (of course, if it's consistent). > > Thanks, > Dmytro Sheyko R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From ahughes at redhat.com Fri May 28 16:01:33 2010 From: ahughes at redhat.com (ahughes at redhat.com) Date: Fri, 28 May 2010 16:01:33 +0000 Subject: hg: jdk7/tl/jdk: 2 new changesets Message-ID: <20100528160232.1642146E77@hg.openjdk.java.net> Changeset: 0454cb04a407 Author: andrew Date: 2010-05-28 16:59 +0100 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/0454cb04a407 6956840: (ch) Rawtype warning when compiling sun.nio.ch.CompletedFuture Summary: Add missing generic type to CompletedFuture construction and remove unneeded SuppressWarnings annotations. Reviewed-by: alanb ! src/share/classes/sun/nio/ch/CompletedFuture.java Changeset: 0f58be815a2e Author: andrew Date: 2010-05-28 17:01 +0100 URL: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/0f58be815a2e Merge From lana.steuck at oracle.com Fri May 28 21:58:08 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Fri, 28 May 2010 21:58:08 +0000 Subject: hg: jdk7/tl: 3 new changesets Message-ID: <20100528215808.7475A46E81@hg.openjdk.java.net> Changeset: 412712f77af6 Author: ohair Date: 2010-05-25 15:51 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/rev/412712f77af6 6943119: Rebrand source copyright notices Reviewed-by: darcy ! Makefile ! make/Defs-internal.gmk ! make/corba-rules.gmk ! make/deploy-rules.gmk ! make/hotspot-rules.gmk ! make/install-rules.gmk ! make/jaxp-rules.gmk ! make/jaxws-rules.gmk ! make/jdk-rules.gmk ! make/jprt.gmk ! make/jprt.properties ! make/langtools-rules.gmk ! make/sanity-rules.gmk ! make/sponsors-rules.gmk ! make/templates/bsd-header ! make/templates/gpl-cp-header ! test/Makefile Changeset: fd3663286e77 Author: ohair Date: 2010-05-26 10:35 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/rev/fd3663286e77 Merge Changeset: cf71cb515116 Author: mikejwre Date: 2010-05-27 10:57 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/rev/cf71cb515116 Added tag jdk7-b95 for changeset fd3663286e77 ! .hgtags From lana.steuck at oracle.com Fri May 28 22:00:00 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Fri, 28 May 2010 22:00:00 +0000 Subject: hg: jdk7/tl/hotspot: Added tag jdk7-b95 for changeset 91d861ba858d Message-ID: <20100528220002.3C36B46E82@hg.openjdk.java.net> Changeset: 2b554795d0f4 Author: mikejwre Date: 2010-05-27 10:57 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/hotspot/rev/2b554795d0f4 Added tag jdk7-b95 for changeset 91d861ba858d ! .hgtags From lana.steuck at oracle.com Fri May 28 22:03:08 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Fri, 28 May 2010 22:03:08 +0000 Subject: hg: jdk7/tl/jaxp: 3 new changesets Message-ID: <20100528220308.A88FE46E83@hg.openjdk.java.net> Changeset: 72d78db95fb1 Author: ohair Date: 2010-05-25 15:52 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jaxp/rev/72d78db95fb1 6943119: Rebrand source copyright notices Reviewed-by: darcy ! build-defs.xml ! build-drop-template.xml ! build.properties ! build.xml ! jaxp.properties ! make/Makefile ! make/jprt.properties Changeset: 07050840f98c Author: ohair Date: 2010-05-26 10:41 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jaxp/rev/07050840f98c Merge Changeset: 9510ed0e1c7a Author: mikejwre Date: 2010-05-27 10:57 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jaxp/rev/9510ed0e1c7a Added tag jdk7-b95 for changeset 07050840f98c ! .hgtags From lana.steuck at oracle.com Fri May 28 22:03:14 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Fri, 28 May 2010 22:03:14 +0000 Subject: hg: jdk7/tl/jaxws: 3 new changesets Message-ID: <20100528220314.9B4B346E84@hg.openjdk.java.net> Changeset: 4ac192952d75 Author: ohair Date: 2010-05-25 15:53 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jaxws/rev/4ac192952d75 6943119: Rebrand source copyright notices Reviewed-by: darcy ! build-defs.xml ! build-drop-template.xml ! build.properties ! build.xml ! jaxws.properties ! make/Makefile ! make/jprt.properties Changeset: ee06cfb113d5 Author: ohair Date: 2010-05-26 10:40 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jaxws/rev/ee06cfb113d5 Merge Changeset: 208fd4451232 Author: mikejwre Date: 2010-05-27 10:57 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/jaxws/rev/208fd4451232 Added tag jdk7-b95 for changeset ee06cfb113d5 ! .hgtags From lana.steuck at oracle.com Fri May 28 22:36:18 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Fri, 28 May 2010 22:36:18 +0000 Subject: hg: jdk7/tl/langtools: 4 new changesets Message-ID: <20100528223626.4885E46E86@hg.openjdk.java.net> Changeset: 9d9f26857129 Author: ohair Date: 2010-05-25 15:54 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/9d9f26857129 6943119: Rebrand source copyright notices Reviewed-by: darcy ! make/Makefile ! make/Makefile-classic ! make/build.properties ! make/build.xml ! make/jprt.properties ! make/netbeans/langtools/build.xml ! make/netbeans/langtools/nbproject/project.xml ! make/netbeans/langtools/nbproject/standard-context-menu-items.ent ! make/netbeans/langtools/nbproject/standard-ide-actions.ent ! make/test/HelloWorld.java ! make/test/bootstrap/javac.sh ! make/test/bootstrap/javadoc.sh ! make/test/bootstrap/javah.sh ! make/test/contents.sh ! make/test/lib/apt.sh ! make/test/lib/classes.sh ! make/test/lib/javac.sh ! make/test/lib/javadoc.sh ! make/test/lib/javah.sh ! make/test/lib/javap.sh ! make/test/lib/src.sh ! make/tools/CompileProperties/CompileProperties.java ! make/tools/CompileProperties/CompilePropertiesTask.java ! make/tools/GenStubs/GenStubs.java ! make/tools/SelectTool/SelectToolTask.java ! src/share/bin/launcher.sh-template ! src/share/classes/com/sun/javadoc/AnnotationDesc.java ! src/share/classes/com/sun/javadoc/AnnotationTypeDoc.java ! src/share/classes/com/sun/javadoc/AnnotationTypeElementDoc.java ! src/share/classes/com/sun/javadoc/AnnotationValue.java ! src/share/classes/com/sun/javadoc/ClassDoc.java ! src/share/classes/com/sun/javadoc/ConstructorDoc.java ! src/share/classes/com/sun/javadoc/Doc.java ! src/share/classes/com/sun/javadoc/DocErrorReporter.java ! src/share/classes/com/sun/javadoc/Doclet.java ! src/share/classes/com/sun/javadoc/ExecutableMemberDoc.java ! src/share/classes/com/sun/javadoc/FieldDoc.java ! src/share/classes/com/sun/javadoc/LanguageVersion.java ! src/share/classes/com/sun/javadoc/MemberDoc.java ! src/share/classes/com/sun/javadoc/MethodDoc.java ! src/share/classes/com/sun/javadoc/PackageDoc.java ! src/share/classes/com/sun/javadoc/ParamTag.java ! src/share/classes/com/sun/javadoc/Parameter.java ! src/share/classes/com/sun/javadoc/ParameterizedType.java ! src/share/classes/com/sun/javadoc/ProgramElementDoc.java ! src/share/classes/com/sun/javadoc/RootDoc.java ! src/share/classes/com/sun/javadoc/SeeTag.java ! src/share/classes/com/sun/javadoc/SerialFieldTag.java ! src/share/classes/com/sun/javadoc/SourcePosition.java ! src/share/classes/com/sun/javadoc/Tag.java ! src/share/classes/com/sun/javadoc/ThrowsTag.java ! src/share/classes/com/sun/javadoc/Type.java ! src/share/classes/com/sun/javadoc/TypeVariable.java ! src/share/classes/com/sun/javadoc/WildcardType.java ! src/share/classes/com/sun/javadoc/package.html ! src/share/classes/com/sun/mirror/apt/AnnotationProcessor.java ! src/share/classes/com/sun/mirror/apt/AnnotationProcessorEnvironment.java ! src/share/classes/com/sun/mirror/apt/AnnotationProcessorFactory.java ! src/share/classes/com/sun/mirror/apt/AnnotationProcessorListener.java ! src/share/classes/com/sun/mirror/apt/AnnotationProcessors.java ! src/share/classes/com/sun/mirror/apt/Filer.java ! src/share/classes/com/sun/mirror/apt/Messager.java ! src/share/classes/com/sun/mirror/apt/RoundCompleteEvent.java ! src/share/classes/com/sun/mirror/apt/RoundCompleteListener.java ! src/share/classes/com/sun/mirror/apt/RoundState.java ! src/share/classes/com/sun/mirror/apt/package-info.java ! src/share/classes/com/sun/mirror/declaration/AnnotationMirror.java ! src/share/classes/com/sun/mirror/declaration/AnnotationTypeDeclaration.java ! src/share/classes/com/sun/mirror/declaration/AnnotationTypeElementDeclaration.java ! src/share/classes/com/sun/mirror/declaration/AnnotationValue.java ! src/share/classes/com/sun/mirror/declaration/ClassDeclaration.java ! src/share/classes/com/sun/mirror/declaration/ConstructorDeclaration.java ! src/share/classes/com/sun/mirror/declaration/Declaration.java ! src/share/classes/com/sun/mirror/declaration/EnumConstantDeclaration.java ! src/share/classes/com/sun/mirror/declaration/EnumDeclaration.java ! src/share/classes/com/sun/mirror/declaration/ExecutableDeclaration.java ! src/share/classes/com/sun/mirror/declaration/FieldDeclaration.java ! src/share/classes/com/sun/mirror/declaration/InterfaceDeclaration.java ! src/share/classes/com/sun/mirror/declaration/MemberDeclaration.java ! src/share/classes/com/sun/mirror/declaration/MethodDeclaration.java ! src/share/classes/com/sun/mirror/declaration/Modifier.java ! src/share/classes/com/sun/mirror/declaration/PackageDeclaration.java ! src/share/classes/com/sun/mirror/declaration/ParameterDeclaration.java ! src/share/classes/com/sun/mirror/declaration/TypeDeclaration.java ! src/share/classes/com/sun/mirror/declaration/TypeParameterDeclaration.java ! src/share/classes/com/sun/mirror/declaration/package-info.java ! src/share/classes/com/sun/mirror/overview.html ! src/share/classes/com/sun/mirror/type/AnnotationType.java ! src/share/classes/com/sun/mirror/type/ArrayType.java ! src/share/classes/com/sun/mirror/type/ClassType.java ! src/share/classes/com/sun/mirror/type/DeclaredType.java ! src/share/classes/com/sun/mirror/type/EnumType.java ! src/share/classes/com/sun/mirror/type/InterfaceType.java ! src/share/classes/com/sun/mirror/type/MirroredTypeException.java ! src/share/classes/com/sun/mirror/type/MirroredTypesException.java ! src/share/classes/com/sun/mirror/type/PrimitiveType.java ! src/share/classes/com/sun/mirror/type/ReferenceType.java ! src/share/classes/com/sun/mirror/type/TypeMirror.java ! src/share/classes/com/sun/mirror/type/TypeVariable.java ! src/share/classes/com/sun/mirror/type/VoidType.java ! src/share/classes/com/sun/mirror/type/WildcardType.java ! src/share/classes/com/sun/mirror/type/package-info.java ! src/share/classes/com/sun/mirror/util/DeclarationFilter.java ! src/share/classes/com/sun/mirror/util/DeclarationScanner.java ! src/share/classes/com/sun/mirror/util/DeclarationVisitor.java ! src/share/classes/com/sun/mirror/util/DeclarationVisitors.java ! src/share/classes/com/sun/mirror/util/Declarations.java ! src/share/classes/com/sun/mirror/util/SimpleDeclarationVisitor.java ! src/share/classes/com/sun/mirror/util/SimpleTypeVisitor.java ! src/share/classes/com/sun/mirror/util/SourceOrderDeclScanner.java ! src/share/classes/com/sun/mirror/util/SourcePosition.java ! src/share/classes/com/sun/mirror/util/TypeVisitor.java ! src/share/classes/com/sun/mirror/util/Types.java ! src/share/classes/com/sun/mirror/util/package-info.java ! src/share/classes/com/sun/source/tree/AnnotatedTypeTree.java ! src/share/classes/com/sun/source/tree/AnnotationTree.java ! src/share/classes/com/sun/source/tree/ArrayAccessTree.java ! src/share/classes/com/sun/source/tree/ArrayTypeTree.java ! src/share/classes/com/sun/source/tree/AssertTree.java ! src/share/classes/com/sun/source/tree/AssignmentTree.java ! src/share/classes/com/sun/source/tree/BinaryTree.java ! src/share/classes/com/sun/source/tree/BlockTree.java ! src/share/classes/com/sun/source/tree/BreakTree.java ! src/share/classes/com/sun/source/tree/CaseTree.java ! src/share/classes/com/sun/source/tree/CatchTree.java ! src/share/classes/com/sun/source/tree/ClassTree.java ! src/share/classes/com/sun/source/tree/CompilationUnitTree.java ! src/share/classes/com/sun/source/tree/CompoundAssignmentTree.java ! src/share/classes/com/sun/source/tree/ConditionalExpressionTree.java ! src/share/classes/com/sun/source/tree/ContinueTree.java ! src/share/classes/com/sun/source/tree/DoWhileLoopTree.java ! src/share/classes/com/sun/source/tree/EmptyStatementTree.java ! src/share/classes/com/sun/source/tree/EnhancedForLoopTree.java ! src/share/classes/com/sun/source/tree/ErroneousTree.java ! src/share/classes/com/sun/source/tree/ExpressionStatementTree.java ! src/share/classes/com/sun/source/tree/ExpressionTree.java ! src/share/classes/com/sun/source/tree/ForLoopTree.java ! src/share/classes/com/sun/source/tree/IdentifierTree.java ! src/share/classes/com/sun/source/tree/IfTree.java ! src/share/classes/com/sun/source/tree/ImportTree.java ! src/share/classes/com/sun/source/tree/InstanceOfTree.java ! src/share/classes/com/sun/source/tree/LabeledStatementTree.java ! src/share/classes/com/sun/source/tree/LineMap.java ! src/share/classes/com/sun/source/tree/LiteralTree.java ! src/share/classes/com/sun/source/tree/MemberSelectTree.java ! src/share/classes/com/sun/source/tree/MethodInvocationTree.java ! src/share/classes/com/sun/source/tree/MethodTree.java ! src/share/classes/com/sun/source/tree/ModifiersTree.java ! src/share/classes/com/sun/source/tree/NewArrayTree.java ! src/share/classes/com/sun/source/tree/NewClassTree.java ! src/share/classes/com/sun/source/tree/ParameterizedTypeTree.java ! src/share/classes/com/sun/source/tree/ParenthesizedTree.java ! src/share/classes/com/sun/source/tree/PrimitiveTypeTree.java ! src/share/classes/com/sun/source/tree/ReturnTree.java ! src/share/classes/com/sun/source/tree/Scope.java ! src/share/classes/com/sun/source/tree/StatementTree.java ! src/share/classes/com/sun/source/tree/SwitchTree.java ! src/share/classes/com/sun/source/tree/SynchronizedTree.java ! src/share/classes/com/sun/source/tree/ThrowTree.java ! src/share/classes/com/sun/source/tree/Tree.java ! src/share/classes/com/sun/source/tree/TreeVisitor.java ! src/share/classes/com/sun/source/tree/TryTree.java ! src/share/classes/com/sun/source/tree/TypeCastTree.java ! src/share/classes/com/sun/source/tree/TypeParameterTree.java ! src/share/classes/com/sun/source/tree/UnaryTree.java ! src/share/classes/com/sun/source/tree/VariableTree.java ! src/share/classes/com/sun/source/tree/WhileLoopTree.java ! src/share/classes/com/sun/source/tree/WildcardTree.java ! src/share/classes/com/sun/source/tree/package-info.java ! src/share/classes/com/sun/source/util/AbstractTypeProcessor.java ! src/share/classes/com/sun/source/util/JavacTask.java ! src/share/classes/com/sun/source/util/SimpleTreeVisitor.java ! src/share/classes/com/sun/source/util/SourcePositions.java ! src/share/classes/com/sun/source/util/TaskEvent.java ! src/share/classes/com/sun/source/util/TaskListener.java ! src/share/classes/com/sun/source/util/TreePath.java ! src/share/classes/com/sun/source/util/TreePathScanner.java ! src/share/classes/com/sun/source/util/TreeScanner.java ! src/share/classes/com/sun/source/util/Trees.java ! src/share/classes/com/sun/source/util/package-info.java ! src/share/classes/com/sun/tools/apt/Main.java ! src/share/classes/com/sun/tools/apt/comp/AnnotationProcessingError.java ! src/share/classes/com/sun/tools/apt/comp/Apt.java ! src/share/classes/com/sun/tools/apt/comp/BootstrapAPF.java ! src/share/classes/com/sun/tools/apt/comp/PrintAP.java ! src/share/classes/com/sun/tools/apt/comp/UsageMessageNeededException.java ! src/share/classes/com/sun/tools/apt/main/CommandLine.java ! src/share/classes/com/sun/tools/apt/main/JavaCompiler.java ! src/share/classes/com/sun/tools/apt/main/Main.java ! src/share/classes/com/sun/tools/apt/mirror/AptEnv.java ! src/share/classes/com/sun/tools/apt/mirror/apt/AnnotationProcessorEnvironmentImpl.java ! src/share/classes/com/sun/tools/apt/mirror/apt/FilerImpl.java ! src/share/classes/com/sun/tools/apt/mirror/apt/MessagerImpl.java ! src/share/classes/com/sun/tools/apt/mirror/apt/RoundCompleteEventImpl.java ! src/share/classes/com/sun/tools/apt/mirror/apt/RoundStateImpl.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationMirrorImpl.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationProxyMaker.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationTypeDeclarationImpl.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationTypeElementDeclarationImpl.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationValueImpl.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/ClassDeclarationImpl.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/Constants.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/ConstructorDeclarationImpl.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/DeclarationImpl.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/DeclarationMaker.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/EnumConstantDeclarationImpl.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/EnumDeclarationImpl.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/ExecutableDeclarationImpl.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/FieldDeclarationImpl.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/InterfaceDeclarationImpl.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/MemberDeclarationImpl.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/MethodDeclarationImpl.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/PackageDeclarationImpl.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/ParameterDeclarationImpl.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/TypeDeclarationImpl.java ! src/share/classes/com/sun/tools/apt/mirror/declaration/TypeParameterDeclarationImpl.java ! src/share/classes/com/sun/tools/apt/mirror/type/AnnotationTypeImpl.java ! src/share/classes/com/sun/tools/apt/mirror/type/ArrayTypeImpl.java ! src/share/classes/com/sun/tools/apt/mirror/type/ClassTypeImpl.java ! src/share/classes/com/sun/tools/apt/mirror/type/DeclaredTypeImpl.java ! src/share/classes/com/sun/tools/apt/mirror/type/EnumTypeImpl.java ! src/share/classes/com/sun/tools/apt/mirror/type/InterfaceTypeImpl.java ! src/share/classes/com/sun/tools/apt/mirror/type/PrimitiveTypeImpl.java ! src/share/classes/com/sun/tools/apt/mirror/type/TypeMaker.java ! src/share/classes/com/sun/tools/apt/mirror/type/TypeMirrorImpl.java ! src/share/classes/com/sun/tools/apt/mirror/type/TypeVariableImpl.java ! src/share/classes/com/sun/tools/apt/mirror/type/VoidTypeImpl.java ! src/share/classes/com/sun/tools/apt/mirror/type/WildcardTypeImpl.java ! src/share/classes/com/sun/tools/apt/mirror/util/DeclarationsImpl.java ! src/share/classes/com/sun/tools/apt/mirror/util/SourcePositionImpl.java ! src/share/classes/com/sun/tools/apt/mirror/util/TypesImpl.java ! src/share/classes/com/sun/tools/apt/resources/apt.properties ! src/share/classes/com/sun/tools/apt/resources/apt_ja.properties ! src/share/classes/com/sun/tools/apt/resources/apt_zh_CN.properties ! src/share/classes/com/sun/tools/apt/util/Bark.java ! src/share/classes/com/sun/tools/classfile/AccessFlags.java ! src/share/classes/com/sun/tools/classfile/Annotation.java ! src/share/classes/com/sun/tools/classfile/AnnotationDefault_attribute.java ! src/share/classes/com/sun/tools/classfile/Attribute.java ! src/share/classes/com/sun/tools/classfile/AttributeException.java ! src/share/classes/com/sun/tools/classfile/Attributes.java ! src/share/classes/com/sun/tools/classfile/CharacterRangeTable_attribute.java ! src/share/classes/com/sun/tools/classfile/ClassFile.java ! src/share/classes/com/sun/tools/classfile/ClassReader.java ! src/share/classes/com/sun/tools/classfile/ClassTranslator.java ! src/share/classes/com/sun/tools/classfile/ClassWriter.java ! src/share/classes/com/sun/tools/classfile/Code_attribute.java ! src/share/classes/com/sun/tools/classfile/CompilationID_attribute.java ! src/share/classes/com/sun/tools/classfile/ConstantPool.java ! src/share/classes/com/sun/tools/classfile/ConstantPoolException.java ! src/share/classes/com/sun/tools/classfile/ConstantValue_attribute.java ! src/share/classes/com/sun/tools/classfile/DefaultAttribute.java ! src/share/classes/com/sun/tools/classfile/Dependencies.java ! src/share/classes/com/sun/tools/classfile/Dependency.java ! src/share/classes/com/sun/tools/classfile/Deprecated_attribute.java ! src/share/classes/com/sun/tools/classfile/Descriptor.java ! src/share/classes/com/sun/tools/classfile/DescriptorException.java ! src/share/classes/com/sun/tools/classfile/EnclosingMethod_attribute.java ! src/share/classes/com/sun/tools/classfile/Exceptions_attribute.java ! src/share/classes/com/sun/tools/classfile/ExtendedAnnotation.java ! src/share/classes/com/sun/tools/classfile/Field.java ! src/share/classes/com/sun/tools/classfile/InnerClasses_attribute.java ! src/share/classes/com/sun/tools/classfile/Instruction.java ! src/share/classes/com/sun/tools/classfile/LineNumberTable_attribute.java ! src/share/classes/com/sun/tools/classfile/LocalVariableTable_attribute.java ! src/share/classes/com/sun/tools/classfile/LocalVariableTypeTable_attribute.java ! src/share/classes/com/sun/tools/classfile/Method.java ! src/share/classes/com/sun/tools/classfile/Opcode.java ! src/share/classes/com/sun/tools/classfile/RuntimeAnnotations_attribute.java ! src/share/classes/com/sun/tools/classfile/RuntimeInvisibleAnnotations_attribute.java ! src/share/classes/com/sun/tools/classfile/RuntimeInvisibleParameterAnnotations_attribute.java ! src/share/classes/com/sun/tools/classfile/RuntimeInvisibleTypeAnnotations_attribute.java ! src/share/classes/com/sun/tools/classfile/RuntimeParameterAnnotations_attribute.java ! src/share/classes/com/sun/tools/classfile/RuntimeTypeAnnotations_attribute.java ! src/share/classes/com/sun/tools/classfile/RuntimeVisibleAnnotations_attribute.java ! src/share/classes/com/sun/tools/classfile/RuntimeVisibleParameterAnnotations_attribute.java ! src/share/classes/com/sun/tools/classfile/RuntimeVisibleTypeAnnotations_attribute.java ! src/share/classes/com/sun/tools/classfile/Signature.java ! src/share/classes/com/sun/tools/classfile/Signature_attribute.java ! src/share/classes/com/sun/tools/classfile/SourceDebugExtension_attribute.java ! src/share/classes/com/sun/tools/classfile/SourceFile_attribute.java ! src/share/classes/com/sun/tools/classfile/SourceID_attribute.java ! src/share/classes/com/sun/tools/classfile/StackMapTable_attribute.java ! src/share/classes/com/sun/tools/classfile/StackMap_attribute.java ! src/share/classes/com/sun/tools/classfile/Synthetic_attribute.java ! src/share/classes/com/sun/tools/classfile/Type.java ! src/share/classes/com/sun/tools/doclets/Taglet.java ! src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/AbstractIndexWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/AbstractTreeWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/DeprecatedListWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java ! src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialMethodWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/LinkInfoImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/LinkOutputImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/NestedClassWriterImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/PackageFrameWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/SerializedFormWriterImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/SingleIndexWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/SplitIndexWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/StylesheetWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/SubWriterHolderWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/TagletOutputImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/TagletWriterImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/TreeWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/WriterFactoryImpl.java ! src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java ! src/share/classes/com/sun/tools/doclets/formats/html/markup/package.html ! src/share/classes/com/sun/tools/doclets/formats/html/package.html ! src/share/classes/com/sun/tools/doclets/internal/toolkit/AbstractDoclet.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeOptionalMemberWriter.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeRequiredMemberWriter.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeWriter.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/ClassWriter.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/ConstantsSummaryWriter.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/ConstructorWriter.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/EnumConstantWriter.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/FieldWriter.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/MemberSummaryWriter.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/MethodWriter.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/NestedClassWriter.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/PackageSummaryWriter.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/SerializedFormWriter.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/WriterFactory.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractMemberBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeOptionalMemberBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeRequiredMemberBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ClassBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ConstantsSummaryBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ConstructorBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/EnumConstantBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/FieldBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/LayoutParser.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MethodBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/PackageSummaryBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/SerializedFormBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/package.html ! src/share/classes/com/sun/tools/doclets/internal/toolkit/package.html ! src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BaseExecutableMemberTaglet.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BaseInlineTaglet.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/BaseTaglet.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/CodeTaglet.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/DeprecatedTaglet.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/DocRootTaglet.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/InheritDocTaglet.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/InheritableTaglet.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LegacyTaglet.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LiteralTaglet.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ParamTaglet.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ReturnTaglet.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SeeTaglet.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/SimpleTaglet.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/Taglet.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletOutput.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletWriter.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ThrowsTaglet.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/package.html ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/ClassDocCatalog.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/ClassTree.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/ClassUseMapper.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/CommentedMethodFinder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DeprecatedAPIListBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DirectoryManager.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFinder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletAbortException.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletConstants.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Extern.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Group.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/ImplementedMethods.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/IndexBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MessageRetriever.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MetaKeywords.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MethodFinder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PackageListWriter.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/SourcePath.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/SourceToHTMLConverter.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/TaggedMethodFinder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/TextTag.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/VisibleMemberMap.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkFactory.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkInfo.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkOutput.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/package.html ! src/share/classes/com/sun/tools/doclets/internal/toolkit/util/package.html ! src/share/classes/com/sun/tools/doclets/package.html ! src/share/classes/com/sun/tools/doclets/standard/Standard.java ! src/share/classes/com/sun/tools/javac/Launcher.java ! src/share/classes/com/sun/tools/javac/Main.java ! src/share/classes/com/sun/tools/javac/Server.java ! src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java ! src/share/classes/com/sun/tools/javac/api/Formattable.java ! src/share/classes/com/sun/tools/javac/api/JavacScope.java ! src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java ! src/share/classes/com/sun/tools/javac/api/JavacTool.java ! src/share/classes/com/sun/tools/javac/api/JavacTrees.java ! src/share/classes/com/sun/tools/javac/api/Messages.java ! src/share/classes/com/sun/tools/javac/api/WrappingJavaFileManager.java ! src/share/classes/com/sun/tools/javac/code/Attribute.java ! src/share/classes/com/sun/tools/javac/code/BoundKind.java ! src/share/classes/com/sun/tools/javac/code/Flags.java ! src/share/classes/com/sun/tools/javac/code/Kinds.java ! src/share/classes/com/sun/tools/javac/code/Lint.java ! src/share/classes/com/sun/tools/javac/code/Printer.java ! src/share/classes/com/sun/tools/javac/code/Scope.java ! src/share/classes/com/sun/tools/javac/code/Source.java ! src/share/classes/com/sun/tools/javac/code/Symbol.java ! src/share/classes/com/sun/tools/javac/code/Symtab.java ! src/share/classes/com/sun/tools/javac/code/TargetType.java ! src/share/classes/com/sun/tools/javac/code/Type.java ! src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java ! src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java ! src/share/classes/com/sun/tools/javac/code/TypeTags.java ! src/share/classes/com/sun/tools/javac/code/Types.java ! src/share/classes/com/sun/tools/javac/comp/Annotate.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/AttrContext.java ! src/share/classes/com/sun/tools/javac/comp/AttrContextEnv.java ! src/share/classes/com/sun/tools/javac/comp/Check.java ! src/share/classes/com/sun/tools/javac/comp/ConstFold.java ! src/share/classes/com/sun/tools/javac/comp/Enter.java ! src/share/classes/com/sun/tools/javac/comp/Env.java ! src/share/classes/com/sun/tools/javac/comp/Flow.java ! src/share/classes/com/sun/tools/javac/comp/Infer.java ! src/share/classes/com/sun/tools/javac/comp/Lower.java ! src/share/classes/com/sun/tools/javac/comp/MemberEnter.java ! src/share/classes/com/sun/tools/javac/comp/Resolve.java ! src/share/classes/com/sun/tools/javac/comp/Todo.java ! src/share/classes/com/sun/tools/javac/comp/TransTypes.java ! src/share/classes/com/sun/tools/javac/file/BaseFileObject.java ! src/share/classes/com/sun/tools/javac/file/CacheFSInfo.java ! src/share/classes/com/sun/tools/javac/file/JavacFileManager.java ! src/share/classes/com/sun/tools/javac/file/Paths.java ! src/share/classes/com/sun/tools/javac/file/RegularFileObject.java ! src/share/classes/com/sun/tools/javac/file/RelativePath.java ! src/share/classes/com/sun/tools/javac/file/SymbolArchive.java ! src/share/classes/com/sun/tools/javac/file/ZipArchive.java ! src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java ! src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java ! src/share/classes/com/sun/tools/javac/jvm/ByteCodes.java ! src/share/classes/com/sun/tools/javac/jvm/CRTFlags.java ! src/share/classes/com/sun/tools/javac/jvm/CRTable.java ! src/share/classes/com/sun/tools/javac/jvm/ClassFile.java ! src/share/classes/com/sun/tools/javac/jvm/ClassReader.java ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java ! src/share/classes/com/sun/tools/javac/jvm/Code.java ! src/share/classes/com/sun/tools/javac/jvm/Gen.java ! src/share/classes/com/sun/tools/javac/jvm/Items.java ! src/share/classes/com/sun/tools/javac/jvm/Pool.java ! src/share/classes/com/sun/tools/javac/jvm/Target.java ! src/share/classes/com/sun/tools/javac/jvm/UninitializedType.java ! src/share/classes/com/sun/tools/javac/main/CommandLine.java ! src/share/classes/com/sun/tools/javac/main/JavaCompiler.java ! src/share/classes/com/sun/tools/javac/main/JavacOption.java ! src/share/classes/com/sun/tools/javac/main/Main.java ! src/share/classes/com/sun/tools/javac/main/OptionName.java ! src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java ! src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java ! src/share/classes/com/sun/tools/javac/model/FilteredMemberList.java ! src/share/classes/com/sun/tools/javac/model/JavacElements.java ! src/share/classes/com/sun/tools/javac/model/JavacSourcePosition.java ! src/share/classes/com/sun/tools/javac/model/JavacTypes.java ! src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java ! src/share/classes/com/sun/tools/javac/nio/PathFileManager.java ! src/share/classes/com/sun/tools/javac/nio/PathFileObject.java ! src/share/classes/com/sun/tools/javac/parser/DocCommentScanner.java ! src/share/classes/com/sun/tools/javac/parser/EndPosParser.java ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java ! src/share/classes/com/sun/tools/javac/parser/Keywords.java ! src/share/classes/com/sun/tools/javac/parser/Lexer.java ! src/share/classes/com/sun/tools/javac/parser/Parser.java ! src/share/classes/com/sun/tools/javac/parser/ParserFactory.java ! src/share/classes/com/sun/tools/javac/parser/Scanner.java ! src/share/classes/com/sun/tools/javac/parser/Token.java ! src/share/classes/com/sun/tools/javac/processing/AnnotationProcessingError.java ! src/share/classes/com/sun/tools/javac/processing/JavacFiler.java ! src/share/classes/com/sun/tools/javac/processing/JavacMessager.java ! src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java ! src/share/classes/com/sun/tools/javac/processing/JavacRoundEnvironment.java ! src/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java ! src/share/classes/com/sun/tools/javac/processing/ServiceProxy.java ! src/share/classes/com/sun/tools/javac/resources/compiler.properties ! src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties ! src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties ! src/share/classes/com/sun/tools/javac/resources/javac.properties ! src/share/classes/com/sun/tools/javac/resources/javac_ja.properties ! src/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties ! src/share/classes/com/sun/tools/javac/resources/legacy.properties ! src/share/classes/com/sun/tools/javac/resources/version.properties-template ! src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java ! src/share/classes/com/sun/tools/javac/tree/JCTree.java ! src/share/classes/com/sun/tools/javac/tree/Pretty.java ! src/share/classes/com/sun/tools/javac/tree/TreeCopier.java ! src/share/classes/com/sun/tools/javac/tree/TreeInfo.java ! src/share/classes/com/sun/tools/javac/tree/TreeMaker.java ! src/share/classes/com/sun/tools/javac/tree/TreeScanner.java ! src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java ! src/share/classes/com/sun/tools/javac/util/Abort.java ! src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java ! src/share/classes/com/sun/tools/javac/util/AbstractLog.java ! src/share/classes/com/sun/tools/javac/util/BaseFileManager.java ! src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java ! src/share/classes/com/sun/tools/javac/util/Bits.java ! src/share/classes/com/sun/tools/javac/util/ByteBuffer.java ! src/share/classes/com/sun/tools/javac/util/ClientCodeException.java ! src/share/classes/com/sun/tools/javac/util/CloseableURLClassLoader.java ! src/share/classes/com/sun/tools/javac/util/Constants.java ! src/share/classes/com/sun/tools/javac/util/Context.java ! src/share/classes/com/sun/tools/javac/util/Convert.java ! src/share/classes/com/sun/tools/javac/util/DiagnosticSource.java ! src/share/classes/com/sun/tools/javac/util/FatalError.java ! src/share/classes/com/sun/tools/javac/util/ForwardingDiagnosticFormatter.java ! src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java ! src/share/classes/com/sun/tools/javac/util/JavacMessages.java ! src/share/classes/com/sun/tools/javac/util/LayoutCharacters.java ! src/share/classes/com/sun/tools/javac/util/List.java ! src/share/classes/com/sun/tools/javac/util/ListBuffer.java ! src/share/classes/com/sun/tools/javac/util/Log.java ! src/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java ! src/share/classes/com/sun/tools/javac/util/Name.java ! src/share/classes/com/sun/tools/javac/util/Names.java ! src/share/classes/com/sun/tools/javac/util/Options.java ! src/share/classes/com/sun/tools/javac/util/Pair.java ! src/share/classes/com/sun/tools/javac/util/Position.java ! src/share/classes/com/sun/tools/javac/util/PropagatedException.java ! src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java ! src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java ! src/share/classes/com/sun/tools/javac/util/SharedNameTable.java ! src/share/classes/com/sun/tools/javac/util/UnsharedNameTable.java ! src/share/classes/com/sun/tools/javac/util/Warner.java ! src/share/classes/com/sun/tools/javadoc/AbstractTypeImpl.java ! src/share/classes/com/sun/tools/javadoc/AnnotationDescImpl.java ! src/share/classes/com/sun/tools/javadoc/AnnotationTypeDocImpl.java ! src/share/classes/com/sun/tools/javadoc/AnnotationTypeElementDocImpl.java ! src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java ! src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java ! src/share/classes/com/sun/tools/javadoc/Comment.java ! src/share/classes/com/sun/tools/javadoc/ConstructorDocImpl.java ! src/share/classes/com/sun/tools/javadoc/DocEnv.java ! src/share/classes/com/sun/tools/javadoc/DocImpl.java ! src/share/classes/com/sun/tools/javadoc/DocLocale.java ! src/share/classes/com/sun/tools/javadoc/DocletInvoker.java ! src/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java ! src/share/classes/com/sun/tools/javadoc/FieldDocImpl.java ! src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java ! src/share/classes/com/sun/tools/javadoc/JavadocEnter.java ! src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java ! src/share/classes/com/sun/tools/javadoc/JavadocTodo.java ! src/share/classes/com/sun/tools/javadoc/JavadocTool.java ! src/share/classes/com/sun/tools/javadoc/Main.java ! src/share/classes/com/sun/tools/javadoc/MemberDocImpl.java ! src/share/classes/com/sun/tools/javadoc/Messager.java ! src/share/classes/com/sun/tools/javadoc/MethodDocImpl.java ! src/share/classes/com/sun/tools/javadoc/ModifierFilter.java ! src/share/classes/com/sun/tools/javadoc/PackageDocImpl.java ! src/share/classes/com/sun/tools/javadoc/ParamTagImpl.java ! src/share/classes/com/sun/tools/javadoc/ParameterImpl.java ! src/share/classes/com/sun/tools/javadoc/ParameterizedTypeImpl.java ! src/share/classes/com/sun/tools/javadoc/PrimitiveType.java ! src/share/classes/com/sun/tools/javadoc/ProgramElementDocImpl.java ! src/share/classes/com/sun/tools/javadoc/RootDocImpl.java ! src/share/classes/com/sun/tools/javadoc/SeeTagImpl.java ! src/share/classes/com/sun/tools/javadoc/SerialFieldTagImpl.java ! src/share/classes/com/sun/tools/javadoc/SerializedForm.java ! src/share/classes/com/sun/tools/javadoc/SourcePositionImpl.java ! src/share/classes/com/sun/tools/javadoc/Start.java ! src/share/classes/com/sun/tools/javadoc/TagImpl.java ! src/share/classes/com/sun/tools/javadoc/ThrowsTagImpl.java ! src/share/classes/com/sun/tools/javadoc/TypeMaker.java ! src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java ! src/share/classes/com/sun/tools/javadoc/WildcardTypeImpl.java ! src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties ! src/share/classes/com/sun/tools/javadoc/resources/javadoc_ja.properties ! src/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties ! src/share/classes/com/sun/tools/javah/Gen.java ! src/share/classes/com/sun/tools/javah/InternalError.java ! src/share/classes/com/sun/tools/javah/JNI.java ! src/share/classes/com/sun/tools/javah/JavahFileManager.java ! src/share/classes/com/sun/tools/javah/JavahTask.java ! src/share/classes/com/sun/tools/javah/JavahTool.java ! src/share/classes/com/sun/tools/javah/LLNI.java ! src/share/classes/com/sun/tools/javah/Main.java ! src/share/classes/com/sun/tools/javah/Mangle.java ! src/share/classes/com/sun/tools/javah/NativeHeaderTool.java ! src/share/classes/com/sun/tools/javah/TypeSignature.java ! src/share/classes/com/sun/tools/javah/Util.java ! src/share/classes/com/sun/tools/javah/resources/l10n.properties ! src/share/classes/com/sun/tools/javah/resources/l10n_ja.properties ! src/share/classes/com/sun/tools/javah/resources/l10n_zh_CN.properties ! src/share/classes/com/sun/tools/javap/AnnotationWriter.java ! src/share/classes/com/sun/tools/javap/AttributeWriter.java ! src/share/classes/com/sun/tools/javap/BasicWriter.java ! src/share/classes/com/sun/tools/javap/ClassWriter.java ! src/share/classes/com/sun/tools/javap/CodeWriter.java ! src/share/classes/com/sun/tools/javap/ConstantWriter.java ! src/share/classes/com/sun/tools/javap/Context.java ! src/share/classes/com/sun/tools/javap/DisassemblerTool.java ! src/share/classes/com/sun/tools/javap/InstructionDetailWriter.java ! src/share/classes/com/sun/tools/javap/InternalError.java ! src/share/classes/com/sun/tools/javap/JavapFileManager.java ! src/share/classes/com/sun/tools/javap/JavapTask.java ! src/share/classes/com/sun/tools/javap/LocalVariableTableWriter.java ! src/share/classes/com/sun/tools/javap/LocalVariableTypeTableWriter.java ! src/share/classes/com/sun/tools/javap/Main.java ! src/share/classes/com/sun/tools/javap/Messages.java ! src/share/classes/com/sun/tools/javap/Options.java ! src/share/classes/com/sun/tools/javap/SourceWriter.java ! src/share/classes/com/sun/tools/javap/StackMapWriter.java ! src/share/classes/com/sun/tools/javap/TryBlockWriter.java ! src/share/classes/com/sun/tools/javap/TypeAnnotationWriter.java ! src/share/classes/com/sun/tools/javap/resources/version.properties-template ! src/share/classes/javax/annotation/processing/AbstractProcessor.java ! src/share/classes/javax/annotation/processing/Completion.java ! src/share/classes/javax/annotation/processing/Completions.java ! src/share/classes/javax/annotation/processing/Filer.java ! src/share/classes/javax/annotation/processing/FilerException.java ! src/share/classes/javax/annotation/processing/Messager.java ! src/share/classes/javax/annotation/processing/ProcessingEnvironment.java ! src/share/classes/javax/annotation/processing/Processor.java ! src/share/classes/javax/annotation/processing/RoundEnvironment.java ! src/share/classes/javax/annotation/processing/SupportedAnnotationTypes.java ! src/share/classes/javax/annotation/processing/SupportedOptions.java ! src/share/classes/javax/annotation/processing/SupportedSourceVersion.java ! src/share/classes/javax/annotation/processing/package-info.java ! src/share/classes/javax/lang/model/SourceVersion.java ! src/share/classes/javax/lang/model/UnknownEntityException.java ! src/share/classes/javax/lang/model/element/AnnotationMirror.java ! src/share/classes/javax/lang/model/element/AnnotationValue.java ! src/share/classes/javax/lang/model/element/AnnotationValueVisitor.java ! src/share/classes/javax/lang/model/element/Element.java ! src/share/classes/javax/lang/model/element/ElementKind.java ! src/share/classes/javax/lang/model/element/ElementVisitor.java ! src/share/classes/javax/lang/model/element/ExecutableElement.java ! src/share/classes/javax/lang/model/element/Modifier.java ! src/share/classes/javax/lang/model/element/Name.java ! src/share/classes/javax/lang/model/element/NestingKind.java ! src/share/classes/javax/lang/model/element/PackageElement.java ! src/share/classes/javax/lang/model/element/Parameterizable.java ! src/share/classes/javax/lang/model/element/QualifiedNameable.java ! src/share/classes/javax/lang/model/element/TypeElement.java ! src/share/classes/javax/lang/model/element/TypeParameterElement.java ! src/share/classes/javax/lang/model/element/UnknownAnnotationValueException.java ! src/share/classes/javax/lang/model/element/UnknownElementException.java ! src/share/classes/javax/lang/model/element/VariableElement.java ! src/share/classes/javax/lang/model/element/package-info.java ! src/share/classes/javax/lang/model/overview.html ! src/share/classes/javax/lang/model/package-info.java ! src/share/classes/javax/lang/model/type/ArrayType.java ! src/share/classes/javax/lang/model/type/DeclaredType.java ! src/share/classes/javax/lang/model/type/ErrorType.java ! src/share/classes/javax/lang/model/type/ExecutableType.java ! src/share/classes/javax/lang/model/type/MirroredTypeException.java ! src/share/classes/javax/lang/model/type/MirroredTypesException.java ! src/share/classes/javax/lang/model/type/NoType.java ! src/share/classes/javax/lang/model/type/NullType.java ! src/share/classes/javax/lang/model/type/PrimitiveType.java ! src/share/classes/javax/lang/model/type/ReferenceType.java ! src/share/classes/javax/lang/model/type/TypeKind.java ! src/share/classes/javax/lang/model/type/TypeMirror.java ! src/share/classes/javax/lang/model/type/TypeVariable.java ! src/share/classes/javax/lang/model/type/TypeVisitor.java ! src/share/classes/javax/lang/model/type/UnknownTypeException.java ! src/share/classes/javax/lang/model/type/WildcardType.java ! src/share/classes/javax/lang/model/type/package-info.java ! src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java ! src/share/classes/javax/lang/model/util/AbstractElementVisitor6.java ! src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java ! src/share/classes/javax/lang/model/util/ElementFilter.java ! src/share/classes/javax/lang/model/util/ElementKindVisitor6.java ! src/share/classes/javax/lang/model/util/ElementScanner6.java ! src/share/classes/javax/lang/model/util/Elements.java ! src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java ! src/share/classes/javax/lang/model/util/SimpleElementVisitor6.java ! src/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java ! src/share/classes/javax/lang/model/util/TypeKindVisitor6.java ! src/share/classes/javax/lang/model/util/Types.java ! src/share/classes/javax/lang/model/util/package-info.java ! src/share/classes/javax/tools/Diagnostic.java ! src/share/classes/javax/tools/DiagnosticCollector.java ! src/share/classes/javax/tools/DiagnosticListener.java ! src/share/classes/javax/tools/FileObject.java ! src/share/classes/javax/tools/ForwardingFileObject.java ! src/share/classes/javax/tools/ForwardingJavaFileManager.java ! src/share/classes/javax/tools/ForwardingJavaFileObject.java ! src/share/classes/javax/tools/JavaCompiler.java ! src/share/classes/javax/tools/JavaFileManager.java ! src/share/classes/javax/tools/JavaFileObject.java ! src/share/classes/javax/tools/OptionChecker.java ! src/share/classes/javax/tools/SimpleJavaFileObject.java ! src/share/classes/javax/tools/StandardJavaFileManager.java ! src/share/classes/javax/tools/StandardLocation.java ! src/share/classes/javax/tools/Tool.java ! src/share/classes/javax/tools/ToolProvider.java ! src/share/classes/javax/tools/package-info.java ! src/share/sample/javac/processing/src/CheckNamesProcessor.java ! test/com/sun/javadoc/5093723/DocumentedClass.java ! test/com/sun/javadoc/5093723/T5093723.java ! test/com/sun/javadoc/5093723/UndocumentedClass.java ! test/com/sun/javadoc/AccessAsciiArt/AccessAsciiArt.java ! test/com/sun/javadoc/AccessAsciiArt/p1/C.java ! test/com/sun/javadoc/AccessAsciiArt/p1/I.java ! test/com/sun/javadoc/AccessAsciiArt/p1/SC.java ! test/com/sun/javadoc/AccessAsciiArt/p1/SI.java ! test/com/sun/javadoc/AccessAsciiArt/p1/subpkg/SSC.java ! test/com/sun/javadoc/AccessFrameTitle/AccessFrameTitle.java ! test/com/sun/javadoc/AccessFrameTitle/p1/C1.java ! test/com/sun/javadoc/AccessFrameTitle/p2/C2.java ! test/com/sun/javadoc/AccessH1/AccessH1.java ! test/com/sun/javadoc/AccessH1/p1/C.java ! test/com/sun/javadoc/AccessH1/p2/C2.java ! test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java ! test/com/sun/javadoc/AccessSkipNav/p1/C1.java ! test/com/sun/javadoc/AccessSkipNav/p2/C2.java ! test/com/sun/javadoc/AccessSummary/AccessSummary.java ! test/com/sun/javadoc/AccessSummary/p1/C1.java ! test/com/sun/javadoc/AccessSummary/p2/C2.java ! test/com/sun/javadoc/AuthorDD/AuthorDD.java ! test/com/sun/javadoc/AuthorDD/p1/C1.java ! test/com/sun/javadoc/DocRootSlash/DocRootSlash.java ! test/com/sun/javadoc/DocRootSlash/p1/C1.java ! test/com/sun/javadoc/DocRootSlash/p2/C2.java ! test/com/sun/javadoc/JavascriptWinTitle/JavascriptWinTitle.java ! test/com/sun/javadoc/JavascriptWinTitle/p1/C.java ! test/com/sun/javadoc/JavascriptWinTitle/p2/C2.java ! test/com/sun/javadoc/MetaTag/MetaTag.java ! test/com/sun/javadoc/MetaTag/p1/C1.java ! test/com/sun/javadoc/MetaTag/p2/C2.java ! test/com/sun/javadoc/PackagesHeader/PackagesHeader.java ! test/com/sun/javadoc/PackagesHeader/p1/C1.java ! test/com/sun/javadoc/PackagesHeader/p2/C2.java ! test/com/sun/javadoc/ValidHtml/ValidHtml.java ! test/com/sun/javadoc/ValidHtml/p1/C.java ! test/com/sun/javadoc/ValidHtml/p2/C2.java ! test/com/sun/javadoc/VersionNumber/VersionNumber.java ! test/com/sun/javadoc/VersionNumber/p1/C.java ! test/com/sun/javadoc/WindowTitles/WindowTitles.java ! test/com/sun/javadoc/WindowTitles/p1/C1.java ! test/com/sun/javadoc/WindowTitles/p2/C2.java ! test/com/sun/javadoc/_template/Template.java ! test/com/sun/javadoc/_template/TemplateComplete.java ! test/com/sun/javadoc/constantValues/A.java ! test/com/sun/javadoc/constantValues/TestConstantValues.java ! test/com/sun/javadoc/constantValues/TestConstantValues2.java ! test/com/sun/javadoc/constantValues/TestConstantValuesDriver.java ! test/com/sun/javadoc/dupThrowsTags/TestDupThrowsTags.java ! test/com/sun/javadoc/lib/JavadocTester.java ! test/com/sun/javadoc/testAbsLinkPath/TestAbsLinkPath.java ! test/com/sun/javadoc/testAbsLinkPath/pkg1/C1.java ! test/com/sun/javadoc/testAbsLinkPath/pkg2/C2.java ! test/com/sun/javadoc/testAnnotationTypes/TestAnnotationTypes.java ! test/com/sun/javadoc/testAnnotationTypes/pkg/AnnotationType.java ! test/com/sun/javadoc/testBackSlashInLink/TestBackSlashInLink.java ! test/com/sun/javadoc/testBadPackageFileInJar/TestBadPackageFileInJar.java ! test/com/sun/javadoc/testBadPackageFileInJar/pkg/C.java ! test/com/sun/javadoc/testBadSourceFile/C1.java ! test/com/sun/javadoc/testBadSourceFile/C2.java ! test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java ! test/com/sun/javadoc/testBaseClass/Bar.java ! test/com/sun/javadoc/testBaseClass/BaseClass.java ! test/com/sun/javadoc/testBaseClass/TestBaseClass.java ! test/com/sun/javadoc/testBaseClass/baz/Foo.java ! test/com/sun/javadoc/testBreakIterator/TestBreakIterator.java ! test/com/sun/javadoc/testBreakIterator/pkg/BreakIteratorTest.java ! test/com/sun/javadoc/testCRLineSeparator/TestCRLineSeparator.java ! test/com/sun/javadoc/testCRLineSeparator/pkg/MyClass.java ! test/com/sun/javadoc/testClassCrossReferences/C.java ! test/com/sun/javadoc/testClassCrossReferences/TestClassCrossReferences.java ! test/com/sun/javadoc/testClassTree/TestClassTree.java ! test/com/sun/javadoc/testClassTree/pkg/AnnotationType.java ! test/com/sun/javadoc/testClassTree/pkg/ChildClass.java ! test/com/sun/javadoc/testClassTree/pkg/Coin.java ! test/com/sun/javadoc/testClassTree/pkg/ParentClass.java ! test/com/sun/javadoc/testCmndLineClass/C5.java ! test/com/sun/javadoc/testCmndLineClass/TestCmndLineClass.java ! test/com/sun/javadoc/testCmndLineClass/pkg1/C1.java ! test/com/sun/javadoc/testCmndLineClass/pkg1/C2.java ! test/com/sun/javadoc/testCmndLineClass/pkg2/C3.java ! test/com/sun/javadoc/testCmndLineClass/pkg2/C4.java ! test/com/sun/javadoc/testConstantValuesPage/TestConstantValuesPage.java ! test/com/sun/javadoc/testConstructorIndent/C.java ! test/com/sun/javadoc/testConstructorIndent/TestConstructorIndent.java ! test/com/sun/javadoc/testDeprecatedDocs/TestDeprecatedDocs.java ! test/com/sun/javadoc/testDeprecatedDocs/pkg/DeprecatedClassByAnnotation.java ! test/com/sun/javadoc/testDeprecatedDocs/pkg/TestAnnotationType.java ! test/com/sun/javadoc/testDeprecatedDocs/pkg/TestClass.java ! test/com/sun/javadoc/testDeprecatedDocs/pkg/TestEnum.java ! test/com/sun/javadoc/testDeprecatedDocs/pkg/TestError.java ! test/com/sun/javadoc/testDeprecatedDocs/pkg/TestException.java ! test/com/sun/javadoc/testDeprecatedDocs/pkg/TestInterface.java ! test/com/sun/javadoc/testDocErrorReporter/TestDocErrorReporter.java ! test/com/sun/javadoc/testDocFileDir/TestDocFileDir.java ! test/com/sun/javadoc/testDocFileDir/pkg/C.java ! test/com/sun/javadoc/testDocRootInlineTag/TestDocRootInlineTag.java ! test/com/sun/javadoc/testDocRootInlineTag/TestDocRootTag.java ! test/com/sun/javadoc/testDocRootInlineTag/pkg/C.java ! test/com/sun/javadoc/testDupParamWarn/TestDupParamWarn.java ! test/com/sun/javadoc/testDupParamWarn/pkg/Bar.java ! test/com/sun/javadoc/testDupParamWarn/pkg/Foo.java ! test/com/sun/javadoc/testEmptyClass/TestEmptyClass.java ! test/com/sun/javadoc/testEmptyClass/src/Empty.java ! test/com/sun/javadoc/testEnclosingClass/TestEnclosingClass.java ! test/com/sun/javadoc/testEnclosingClass/pkg/MyClass.java ! test/com/sun/javadoc/testEncoding/EncodeTest.java ! test/com/sun/javadoc/testEncoding/TestEncoding.java ! test/com/sun/javadoc/testExternalOverridenMethod/TestExternalOverridenMethod.java ! test/com/sun/javadoc/testExternalOverridenMethod/pkg/XReader.java ! test/com/sun/javadoc/testGroupOption/TestGroupOption.java ! test/com/sun/javadoc/testGroupOption/pkg1/C.java ! test/com/sun/javadoc/testGroupOption/pkg2/C.java ! test/com/sun/javadoc/testGroupOption/pkg3/C.java ! test/com/sun/javadoc/testHeadings/TestHeadings.java ! test/com/sun/javadoc/testHeadings/pkg1/C1.java ! test/com/sun/javadoc/testHeadings/pkg2/C2.java ! test/com/sun/javadoc/testHelpOption/TestHelpOption.java ! test/com/sun/javadoc/testHiddenMembers/TestHiddenMembers.java ! test/com/sun/javadoc/testHiddenMembers/pkg/BaseClass.java ! test/com/sun/javadoc/testHiddenMembers/pkg/SubClass.java ! test/com/sun/javadoc/testHref/TestHref.java ! test/com/sun/javadoc/testHref/pkg/C1.java ! test/com/sun/javadoc/testHref/pkg/C2.java ! test/com/sun/javadoc/testHref/pkg/C3.java ! test/com/sun/javadoc/testHref/pkg/C4.java ! test/com/sun/javadoc/testHrefInDocComment/TestHrefInDocComment.java ! test/com/sun/javadoc/testHrefInDocComment/pkg/I1.java ! test/com/sun/javadoc/testHrefInDocComment/pkg/I2.java ! test/com/sun/javadoc/testHtmlComments/C.java ! test/com/sun/javadoc/testHtmlComments/TestHtmlComments.java ! test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java ! test/com/sun/javadoc/testHtmlDefinitionListTag/pkg1/C1.java ! test/com/sun/javadoc/testHtmlDefinitionListTag/pkg1/C2.java ! test/com/sun/javadoc/testHtmlDefinitionListTag/pkg1/C3.java ! test/com/sun/javadoc/testHtmlDefinitionListTag/pkg1/C4.java ! test/com/sun/javadoc/testHtmlDefinitionListTag/pkg1/C5.java ! test/com/sun/javadoc/testHtmlDefinitionListTag/pkg1/package-info.java ! test/com/sun/javadoc/testHtmlStrongTag/TestHtmlStrongTag.java ! test/com/sun/javadoc/testHtmlStrongTag/pkg1/C1.java ! test/com/sun/javadoc/testHtmlStrongTag/pkg2/C2.java ! test/com/sun/javadoc/testHtmlTableTags/TestHtmlTableTags.java ! test/com/sun/javadoc/testHtmlTableTags/pkg1/C1.java ! test/com/sun/javadoc/testHtmlTableTags/pkg1/I1.java ! test/com/sun/javadoc/testHtmlTableTags/pkg1/package-info.java ! test/com/sun/javadoc/testHtmlTableTags/pkg2/C2.java ! test/com/sun/javadoc/testHtmlTableTags/pkg2/C3.java ! test/com/sun/javadoc/testHtmlTableTags/pkg2/C4.java ! test/com/sun/javadoc/testHtmlTableTags/pkg2/package-info.java ! test/com/sun/javadoc/testHtmlTag/TestHtmlTag.java ! test/com/sun/javadoc/testHtmlTag/pkg1/C1.java ! test/com/sun/javadoc/testHtmlTag/pkg2/C2.java ! test/com/sun/javadoc/testIndex/NoPackage.java ! test/com/sun/javadoc/testIndex/TestIndex.java ! test/com/sun/javadoc/testIndex/pkg/AnnotationType.java ! test/com/sun/javadoc/testIndex/pkg/C.java ! test/com/sun/javadoc/testIndex/pkg/Coin.java ! test/com/sun/javadoc/testIndex/pkg/Interface.java ! test/com/sun/javadoc/testInlineLinkLabel/TestInlineLinkLabel.java ! test/com/sun/javadoc/testInlineLinkLabel/pkg/C1.java ! test/com/sun/javadoc/testInlineLinkLabel/pkg/C2.java ! test/com/sun/javadoc/testInterface/TestInterface.java ! test/com/sun/javadoc/testInterface/pkg/Child.java ! test/com/sun/javadoc/testInterface/pkg/Interface.java ! test/com/sun/javadoc/testInterface/pkg/Parent.java ! test/com/sun/javadoc/testJavascript/TestJavascript.java ! test/com/sun/javadoc/testJavascript/pkg/C.java ! test/com/sun/javadoc/testLeadingSpaces/LeadingSpaces.java ! test/com/sun/javadoc/testLegacyTaglet/C.java ! test/com/sun/javadoc/testLegacyTaglet/TestLegacyTaglet.java ! test/com/sun/javadoc/testLegacyTaglet/ToDoTaglet.java ! test/com/sun/javadoc/testLegacyTaglet/UnderlineTaglet.java ! test/com/sun/javadoc/testLinkOption/TestBadLinkOption.java ! test/com/sun/javadoc/testLinkOption/TestLinkOption.java ! test/com/sun/javadoc/testLinkOption/TestNewLineInLink.java ! test/com/sun/javadoc/testLinkOption/java/lang/StringBuilderChild.java ! test/com/sun/javadoc/testLinkOption/pkg/C.java ! test/com/sun/javadoc/testLinkOption/pkg2/C2.java ! test/com/sun/javadoc/testLinkOption/testNewLineInLink/C.java ! test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java ! test/com/sun/javadoc/testLinkTaglet/checkPkg/A.java ! test/com/sun/javadoc/testLinkTaglet/checkPkg/B.java ! test/com/sun/javadoc/testLinkTaglet/pkg/C.java ! test/com/sun/javadoc/testLinkToSerialForm/TestLinkToSerialForm.java ! test/com/sun/javadoc/testLinkToSerialForm/pkg/C.java ! test/com/sun/javadoc/testMemberInheritence/TestMemberInheritence.java ! test/com/sun/javadoc/testMemberInheritence/diamond/A.java ! test/com/sun/javadoc/testMemberInheritence/diamond/B.java ! test/com/sun/javadoc/testMemberInheritence/diamond/C.java ! test/com/sun/javadoc/testMemberInheritence/diamond/X.java ! test/com/sun/javadoc/testMemberInheritence/diamond/Z.java ! test/com/sun/javadoc/testMemberInheritence/inheritDist/A.java ! test/com/sun/javadoc/testMemberInheritence/inheritDist/B.java ! test/com/sun/javadoc/testMemberInheritence/inheritDist/C.java ! test/com/sun/javadoc/testMemberInheritence/pkg/BaseClass.java ! test/com/sun/javadoc/testMemberInheritence/pkg/BaseInterface.java ! test/com/sun/javadoc/testMemberInheritence/pkg/SubClass.java ! test/com/sun/javadoc/testMemberSummary/TestMemberSummary.java ! test/com/sun/javadoc/testMemberSummary/pkg/PrivateParent.java ! test/com/sun/javadoc/testMemberSummary/pkg/PublicChild.java ! test/com/sun/javadoc/testMemberSummary/pkg2/A.java ! test/com/sun/javadoc/testModifier/Interface.java ! test/com/sun/javadoc/testModifier/ModifierAbstract.java ! test/com/sun/javadoc/testModifier/Test.java ! test/com/sun/javadoc/testModifier/TestModifier.java ! test/com/sun/javadoc/testNavagation/TestNavagation.java ! test/com/sun/javadoc/testNavagation/pkg/A.java ! test/com/sun/javadoc/testNavagation/pkg/C.java ! test/com/sun/javadoc/testNavagation/pkg/E.java ! test/com/sun/javadoc/testNavagation/pkg/I.java ! test/com/sun/javadoc/testNestedInlineTag/TestNestedInlineTag.java ! test/com/sun/javadoc/testNestedInlineTag/testtaglets/BoldTaglet.java ! test/com/sun/javadoc/testNestedInlineTag/testtaglets/GreenTaglet.java ! test/com/sun/javadoc/testNestedInlineTag/testtaglets/UnderlineTaglet.java ! test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg/AnnotationType.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg/AnnotationTypeUndocumented.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg/AnnotationTypeUsage.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg/Coin.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg/MultiTypeParameters.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg/SubInterface.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg/SuperInterface.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg/TypeParameterSubClass.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg/TypeParameterSuperClass.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg/TypeParameters.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg/VarArgs.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg/Wildcards.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg/package-info.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg1/A.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg1/B.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg2/ClassUseTest1.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg2/ClassUseTest2.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg2/ClassUseTest3.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg2/Foo.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg2/Foo2.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg2/Foo3.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg2/Foo4.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg2/ParamTest.java ! test/com/sun/javadoc/testNewLanguageFeatures/pkg2/ParamTest2.java ! test/com/sun/javadoc/testNoPackagesFile/C.java ! test/com/sun/javadoc/testNoPackagesFile/TestNoPackagesFile.java ! test/com/sun/javadoc/testNotifications/TestNotifications.java ! test/com/sun/javadoc/testNotifications/pkg/C.java ! test/com/sun/javadoc/testOverridenMethods/TestMultiInheritence.java ! test/com/sun/javadoc/testOverridenMethods/TestOverridenMethodDocCopy.java ! test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethods.java ! test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethodsWithPackageFlag.java ! test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethodsWithPrivateFlag.java ! test/com/sun/javadoc/testOverridenMethods/pkg1/BaseClass.java ! test/com/sun/javadoc/testOverridenMethods/pkg1/SubClass.java ! test/com/sun/javadoc/testOverridenMethods/pkg2/SubClass.java ! test/com/sun/javadoc/testOverridenMethods/pkg3/I0.java ! test/com/sun/javadoc/testOverridenMethods/pkg3/I1.java ! test/com/sun/javadoc/testOverridenMethods/pkg3/I2.java ! test/com/sun/javadoc/testOverridenMethods/pkg3/I3.java ! test/com/sun/javadoc/testOverridenMethods/pkg3/I4.java ! test/com/sun/javadoc/testPackagePage/TestPackagePage.java ! test/com/sun/javadoc/testPackagePage/com/pkg/C.java ! test/com/sun/javadoc/testPackagePage/pkg2/C.java ! test/com/sun/javadoc/testParamTaglet/TestParamTaglet.java ! test/com/sun/javadoc/testParamTaglet/pkg/C.java ! test/com/sun/javadoc/testParamTaglet/pkg/Parent.java ! test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java ! test/com/sun/javadoc/testPrivateClasses/pkg/PrivateInterface.java ! test/com/sun/javadoc/testPrivateClasses/pkg/PrivateParent.java ! test/com/sun/javadoc/testPrivateClasses/pkg/PublicChild.java ! test/com/sun/javadoc/testPrivateClasses/pkg/PublicInterface.java ! test/com/sun/javadoc/testPrivateClasses/pkg2/C.java ! test/com/sun/javadoc/testPrivateClasses/pkg2/I.java ! test/com/sun/javadoc/testRecurseSubPackages/TestRecurseSubPackages.java ! test/com/sun/javadoc/testRecurseSubPackages/pkg1/C1.java ! test/com/sun/javadoc/testRecurseSubPackages/pkg1/C2.java ! test/com/sun/javadoc/testRecurseSubPackages/pkg1/pkg2/C3.java ! test/com/sun/javadoc/testRecurseSubPackages/pkg1/pkg2/C4.java ! test/com/sun/javadoc/testRecurseSubPackages/pkg1/pkg2/packageToExclude/DummyClass.java ! test/com/sun/javadoc/testRecurseSubPackages/pkg1/pkg2/pkg3/C5.java ! test/com/sun/javadoc/testRecurseSubPackages/pkg1/pkg2/pkg3/C6.java ! test/com/sun/javadoc/testRelativeLinks/TestRelativeLinks.java ! test/com/sun/javadoc/testRelativeLinks/pkg/C.java ! test/com/sun/javadoc/testRelativeLinks/pkg2/Foo.java ! test/com/sun/javadoc/testReturnTag/TestReturnTag.java ! test/com/sun/javadoc/testSerialVersionUID/C.java ! test/com/sun/javadoc/testSerialVersionUID/TestSerialVersionUID.java ! test/com/sun/javadoc/testSerializedForm/TestSerializedForm.java ! test/com/sun/javadoc/testSerializedFormDeprecationInfo/TestSerializedFormDeprecationInfo.java ! test/com/sun/javadoc/testSerializedFormDeprecationInfo/pkg1/C1.java ! test/com/sun/javadoc/testSerializedFormDeprecationInfo/pkg1/C2.java ! test/com/sun/javadoc/testSerializedFormDeprecationInfo/pkg1/C3.java ! test/com/sun/javadoc/testSimpleTag/C.java ! test/com/sun/javadoc/testSimpleTag/TestSimpleTag.java ! test/com/sun/javadoc/testSimpleTagExclude/DummyClass.java ! test/com/sun/javadoc/testSimpleTagExclude/TestSimpleTagExclude.java ! test/com/sun/javadoc/testSourceTab/DoubleTab/C.java ! test/com/sun/javadoc/testSourceTab/SingleTab/C.java ! test/com/sun/javadoc/testSourceTab/TestSourceTab.java ! test/com/sun/javadoc/testStylesheet/TestStylesheet.java ! test/com/sun/javadoc/testStylesheet/pkg/A.java ! test/com/sun/javadoc/testSummaryHeading/C.java ! test/com/sun/javadoc/testSummaryHeading/TestSummaryHeading.java ! test/com/sun/javadoc/testSuperclassInSerialForm/TestSuperClassInSerialForm.java ! test/com/sun/javadoc/testSuperclassInSerialForm/pkg/SubClass.java ! test/com/sun/javadoc/testSuperclassInSerialForm/pkg/SuperClass.java ! test/com/sun/javadoc/testSupplementary/TestSupplementary.java ! test/com/sun/javadoc/testTagHolderMethod/TestTagHolderMethod.java ! test/com/sun/javadoc/testTagHolderMethod/pkg/C.java ! test/com/sun/javadoc/testTagInheritence/TestTagInheritence.java ! test/com/sun/javadoc/testTagInheritence/firstSentence/A.java ! test/com/sun/javadoc/testTagInheritence/firstSentence/B.java ! test/com/sun/javadoc/testTagInheritence/firstSentence2/A.java ! test/com/sun/javadoc/testTagInheritence/firstSentence2/B.java ! test/com/sun/javadoc/testTagInheritence/firstSentence2/C.java ! test/com/sun/javadoc/testTagInheritence/pkg/TestAbstractClass.java ! test/com/sun/javadoc/testTagInheritence/pkg/TestInterface.java ! test/com/sun/javadoc/testTagInheritence/pkg/TestInterfaceForAbstractClass.java ! test/com/sun/javadoc/testTagInheritence/pkg/TestSuperSuperClass.java ! test/com/sun/javadoc/testTagInheritence/pkg/TestSuperSuperInterface.java ! test/com/sun/javadoc/testTagInheritence/pkg/TestTagInheritence.java ! test/com/sun/javadoc/testTagMisuse/TestTagMisuse.java ! test/com/sun/javadoc/testTaglets/C.java ! test/com/sun/javadoc/testTaglets/Child.java ! test/com/sun/javadoc/testTaglets/Parent.java ! test/com/sun/javadoc/testTaglets/TestTaglets.java ! test/com/sun/javadoc/testTaglets/taglets/Foo.java ! test/com/sun/javadoc/testThrowsHead/C.java ! test/com/sun/javadoc/testThrowsHead/TestThrowsHead.java ! test/com/sun/javadoc/testThrowsInheritence/C.java ! test/com/sun/javadoc/testThrowsInheritence/Foo.java ! test/com/sun/javadoc/testThrowsInheritence/I.java ! test/com/sun/javadoc/testThrowsInheritence/Iface.java ! test/com/sun/javadoc/testThrowsInheritence/TestThrowsTagInheritence.java ! test/com/sun/javadoc/testThrowsTag/TestThrowsTag.java ! test/com/sun/javadoc/testThrowsTag/pkg/C.java ! test/com/sun/javadoc/testThrowsTag/pkg/P.java ! test/com/sun/javadoc/testThrowsTag/pkg/T1.java ! test/com/sun/javadoc/testThrowsTag/pkg/T2.java ! test/com/sun/javadoc/testThrowsTag/pkg/T3.java ! test/com/sun/javadoc/testThrowsTag/pkg/T4.java ! test/com/sun/javadoc/testThrowsTag/pkg/T5.java ! test/com/sun/javadoc/testThrowsTag/pkg/T6.java ! test/com/sun/javadoc/testThrowsTag/pkg/T7.java ! test/com/sun/javadoc/testThrowsTag/pkg/T8.java ! test/com/sun/javadoc/testTitleInHref/TestTitleInHref.java ! test/com/sun/javadoc/testTitleInHref/pkg/Class.java ! test/com/sun/javadoc/testTitleInHref/pkg/Interface.java ! test/com/sun/javadoc/testTitleInHref/pkg/Links.java ! test/com/sun/javadoc/testTopOption/TestTopOption.java ! test/com/sun/javadoc/testTopOption/pkg/AnnotationType.java ! test/com/sun/javadoc/testTopOption/pkg/Cl.java ! test/com/sun/javadoc/testTypeParams/TestTypeParameters.java ! test/com/sun/javadoc/testTypeParams/pkg/C.java ! test/com/sun/javadoc/testTypeParams/pkg/Parent.java ! test/com/sun/javadoc/testUnnamedPackage/BadSource.java ! test/com/sun/javadoc/testUnnamedPackage/C.java ! test/com/sun/javadoc/testUnnamedPackage/TestUnnamedPackage.java ! test/com/sun/javadoc/testUseOption/TestUseOption.java ! test/com/sun/javadoc/testUseOption/pkg1/C1.java ! test/com/sun/javadoc/testUseOption/pkg1/C2.java ! test/com/sun/javadoc/testUseOption/pkg1/C4.java ! test/com/sun/javadoc/testUseOption/pkg1/C5.java ! test/com/sun/javadoc/testUseOption/pkg1/C6.java ! test/com/sun/javadoc/testUseOption/pkg1/C7.java ! test/com/sun/javadoc/testUseOption/pkg1/C8.java ! test/com/sun/javadoc/testUseOption/pkg1/UsedClass.java ! test/com/sun/javadoc/testUseOption/pkg2/C3.java ! test/com/sun/javadoc/testValueTag/TestValueTag.java ! test/com/sun/javadoc/testValueTag/pkg1/Class1.java ! test/com/sun/javadoc/testValueTag/pkg1/Class2.java ! test/com/sun/javadoc/testValueTag/pkg1/CustomTagUsage.java ! test/com/sun/javadoc/testValueTag/pkg2/Class3.java ! test/com/sun/javadoc/testWarnBadParamNames/C.java ! test/com/sun/javadoc/testWarnBadParamNames/TestWarnBadParamNames.java ! test/com/sun/javadoc/testWarnings/TestWarnings.java ! test/jprt.config ! test/tools/apt/Basics/Aggregate.java ! test/tools/apt/Basics/ClassAnnotations.java ! test/tools/apt/Basics/FreshnessApf.java ! test/tools/apt/Basics/GenClass.java ! test/tools/apt/Basics/Indirect.java ! test/tools/apt/Basics/Lacuna.java ! test/tools/apt/Basics/MethodAnnotations.java ! test/tools/apt/Basics/Milk.java ! test/tools/apt/Basics/MisMatch.java ! test/tools/apt/Basics/Misc.java ! test/tools/apt/Basics/MyMarker.java ! test/tools/apt/Basics/MySimple.java ! test/tools/apt/Basics/NestedClassAnnotations.java ! test/tools/apt/Basics/NullAPF.java ! test/tools/apt/Basics/ParameterAnnotations.java ! test/tools/apt/Basics/StaticFieldAnnotations.java ! test/tools/apt/Basics/StaticMethodAnnotations.java ! test/tools/apt/Basics/TestGetPackageApf.java ! test/tools/apt/Basics/TestGetTypeDeclarationApf.java ! test/tools/apt/Basics/annot/AnnotMarker.java ! test/tools/apt/Basics/annot/AnnotShangri_la.java ! test/tools/apt/Basics/annot/AnnotSimple.java ! test/tools/apt/Basics/annot/annot2/AnnotMarker2.java ! test/tools/apt/Basics/annot/annot2/AnnotSimple2.java ! test/tools/apt/Basics/apt.sh ! test/tools/apt/Basics/foo/bar/Baz.java ! test/tools/apt/Basics/foo/bar/Quux.java ! test/tools/apt/Basics/p1/p2.java ! test/tools/apt/Basics/p1/p2/C1.java ! test/tools/apt/Basics/print.sh ! test/tools/apt/Compile/ClassDeclApf.java ! test/tools/apt/Compile/ClassDeclApf2.java ! test/tools/apt/Compile/Dummy1.java ! test/tools/apt/Compile/ErrorAPF.java ! test/tools/apt/Compile/Round1Apf.java ! test/tools/apt/Compile/Round2Apf.java ! test/tools/apt/Compile/Round3Apf.java ! test/tools/apt/Compile/Round4Apf.java ! test/tools/apt/Compile/Rounds.java ! test/tools/apt/Compile/StaticApf.java ! test/tools/apt/Compile/WarnAPF.java ! test/tools/apt/Compile/WrappedStaticApf.java ! test/tools/apt/Compile/compile.sh ! test/tools/apt/Compile/src/AhOneClass.java ! test/tools/apt/Compile/src/AndAhTwoClass.java ! test/tools/apt/Compile/src/Round1Class.java ! test/tools/apt/Discovery/Dee.java ! test/tools/apt/Discovery/Dum.java ! test/tools/apt/Discovery/Empty.java ! test/tools/apt/Discovery/PhantomTouch.java ! test/tools/apt/Discovery/PhantomUpdate.java ! test/tools/apt/Discovery/Touch.java ! test/tools/apt/Discovery/discovery.sh ! test/tools/apt/Misc/Marked.java ! test/tools/apt/Misc/Marker.java ! test/tools/apt/Misc/Misc.java ! test/tools/apt/Misc/misc.sh ! test/tools/apt/Options/Marked.java ! test/tools/apt/Options/Marker.java ! test/tools/apt/Options/OptionChecker.java ! test/tools/apt/Options/options.sh ! test/tools/apt/Scanners/Counter.java ! test/tools/apt/Scanners/MemberOrderApf.java ! test/tools/apt/Scanners/Order.java ! test/tools/apt/Scanners/Scanner.java ! test/tools/apt/Scanners/TestEnum.java ! test/tools/apt/Scanners/VisitOrder.java ! test/tools/apt/Scanners/scanner.sh ! test/tools/apt/lib/Ignore.java ! test/tools/apt/lib/Test.java ! test/tools/apt/lib/TestProcessor.java ! test/tools/apt/lib/TestProcessorFactory.java ! test/tools/apt/lib/Tester.java ! test/tools/apt/mirror/declaration/AnnoMirror.java ! test/tools/apt/mirror/declaration/AnnoTypeDecl.java ! test/tools/apt/mirror/declaration/AnnoTypeElemDecl.java ! test/tools/apt/mirror/declaration/AnnoVal.java ! test/tools/apt/mirror/declaration/ClassDecl.java ! test/tools/apt/mirror/declaration/ConstExpr.java ! test/tools/apt/mirror/declaration/ConstructorDecl.java ! test/tools/apt/mirror/declaration/EnumDecl.java ! test/tools/apt/mirror/declaration/FieldDecl.java ! test/tools/apt/mirror/declaration/GetAnno.java ! test/tools/apt/mirror/declaration/InterfaceDecl.java ! test/tools/apt/mirror/declaration/MethodDecl.java ! test/tools/apt/mirror/declaration/PackageDecl.java ! test/tools/apt/mirror/declaration/ParameterDecl.java ! test/tools/apt/mirror/declaration/pkg1/AClass.java ! test/tools/apt/mirror/declaration/pkg1/AnAnnoType.java ! test/tools/apt/mirror/declaration/pkg1/AnEnum.java ! test/tools/apt/mirror/declaration/pkg1/AnInterface.java ! test/tools/apt/mirror/declaration/pkg1/package-info.java ! test/tools/apt/mirror/declaration/pkg1/pkg2/AnInterface.java ! test/tools/apt/mirror/declaration/pkg1/pkg2/package.html ! test/tools/apt/mirror/type/AnnoTyp.java ! test/tools/apt/mirror/type/ArrayTyp.java ! test/tools/apt/mirror/type/ClassTyp.java ! test/tools/apt/mirror/type/EnumTyp.java ! test/tools/apt/mirror/type/InterfaceTyp.java ! test/tools/apt/mirror/type/PrimitiveTyp.java ! test/tools/apt/mirror/type/TypeVar.java ! test/tools/apt/mirror/type/WildcardTyp.java ! test/tools/apt/mirror/util/Overrides.java ! test/tools/apt/mirror/util/TypeCreation.java ! test/tools/apt/verifyVariables.sh ! test/tools/javac/4241573/T4241573.java ! test/tools/javac/4846262/Test.sh ! test/tools/javac/4980495/static/p1/A1.java ! test/tools/javac/4980495/static/p2/A2.java ! test/tools/javac/4980495/std/p1/A1.java ! test/tools/javac/4980495/std/p2/A2.java ! test/tools/javac/5005368.java ! test/tools/javac/5045412/Bar.java ! test/tools/javac/5045412/Foo.java ! test/tools/javac/6199662/Tree.java ! test/tools/javac/6199662/TreeInfo.java ! test/tools/javac/6199662/TreeScanner.java ! test/tools/javac/6257443/T6257443.java ! test/tools/javac/6257443/package-info.java ! test/tools/javac/6302184/T6302184.java ! test/tools/javac/6302184/T6302184.sh ! test/tools/javac/6304921/TestLog.java ! test/tools/javac/6330997/T1.java ! test/tools/javac/6330997/T2.java ! test/tools/javac/6330997/T6330997.java ! test/tools/javac/6341866/A.java ! test/tools/javac/6341866/Anno.java ! test/tools/javac/6341866/B.java ! test/tools/javac/6341866/T6341866.java ! test/tools/javac/6342411/T6342411.java ! test/tools/javac/6342411/a/Base.java ! test/tools/javac/6342411/a/Pub.java ! test/tools/javac/6390045/T6390045a.java ! test/tools/javac/6390045/T6390045b.java ! test/tools/javac/6394683/A.java ! test/tools/javac/6394683/B.java ! test/tools/javac/6394683/T6394683.java ! test/tools/javac/6400383/T6400383.java ! test/tools/javac/6400872/A.java ! test/tools/javac/6400872/B.java ! test/tools/javac/6400872/C.java ! test/tools/javac/6400872/T6400872.java ! test/tools/javac/6402516/A.java ! test/tools/javac/6402516/CheckClass.java ! test/tools/javac/6402516/CheckIsAccessible.java ! test/tools/javac/6402516/CheckLocalElements.java ! test/tools/javac/6402516/CheckMethod.java ! test/tools/javac/6402516/Checker.java ! test/tools/javac/6402516/TestClass.java ! test/tools/javac/6402516/TestIsAccessible.java ! test/tools/javac/6402516/TestLocalElements.java ! test/tools/javac/6402516/TestMethod.java ! test/tools/javac/6403424/A.java ! test/tools/javac/6403424/B.java ! test/tools/javac/6403424/T6403424.java ! test/tools/javac/6410653/T6410653.java ! test/tools/javac/6440583/A.java ! test/tools/javac/6440583/T6440583.java ! test/tools/javac/6457284/T6457284.java ! test/tools/javac/6464451/BigFinally.java ! test/tools/javac/6464451/DeepNestedFinally.java ! test/tools/javac/6464451/ManyExitsInTry.java ! test/tools/javac/6508981/TestInferBinaryName.java ! test/tools/javac/6508981/p/A.java ! test/tools/javac/6521805/T6521805b.java ! test/tools/javac/6521805/T6521805c.java ! test/tools/javac/6521805/T6521805e.java ! test/tools/javac/6627362/T6627362.java ! test/tools/javac/6627362/x/E.java ! test/tools/javac/6627362/x/Object.java ! test/tools/javac/6668794/badClass/A.java ! test/tools/javac/6668794/badClass/Test.java ! test/tools/javac/6668794/badSource/p/A.java ! test/tools/javac/6734819/T6734819a.java ! test/tools/javac/6734819/T6734819b.java ! test/tools/javac/6835430/A.java ! test/tools/javac/6835430/T6835430.java ! test/tools/javac/6889255/T6889255.java ! test/tools/javac/6902720/E1.java ! test/tools/javac/6902720/E2.java ! test/tools/javac/6902720/Test.java ! test/tools/javac/AbstractOverride.java ! test/tools/javac/AccessMethods/AccessMethodsLHS.java ! test/tools/javac/AccessMethods/BitwiseAssignment.java ! test/tools/javac/AccessMethods/ChainedAssignment.java ! test/tools/javac/AccessMethods/ConstructorAccess.java ! test/tools/javac/AccessMethods/InternalHandshake.java ! test/tools/javac/AccessMethods/LateAddition.java ! test/tools/javac/AccessMethods/UplevelPrivateConstants.java ! test/tools/javac/AddReferenceThis.java ! test/tools/javac/Ambig3.java ! test/tools/javac/AnonClsInIntf.java ! test/tools/javac/AnonInnerException_1.java ! test/tools/javac/AnonInnerException_2.java ! test/tools/javac/AnonInnerException_3.java ! test/tools/javac/AnonStaticMember_1.java ! test/tools/javac/AnonStaticMember_2.java ! test/tools/javac/AnonStaticMember_3.java ! test/tools/javac/AnonymousConstructorExceptions.java ! test/tools/javac/AnonymousNull.java ! test/tools/javac/AnonymousProtect/AnonymousProtect.java ! test/tools/javac/AnonymousProtect/P1/priv.java ! test/tools/javac/AnonymousProtect/P1/pub.java ! test/tools/javac/AnonymousProtect/P1/pubExposePriv.java ! test/tools/javac/AnonymousProtect/P2/usePub.java ! test/tools/javac/AnonymousType.java ! test/tools/javac/ArrayCast.java ! test/tools/javac/ArrayCloneCodeGen.java ! test/tools/javac/BadAnnotation.java ! test/tools/javac/BadBreak.java ! test/tools/javac/BadCovar.java ! test/tools/javac/BadHexConstant.java ! test/tools/javac/BadOptimization/DeadCode1.java ! test/tools/javac/BadOptimization/DeadCode2.java ! test/tools/javac/BadOptimization/DeadCode3.java ! test/tools/javac/BadOptimization/DeadCode4.java ! test/tools/javac/BadOptimization/DeadCode5.java ! test/tools/javac/BadOptimization/DeadCode6.java ! test/tools/javac/BadOptimization/Switch1.java ! test/tools/javac/BadOptimization/Switch2.java ! test/tools/javac/BoolArray.java ! test/tools/javac/BoundClassError.java ! test/tools/javac/BreakAcrossClass.java ! test/tools/javac/Capture.java ! test/tools/javac/CaptureInSubtype.java ! test/tools/javac/CascadedInnerNewInstance.java ! test/tools/javac/CastInterface2Array.java ! test/tools/javac/ClassCycle/ClassCycle1a.java ! test/tools/javac/ClassCycle/ClassCycle1b.java ! test/tools/javac/ClassCycle/ClassCycle2a.java ! test/tools/javac/ClassCycle/ClassCycle2b.java ! test/tools/javac/ClassCycle/ClassCycle3a.java ! test/tools/javac/ClassCycle/ClassCycle3b.java ! test/tools/javac/ClassFileModifiers/ClassModifiers.java ! test/tools/javac/ClassFileModifiers/MemberModifiers.java ! test/tools/javac/ClassIsAbstract.java ! test/tools/javac/ClassLit.java ! test/tools/javac/ClassLiterals/ClassLiteralHelperContext.java ! test/tools/javac/ClassLiterals/InitializeOuter.java ! test/tools/javac/ClassLiterals/InitializeTarget.java ! test/tools/javac/ClassLiterals/InnerClassLiterals.java ! test/tools/javac/ClassLiterals/LiteralInterfaceImpl.java ! test/tools/javac/ClassLiterals/LiteralInterface_1.java ! test/tools/javac/ClassLiterals/LiteralInterface_2.java ! test/tools/javac/ClassLiterals/LiteralInterface_3.java ! test/tools/javac/ClassLiterals/evalinit/ClassLiteralEvalInit.java ! test/tools/javac/ClassLiterals/evalinit/java/lang/Integer.java ! test/tools/javac/ClassLiterals/p1/C.java ! test/tools/javac/ClassLiterals/p1/SuperClass.java ! test/tools/javac/ClassModifiers/InterfaceAndInnerClsCtor.java ! test/tools/javac/ClassPathTest/ClassPathTest.sh ! test/tools/javac/ClassPathTest/ClassPathTest1.java ! test/tools/javac/ClassPathTest/ClassPathTest2.java ! test/tools/javac/ClassPathTest/ClassPathTest3.java ! test/tools/javac/ClassPathTest/bar/pkg/ClassPathTestAux2.java ! test/tools/javac/ClassPathTest/foo/pkg/ClassPathTestAux1.java ! test/tools/javac/ClassPathTest/pkg/ClassPathTestAux3.java ! test/tools/javac/ClassToTypeParm.java ! test/tools/javac/CloneableProblem.java ! test/tools/javac/Closure1.java ! test/tools/javac/Closure2.java ! test/tools/javac/Closure3.java ! test/tools/javac/Closure4.java ! test/tools/javac/Closure5.java ! test/tools/javac/Closure6.java ! test/tools/javac/CompoundBox.java ! test/tools/javac/ConditionalArgTypes_1.java ! test/tools/javac/ConditionalArgTypes_2.java ! test/tools/javac/ConditionalClass.java ! test/tools/javac/ConditionalInline.java ! test/tools/javac/ConditionalWithVoid.java ! test/tools/javac/ConstBoolAppend.java ! test/tools/javac/ConstCharAppend.java ! test/tools/javac/ConstantValues/ConstValInit.java ! test/tools/javac/ConstantValues/ConstValInlining.java ! test/tools/javac/ConstantValues/test_ff1.java ! test/tools/javac/ConstantValues/test_ff2.java ! test/tools/javac/CyclicInheritance2.java ! test/tools/javac/CyclicInheritance4.java ! test/tools/javac/CyclicInheritance6/Main.java ! test/tools/javac/CyclicInheritance6/p1/A.java ! test/tools/javac/CyclicInheritance6/p1/B.java ! test/tools/javac/CyclicInheritance6/p1/C.java ! test/tools/javac/CyclicScoping/CyclicScoping_1.java ! test/tools/javac/CyclicScoping/CyclicScoping_2.java ! test/tools/javac/DeadInnerClass.java ! test/tools/javac/DeclarationStatementInline.java ! test/tools/javac/DeepStringConcat.java ! test/tools/javac/DefiniteAssignment/ConstantInfiniteWhile.java ! test/tools/javac/DefiniteAssignment/DABlock.java ! test/tools/javac/DefiniteAssignment/DALoop1.java ! test/tools/javac/DefiniteAssignment/DASwitch.java ! test/tools/javac/DefiniteAssignment/DUAssert.java ! test/tools/javac/DefiniteAssignment/DUBeforeDefined1.java ! test/tools/javac/DefiniteAssignment/DUBeforeDefined2.java ! test/tools/javac/DefiniteAssignment/DUParam1.java ! test/tools/javac/DefiniteAssignment/DUParam2.java ! test/tools/javac/DefiniteAssignment/DUSwitch.java ! test/tools/javac/DefiniteAssignment/DUSwitch2.java ! test/tools/javac/DefiniteAssignment/DUTry.java ! test/tools/javac/DefiniteAssignment/DefAssignAfterIf_1.java ! test/tools/javac/DefiniteAssignment/DefAssignAfterIf_2.java ! test/tools/javac/DefiniteAssignment/DefAssignAfterThis_1.java ! test/tools/javac/DefiniteAssignment/DefAssignAfterThis_2.java ! test/tools/javac/DefiniteAssignment/DefAssignAfterTry1.java ! test/tools/javac/DefiniteAssignment/DefAssignAfterTry2.java ! test/tools/javac/DefiniteAssignment/DefAssignAfterTry3.java ! test/tools/javac/DefiniteAssignment/DefAssignBoolean/DefAssignBoolean_1.java ! test/tools/javac/DefiniteAssignment/DefAssignBoolean/DefAssignBoolean_10.java ! test/tools/javac/DefiniteAssignment/DefAssignBoolean/DefAssignBoolean_11.java ! test/tools/javac/DefiniteAssignment/DefAssignBoolean/DefAssignBoolean_12.java ! test/tools/javac/DefiniteAssignment/DefAssignBoolean/DefAssignBoolean_13.java ! test/tools/javac/DefiniteAssignment/DefAssignBoolean/DefAssignBoolean_14.java ! test/tools/javac/DefiniteAssignment/DefAssignBoolean/DefAssignBoolean_15.java ! test/tools/javac/DefiniteAssignment/DefAssignBoolean/DefAssignBoolean_16.java ! test/tools/javac/DefiniteAssignment/DefAssignBoolean/DefAssignBoolean_2.java ! test/tools/javac/DefiniteAssignment/DefAssignBoolean/DefAssignBoolean_3.java ! test/tools/javac/DefiniteAssignment/DefAssignBoolean/DefAssignBoolean_4.java ! test/tools/javac/DefiniteAssignment/DefAssignBoolean/DefAssignBoolean_5.java ! test/tools/javac/DefiniteAssignment/DefAssignBoolean/DefAssignBoolean_6.java ! test/tools/javac/DefiniteAssignment/DefAssignBoolean/DefAssignBoolean_7.java ! test/tools/javac/DefiniteAssignment/DefAssignBoolean/DefAssignBoolean_8.java ! test/tools/javac/DefiniteAssignment/DefAssignBoolean/DefAssignBoolean_9.java ! test/tools/javac/DefiniteAssignment/DefAssignBoolean/DefAssignCond.java ! test/tools/javac/DefiniteAssignment/DefAssignBoolean/DefAssignConstantBoolean.java ! test/tools/javac/DefiniteAssignment/DefAssignNestedArg.java ! test/tools/javac/DefiniteAssignment/T4704365.java ! test/tools/javac/DefiniteAssignment/T4717164.java ! test/tools/javac/DefiniteAssignment/T4717165.java ! test/tools/javac/DefiniteAssignment/T4718134.java ! test/tools/javac/DefiniteAssignment/T4718142.java ! test/tools/javac/DefiniteAssignment/T4718142a.java ! test/tools/javac/DefiniteAssignment/T4718708.java ! test/tools/javac/DefiniteAssignment/T4720379.java ! test/tools/javac/DefiniteAssignment/T4720751.java ! test/tools/javac/DefiniteAssignment/T4721062a.java ! test/tools/javac/DefiniteAssignment/T4721062b.java ! test/tools/javac/DefiniteAssignment/T4721076.java ! test/tools/javac/DefiniteAssignment/T4721998.java ! test/tools/javac/DefiniteAssignment/T4725725.java ! test/tools/javac/DefiniteAssignment/ThrowBeforeTryFinally.java ! test/tools/javac/DefiniteAssignment/UncaughtException.java ! test/tools/javac/DepParam.java ! test/tools/javac/Diagnostics/6769027/T6769027.java ! test/tools/javac/DivByZero.java ! test/tools/javac/DuplicateClass.java ! test/tools/javac/DuplicateClass2.java ! test/tools/javac/DuplicateImport.java ! test/tools/javac/EOI.java ! test/tools/javac/EarlyAssert.java ! test/tools/javac/EarlyAssertWrapper.java ! test/tools/javac/EmptyArray.java ! test/tools/javac/EmptyBreak.java ! test/tools/javac/EmptyDocComments.java ! test/tools/javac/EmptySwitch.java ! test/tools/javac/EnclosingAccessCheck.java ! test/tools/javac/Enum1.java ! test/tools/javac/ExceptionalFinally.java ! test/tools/javac/ExceptionalFinally2.java ! test/tools/javac/ExprQualifiedType.java ! test/tools/javac/ExtDirs/ExtDirTest_1.java ! test/tools/javac/ExtDirs/ExtDirTest_2.java ! test/tools/javac/ExtDirs/ExtDirTest_3.java ! test/tools/javac/ExtDirs/ExtDirs.sh ! test/tools/javac/ExtendsAccess/p/ExtendsAccess.java ! test/tools/javac/ExtendsScope.java ! test/tools/javac/ExtraneousEquals.java ! test/tools/javac/FaultySignature.java ! test/tools/javac/FinalInitializer.java ! test/tools/javac/FinalInitializer_2.java ! test/tools/javac/FinalIntConcatenation.java ! test/tools/javac/FinalThisReference.java ! test/tools/javac/FinallyWarn.java ! test/tools/javac/FlatnameClash.java ! test/tools/javac/FlatnameClash2.java ! test/tools/javac/FloatingPointChanges/Test.java ! test/tools/javac/FoldConditional.java ! test/tools/javac/ForwardReference/ForwardReference_2.java ! test/tools/javac/ForwardReference/ForwardReference_4.java ! test/tools/javac/ForwardReference/ForwardReference_5.java ! test/tools/javac/ForwardReference/T6676362a.java ! test/tools/javac/ForwardReference/T6676362b.java ! test/tools/javac/ForwardReference/UseBeforeDeclaration.java ! test/tools/javac/GoodCovar.java ! test/tools/javac/HexFloatLiterals.java ! test/tools/javac/HexThree.java ! test/tools/javac/HiddenAbstractMethod/one/Parent.java ! test/tools/javac/HiddenAbstractMethod/two/Child.java ! test/tools/javac/IllDefinedOrderOfInit.java ! test/tools/javac/IllegallyOptimizedException.java ! test/tools/javac/ImplicitToString.java ! test/tools/javac/ImportCycle/Dummy.java ! test/tools/javac/ImportCycle/foo/Bottom.java ! test/tools/javac/ImportCycle/foo/Bottom2.java ! test/tools/javac/ImportCycle/foo/Middle.java ! test/tools/javac/ImportCycle/foo/Middle2.java ! test/tools/javac/ImportCycle/foo/Top.java ! test/tools/javac/ImportCycle/foo/Top2.java ! test/tools/javac/ImportPackagePrivateInner/Dummy.java ! test/tools/javac/ImportPackagePrivateInner/foo/Accessee.java ! test/tools/javac/ImportPackagePrivateInner/foo/Accessor.java ! test/tools/javac/ImportUnnamed/Dummy.java ! test/tools/javac/ImportUnnamed/foo/A.java ! test/tools/javac/InconsistentInheritedSignature.java ! test/tools/javac/InconsistentStack.java ! test/tools/javac/Increment.java ! test/tools/javac/InheritedPrivateImpl.java ! test/tools/javac/InitializerCompletion_1.java ! test/tools/javac/InitializerCompletion_2.java ! test/tools/javac/InitializerCompletion_3.java ! test/tools/javac/InitializerCompletion_4.java ! test/tools/javac/InnerClassesAttribute/Test.java ! test/tools/javac/InnerMemberRegression.java ! test/tools/javac/InnerMethSig.java ! test/tools/javac/InnerNamedConstant_1.java ! test/tools/javac/InnerTruth.java ! test/tools/javac/InstanceInitException_1.java ! test/tools/javac/InstanceInitException_2.java ! test/tools/javac/InterfaceAssert.java ! test/tools/javac/InterfaceFieldParsing_1.java ! test/tools/javac/InterfaceInInner.java ! test/tools/javac/InterfaceObjectIncompatibility.java ! test/tools/javac/InterfaceObjectInheritance.java ! test/tools/javac/InterfaceOverrideCheck.java ! test/tools/javac/InterfaceOverrideFinal.java ! test/tools/javac/InterfaceOverrideObject.java ! test/tools/javac/InvalidIntfCast.java ! test/tools/javac/JsrRet.java ! test/tools/javac/LabelHiding_1.java ! test/tools/javac/LabeledDeclaration.java ! test/tools/javac/LocalClasses_1.java ! test/tools/javac/ManyMembers2.java ! test/tools/javac/MemberTypeInheritance.java ! test/tools/javac/MissingInclude.java ! test/tools/javac/MissingInclude.sh ! test/tools/javac/NameClash/One.java ! test/tools/javac/NameClash/a/One.java ! test/tools/javac/NameClash/b/One.java ! test/tools/javac/NameCollision2.java ! test/tools/javac/NestedDuplicateLabels.java ! test/tools/javac/NestedFinallyReturn.java ! test/tools/javac/NewGeneric.java ! test/tools/javac/NoClass.java ! test/tools/javac/NoNoClassDefFoundErrorError.java ! test/tools/javac/NonAmbiguousField/one/Parent.java ! test/tools/javac/NonAmbiguousField/one/Parent2.java ! test/tools/javac/NonAmbiguousField/two/Child.java ! test/tools/javac/NonAmbiguousField/two/Child2.java ! test/tools/javac/NonStaticFieldExpr4c.java ! test/tools/javac/NonStaticFieldExpr4d.java ! test/tools/javac/NonStaticFinalVar.java ! test/tools/javac/Null2DArray.java ! test/tools/javac/NullQualifiedNew.java ! test/tools/javac/NullQualifiedNew2.java ! test/tools/javac/NullQualifiedSuper1.java ! test/tools/javac/NullQualifiedSuper2.java ! test/tools/javac/NullStaticQualifier.java ! test/tools/javac/Object1.java ! test/tools/javac/Object2.java ! test/tools/javac/ObjectIncompatibleInterface.java ! test/tools/javac/ObjectMethodRefFromInterface.java ! test/tools/javac/OuterParameter_1.java ! test/tools/javac/OverrideChecks/6400189/T6400189c.java ! test/tools/javac/OverrideChecks/6400189/T6400189d.java ! test/tools/javac/OverrideChecks/6738538/T6738538a.java ! test/tools/javac/OverrideChecks/6738538/T6738538b.java ! test/tools/javac/OverrideChecks/InconsistentReturn.java ! test/tools/javac/OverrideChecks/InterfaceImplements.java ! test/tools/javac/OverrideChecks/InterfaceOverride.java ! test/tools/javac/OverrideChecks/Private.java ! test/tools/javac/OverrideChecks/StaticOverride.java ! test/tools/javac/OverrideChecks/T4720356a.java ! test/tools/javac/OverrideChecks/T4720356b.java ! test/tools/javac/OverrideChecks/T4720359a.java ! test/tools/javac/OverrideChecks/T4720359b.java ! test/tools/javac/OverrideChecks/T4721069.java ! test/tools/javac/OverrideChecks/T6326485.java ! test/tools/javac/OverrideChecks/T6399361.java ! test/tools/javac/OverrideChecks/ThrowsConflict.java ! test/tools/javac/PackageClassAmbiguity/Bad.java ! test/tools/javac/PackageClassAmbiguity/util.java ! test/tools/javac/PackageClassClash/PackageClassClash.java ! test/tools/javac/Parens1.java ! test/tools/javac/Parens2.java ! test/tools/javac/Parens3.java ! test/tools/javac/Parens4.java ! test/tools/javac/ParseConditional.java ! test/tools/javac/Paths/6638501/HelloLib/test/HelloImpl.java ! test/tools/javac/Paths/6638501/JarFromManifestFailure.java ! test/tools/javac/Paths/6638501/WsCompileExample.java ! test/tools/javac/Paths/6638501/test/SayHello.java ! test/tools/javac/Paths/6638501/test1/SayHelloToo.java ! test/tools/javac/Paths/Class-Path.sh ! test/tools/javac/Paths/CompileClose.java ! test/tools/javac/Paths/Diagnostics.sh ! test/tools/javac/Paths/Help.sh ! test/tools/javac/Paths/MineField.sh ! test/tools/javac/Paths/SameJVM.java ! test/tools/javac/Paths/Util.sh ! test/tools/javac/Paths/wcMineField.sh ! test/tools/javac/PrivateLocalConstructor.java ! test/tools/javac/PrivateUplevelConstant.java ! test/tools/javac/ProtectedInnerClass/ProtectedInnerClass.sh ! test/tools/javac/ProtectedInnerClass/ProtectedInnerClass_2.java ! test/tools/javac/ProtectedInnerClass/p1/ProtectedInnerClass1.java ! test/tools/javac/ProtectedInnerClass/p2/ProtectedInnerClass2.java ! test/tools/javac/ProtectedInnerClass/p2/ProtectedInnerClass3.java ! test/tools/javac/QualifiedAccess/QualifiedAccess_4.java ! test/tools/javac/QualifiedAccess/pack1/P1.java ! test/tools/javac/QualifiedAccess/pack1/P2.java ! test/tools/javac/QualifiedConstant.java ! test/tools/javac/QualifiedNew.java ! test/tools/javac/QualifiedNewScope.java ! test/tools/javac/QualifiedOuterThis.java ! test/tools/javac/QualifiedOuterThis2.java ! test/tools/javac/QualifiedThisAndSuper_1.java ! test/tools/javac/QualifiedThisAndSuper_2.java ! test/tools/javac/QualifiedThisAndSuper_3.java ! test/tools/javac/QualifiedThisExactMatch.java ! test/tools/javac/RawCrash.java ! test/tools/javac/ReturnAfterIfThenElse.java ! test/tools/javac/SerialWarn.java ! test/tools/javac/ShiftExpressionTest.java ! test/tools/javac/Source5.java ! test/tools/javac/StandaloneQualifiedSuper.java ! test/tools/javac/StaticBlockScope.java ! test/tools/javac/StoreClass.java ! test/tools/javac/StrictAbstract.java ! test/tools/javac/StringAppendAccessMethodOnLHS.java ! test/tools/javac/StringConversion.java ! test/tools/javac/StringConversion2.java ! test/tools/javac/StringsInSwitch/OneCaseSwitches.java ! test/tools/javac/StringsInSwitch/StringSwitches.java ! test/tools/javac/SuperField.java ! test/tools/javac/SuperMeth.java ! test/tools/javac/SuperMethodResolve.java ! test/tools/javac/SuperNew.java ! test/tools/javac/SuperNew2.java ! test/tools/javac/SuperNew3.java ! test/tools/javac/SuperNew4.java ! test/tools/javac/SuperclassConstructorException.java ! test/tools/javac/SwitchFence.java ! test/tools/javac/SwitchScope.java ! test/tools/javac/SynthName1.java ! test/tools/javac/SynthName2.java ! test/tools/javac/T4848619/T4848619a.java ! test/tools/javac/T4848619/T4848619b.java ! test/tools/javac/T4994049/DeprecatedNOT.java ! test/tools/javac/T4994049/DeprecatedYES.java ! test/tools/javac/T5090006/T5090006.java ! test/tools/javac/T5090006/compiler.sh ! test/tools/javac/T5092545.java ! test/tools/javac/T5105890.java ! test/tools/javac/T6180021/AbstractSub.java ! test/tools/javac/T6180021/Sub.java ! test/tools/javac/T6180021/Super.java ! test/tools/javac/T6231246/T6231246.java ! test/tools/javac/T6232928.java ! test/tools/javac/T6232928/package-info.java ! test/tools/javac/T6234077.java ! test/tools/javac/T6238612.java ! test/tools/javac/T6265400.java ! test/tools/javac/T6266772.java ! test/tools/javac/T6294589.java ! test/tools/javac/T6304128.java ! test/tools/javac/T6306967.java ! test/tools/javac/T6326754.java ! test/tools/javac/T6341023.java ! test/tools/javac/T6351767.java ! test/tools/javac/T6356217/T6356217.java ! test/tools/javac/T6358024.java ! test/tools/javac/T6358166.java ! test/tools/javac/T6358168.java ! test/tools/javac/T6361619.java ! test/tools/javac/T6366196.java ! test/tools/javac/T6370653.java ! test/tools/javac/T6379327.java ! test/tools/javac/T6395974.java ! test/tools/javac/T6397044.java ! test/tools/javac/T6397286.java ! test/tools/javac/T6403466.java ! test/tools/javac/T6404756.java ! test/tools/javac/T6405099.java ! test/tools/javac/T6407066.java ! test/tools/javac/T6407257.java ! test/tools/javac/T6410706.java ! test/tools/javac/T6411379.java ! test/tools/javac/T6413876.java ! test/tools/javac/T6423583.java ! test/tools/javac/T6435291/T6435291.java ! test/tools/javac/T6472751.java ! test/tools/javac/T6534287.java ! test/tools/javac/T6557865.java ! test/tools/javac/T6558476.java ! test/tools/javac/T6595666.java ! test/tools/javac/T6625520.java ! test/tools/javac/T6654037.java ! test/tools/javac/T6663588.java ! test/tools/javac/T6665791.java ! test/tools/javac/T6668802.java ! test/tools/javac/T6705935.java ! test/tools/javac/T6725036.java ! test/tools/javac/T6759996.java ! test/tools/javac/T6794959.java ! test/tools/javac/T6855236.java ! test/tools/javac/T6873849.java ! test/tools/javac/T6881645.java ! test/tools/javac/T6942649.java ! test/tools/javac/ThrowNull.java ! test/tools/javac/ThrowsIntersection_1.java ! test/tools/javac/ThrowsIntersection_2.java ! test/tools/javac/ThrowsIntersection_3.java ! test/tools/javac/ThrowsIntersection_4.java ! test/tools/javac/TryInInstanceInit.java ! test/tools/javac/UncaughtOverflow.java ! test/tools/javac/UncaughtOverflow2.java ! test/tools/javac/UnreachableVar.java ! test/tools/javac/UnterminatedLineComment.java ! test/tools/javac/UplevelFromAnonInSuperCall.java ! test/tools/javac/UseEnum.java ! test/tools/javac/VarDeclarationWithAssignment.java ! test/tools/javac/Verify.java ! test/tools/javac/VerifyDA.java ! test/tools/javac/VersionOpt.java ! test/tools/javac/VoidArray.java ! test/tools/javac/abstract/T1.java ! test/tools/javac/abstract/T2.java ! test/tools/javac/abstract/T3.java ! test/tools/javac/abstract/T4717181a.java ! test/tools/javac/abstract/T4717181b.java ! test/tools/javac/abstract/U1.java ! test/tools/javac/abstract/U2.java ! test/tools/javac/abstract/U3.java ! test/tools/javac/accessVirtualInner/Main.java ! test/tools/javac/accessVirtualInner/a/A.java ! test/tools/javac/accessVirtualInner/b/B.java ! test/tools/javac/accessVirtualInner/c/C.java ! test/tools/javac/annotations/6214965/CompilerAnnotationTest.java ! test/tools/javac/annotations/6214965/CompilerAnnotationTest2.java ! test/tools/javac/annotations/6214965/CompilerAnnotationTest2bad.java ! test/tools/javac/annotations/6214965/T6214965.java ! test/tools/javac/annotations/6359949/T6359949.java ! test/tools/javac/annotations/6359949/T6359949a.java ! test/tools/javac/annotations/6365854/T6365854.java ! test/tools/javac/annotations/6365854/TestAnnotation.java ! test/tools/javac/annotations/6365854/TestCore.java ! test/tools/javac/annotations/6365854/evolve/TestAnnotation.java ! test/tools/javac/annotations/default/A.java ! test/tools/javac/annotations/default/B.java ! test/tools/javac/annotations/default/C.java ! test/tools/javac/annotations/default/Derr.java ! test/tools/javac/annotations/default/Eerr.java ! test/tools/javac/annotations/neg/AnnComma.java ! test/tools/javac/annotations/neg/ArrayLit.java ! test/tools/javac/annotations/neg/Constant.java ! test/tools/javac/annotations/neg/Cycle1.java ! test/tools/javac/annotations/neg/Cycle2.java ! test/tools/javac/annotations/neg/Cycle3.java ! test/tools/javac/annotations/neg/Dep.java ! test/tools/javac/annotations/neg/Dup.java ! test/tools/javac/annotations/neg/DupTarget.java ! test/tools/javac/annotations/neg/MemberOver.java ! test/tools/javac/annotations/neg/MixedSource.java ! test/tools/javac/annotations/neg/NoAnnotationMethods.java ! test/tools/javac/annotations/neg/NoClone.java ! test/tools/javac/annotations/neg/NoObjectMethods.java ! test/tools/javac/annotations/neg/ObjectMembers.java ! test/tools/javac/annotations/neg/OverrideNo.java ! test/tools/javac/annotations/neg/Package.java ! test/tools/javac/annotations/neg/Recovery.java ! test/tools/javac/annotations/neg/Recovery1.java ! test/tools/javac/annotations/neg/Scope.java ! test/tools/javac/annotations/neg/Syntax1.java ! test/tools/javac/annotations/neg/WrongTarget.java ! test/tools/javac/annotations/neg/WrongTarget2.java ! test/tools/javac/annotations/neg/WrongValue.java ! test/tools/javac/annotations/neg/Z1.java ! test/tools/javac/annotations/neg/Z10.java ! test/tools/javac/annotations/neg/Z11.java ! test/tools/javac/annotations/neg/Z12.java ! test/tools/javac/annotations/neg/Z13.java ! test/tools/javac/annotations/neg/Z14.java ! test/tools/javac/annotations/neg/Z15.java ! test/tools/javac/annotations/neg/Z16.java ! test/tools/javac/annotations/neg/Z2.java ! test/tools/javac/annotations/neg/Z3.java ! test/tools/javac/annotations/neg/Z4.java ! test/tools/javac/annotations/neg/Z5.java ! test/tools/javac/annotations/neg/Z8.java ! test/tools/javac/annotations/neg/Z9.java ! test/tools/javac/annotations/pos/AnnotationMethods.java ! test/tools/javac/annotations/pos/AnnoteElideBraces.java ! test/tools/javac/annotations/pos/ClassA.java ! test/tools/javac/annotations/pos/ClassB.java ! test/tools/javac/annotations/pos/Dep.java ! test/tools/javac/annotations/pos/Enum1.java ! test/tools/javac/annotations/pos/Local.java ! test/tools/javac/annotations/pos/Members.java ! test/tools/javac/annotations/pos/NType.java ! test/tools/javac/annotations/pos/OverrideCheck.java ! test/tools/javac/annotations/pos/OverrideOK.java ! test/tools/javac/annotations/pos/Parameter.java ! test/tools/javac/annotations/pos/Primitives.java ! test/tools/javac/annotations/pos/RightTarget.java ! test/tools/javac/annotations/pos/TrailingComma.java ! test/tools/javac/annotations/pos/Z1.java ! test/tools/javac/annotations/pos/Z2.java ! test/tools/javac/annotations/pos/Z3.java ! test/tools/javac/annotations/pos/Z4.java ! test/tools/javac/annotations/pos/package-info.java ! test/tools/javac/api/6400303/T6400303.java ! test/tools/javac/api/6400303/Test1.java ! test/tools/javac/api/6400303/Test2.java ! test/tools/javac/api/6406133/T6406133.java ! test/tools/javac/api/6410643/T6410643.java ! test/tools/javac/api/6411310/T6411310.java ! test/tools/javac/api/6411310/Test.java ! test/tools/javac/api/6411333/T6411333.java ! test/tools/javac/api/6412656/T6412656.java ! test/tools/javac/api/6415780/T6415780.java ! test/tools/javac/api/6418694/T6418694.java ! test/tools/javac/api/6420409/T6420409.java ! test/tools/javac/api/6420464/T6420464.java ! test/tools/javac/api/6421111/T6421111.java ! test/tools/javac/api/6421756/T6421756.java ! test/tools/javac/api/6422215/T6422215.java ! test/tools/javac/api/6422327/T6422327.java ! test/tools/javac/api/6423003/T6423003.java ! test/tools/javac/api/6431257/T6431257.java ! test/tools/javac/api/6431257/package-info.java ! test/tools/javac/api/6431435/A.java ! test/tools/javac/api/6431435/T6431435.java ! test/tools/javac/api/6431435/p/B.java ! test/tools/javac/api/6437349/T6437349.java ! test/tools/javac/api/6437999/T6437999.java ! test/tools/javac/api/6437999/Utf8.java ! test/tools/javac/api/6440333/T6440333.java ! test/tools/javac/api/6440528/T6440528.java ! test/tools/javac/api/6440528/package-info.java ! test/tools/javac/api/6452876/T6452876.java ! test/tools/javac/api/6468404/T6468404.java ! test/tools/javac/api/6471599/Main.java ! test/tools/javac/api/6557752/T6557752.java ! test/tools/javac/api/6608214/T6608214.java ! test/tools/javac/api/6731573/T6731573.java ! test/tools/javac/api/6733837/T6733837.java ! test/tools/javac/api/6852595/T6852595.java ! test/tools/javac/api/Sibling.java ! test/tools/javac/api/T6257235.java ! test/tools/javac/api/T6258271.java ! test/tools/javac/api/T6265137.java ! test/tools/javac/api/T6265137a.java ! test/tools/javac/api/T6306137.java ! test/tools/javac/api/T6345974.java ! test/tools/javac/api/T6357331.java ! test/tools/javac/api/T6358786.java ! test/tools/javac/api/T6358955.java ! test/tools/javac/api/T6392782.java ! test/tools/javac/api/T6395981.java ! test/tools/javac/api/T6397104.java ! test/tools/javac/api/T6400205.java ! test/tools/javac/api/T6400207.java ! test/tools/javac/api/T6407011.java ! test/tools/javac/api/T6412669.java ! test/tools/javac/api/T6431879.java ! test/tools/javac/api/T6483788.java ! test/tools/javac/api/T6501502.java ! test/tools/javac/api/T6838467.java ! test/tools/javac/api/T6877206.java ! test/tools/javac/api/TestEvalExpression.java ! test/tools/javac/api/TestGetTree.java ! test/tools/javac/api/TestJavacTask.java ! test/tools/javac/api/TestJavacTaskScanner.java ! test/tools/javac/api/TestOperators.java ! test/tools/javac/api/TestResolveError.java ! test/tools/javac/api/TestResolveIdent.java ! test/tools/javac/api/TestTreePath.java ! test/tools/javac/api/TestTrees.java ! test/tools/javac/api/evalexpr/ByteArrayClassLoader.java ! test/tools/javac/api/evalexpr/CompileFromString.java ! test/tools/javac/api/evalexpr/MemoryFileManager.java ! test/tools/javac/api/guide/Test.java ! test/tools/javac/api/guide/TestMe.java ! test/tools/javac/api/lib/ToolTester.java ! test/tools/javac/apt.sh ! test/tools/javac/assert/Attach.java ! test/tools/javac/assert/DU1.java ! test/tools/javac/assert/DU2.java ! test/tools/javac/binaryCompat/T1.java ! test/tools/javac/binaryCompat/T2.java ! test/tools/javac/binaryCompat/T3.java ! test/tools/javac/boxing/BoxedForeach.java ! test/tools/javac/boxing/Boxing1.java ! test/tools/javac/boxing/Boxing2.java ! test/tools/javac/boxing/Boxing4.java ! test/tools/javac/boxing/BoxingCaching.java ! test/tools/javac/boxing/NoBoxingBool.java ! test/tools/javac/boxing/NoBoxingByte.java ! test/tools/javac/boxing/NoBoxingChar.java ! test/tools/javac/boxing/NoBoxingDouble.java ! test/tools/javac/boxing/NoBoxingFloat.java ! test/tools/javac/boxing/NoBoxingInt.java ! test/tools/javac/boxing/NoBoxingLong.java ! test/tools/javac/boxing/NoBoxingShort.java ! test/tools/javac/boxing/T5082929.java ! test/tools/javac/boxing/T6348760.java ! test/tools/javac/boxing/T6369051.java ! test/tools/javac/boxing/T6614974.java ! test/tools/javac/boxing/T6816548.java ! test/tools/javac/capture/Capture1.java ! test/tools/javac/capture/Capture2.java ! test/tools/javac/capture/Capture3.java ! test/tools/javac/capture/Capture5.java ! test/tools/javac/capture/Martin.java ! test/tools/javac/capture/T6594284.java ! test/tools/javac/cast/4916620/T4916620.java ! test/tools/javac/cast/5034609/T5034609.java ! test/tools/javac/cast/5043020/T5043020.java ! test/tools/javac/cast/5064736/T5064736.java ! test/tools/javac/cast/5065215/T5065215.java ! test/tools/javac/cast/6211853/T6211853.java ! test/tools/javac/cast/6219964/T6219964.java ! test/tools/javac/cast/6256789/T6256789.java ! test/tools/javac/cast/6286112/T6286112.java ! test/tools/javac/cast/6295056/T6295056.java ! test/tools/javac/cast/6302214/T6302214.java ! test/tools/javac/cast/6302214/T6302214a.java ! test/tools/javac/cast/6302956/T6302956.java ! test/tools/javac/cast/6358534/T6358534.java ! test/tools/javac/cast/6467183/T6467183b.java ! test/tools/javac/cast/6548436/T6548436a.java ! test/tools/javac/cast/6548436/T6548436b.java ! test/tools/javac/cast/6548436/T6548436c.java ! test/tools/javac/cast/6548436/T6548436d.java ! test/tools/javac/cast/6558559/T6558559a.java ! test/tools/javac/cast/6558559/T6558559b.java ! test/tools/javac/cast/6586091/T6586091.java ! test/tools/javac/cast/BoxedArray.java ! test/tools/javac/cast/forum/T654170.java ! test/tools/javac/code/ArrayClone.java ! test/tools/javac/completion/C.java ! test/tools/javac/conditional/6500343/T6500343a.java ! test/tools/javac/conditional/6500343/T6500343b.java ! test/tools/javac/conditional/Conditional.java ! test/tools/javac/constDebug/ConstDebug.java ! test/tools/javac/constDebug/ConstDebug.sh ! test/tools/javac/crossPackageImpl/CrossPackageImplA.java ! test/tools/javac/crossPackageImpl/CrossPackageImplB.java ! test/tools/javac/danglingDep/DepX.java ! test/tools/javac/danglingDep/NoDepX.java ! test/tools/javac/danglingDep/RefX.java ! test/tools/javac/danglingDep/Test1.java ! test/tools/javac/depDocComment/DeprecatedDocComment2.java ! test/tools/javac/depOverrides/annotation/B3.java ! test/tools/javac/depOverrides/annotation/I.java ! test/tools/javac/depOverrides/annotation/P.java ! test/tools/javac/depOverrides/annotation/Test1.java ! test/tools/javac/depOverrides/annotation/Test2.java ! test/tools/javac/depOverrides/doccomment/B3.java ! test/tools/javac/depOverrides/doccomment/I.java ! test/tools/javac/depOverrides/doccomment/P.java ! test/tools/javac/depOverrides/doccomment/Test1.java ! test/tools/javac/depOverrides/doccomment/Test2.java ! test/tools/javac/enum/6350057/T6350057.java ! test/tools/javac/enum/6350057/TestEnum.java ! test/tools/javac/enum/6424358/T6424358.java ! test/tools/javac/enum/AbstractEmptyEnum.java ! test/tools/javac/enum/AbstractEnum1.java ! test/tools/javac/enum/DA1.java ! test/tools/javac/enum/DA2.java ! test/tools/javac/enum/DA3.java ! test/tools/javac/enum/Def.java ! test/tools/javac/enum/Enum1.java ! test/tools/javac/enum/Enum2.java ! test/tools/javac/enum/Enum3.java ! test/tools/javac/enum/EnumImplicitPrivateConstructor.java ! test/tools/javac/enum/EnumInit.java ! test/tools/javac/enum/EnumPrivateConstructor.java ! test/tools/javac/enum/EnumProtectedConstructor.java ! test/tools/javac/enum/EnumPublicConstructor.java ! test/tools/javac/enum/EnumSwitch1.java ! test/tools/javac/enum/EnumSwitch2.java ! test/tools/javac/enum/EnumSwitch3.java ! test/tools/javac/enum/EnumSwitch4.java ! test/tools/javac/enum/ExplicitlyAbstractEnum1.java ! test/tools/javac/enum/ExplicitlyAbstractEnum2.java ! test/tools/javac/enum/ExplicitlyFinalEnum1.java ! test/tools/javac/enum/ExplicitlyFinalEnum2.java ! test/tools/javac/enum/FauxEnum1.java ! test/tools/javac/enum/FauxEnum2.java ! test/tools/javac/enum/FauxEnum3.java ! test/tools/javac/enum/FauxSpecialEnum1.java ! test/tools/javac/enum/FauxSpecialEnum2.java ! test/tools/javac/enum/LocalEnum.java ! test/tools/javac/enum/NestedEnum.java ! test/tools/javac/enum/NoFinal.java ! test/tools/javac/enum/NoFinal2.java ! test/tools/javac/enum/NoFinal3.java ! test/tools/javac/enum/NoFinal4.java ! test/tools/javac/enum/NoFinal5.java ! test/tools/javac/enum/OkFinal.java ! test/tools/javac/enum/SynthValues.java ! test/tools/javac/enum/T5075242.java ! test/tools/javac/enum/T5081785.java ! test/tools/javac/enum/T5081785a.java ! test/tools/javac/enum/T5081785b.java ! test/tools/javac/enum/T5081785c.java ! test/tools/javac/enum/T6509042.java ! test/tools/javac/enum/T6675483.java ! test/tools/javac/enum/T6724345.java ! test/tools/javac/enum/TrailingComma.java ! test/tools/javac/enum/UserValue.java ! test/tools/javac/enum/ValueOf.java ! test/tools/javac/enum/enumSwitch/Color2.java ! test/tools/javac/enum/enumSwitch/EnumSwitch.java ! test/tools/javac/enum/forwardRef/TestEnum1.java ! test/tools/javac/enum/forwardRef/TestEnum2.java ! test/tools/javac/enum/forwardRef/TestEnum3.java ! test/tools/javac/enum/forwardRef/TestEnum4.java ! test/tools/javac/enum/forwardRef/TestEnum5.java ! test/tools/javac/enum/forwardRef/TestEnum6.java ! test/tools/javac/expression/NullAppend.java ! test/tools/javac/expression/NullAppend2.java ! test/tools/javac/falseCycle/FalseCycle.java ! test/tools/javac/falseCycle/FalseCycleBase.java ! test/tools/javac/fatalErrors/NoJavaLang.java ! test/tools/javac/fatalErrors/NoJavaLang.sh ! test/tools/javac/foreach/Foreach.java ! test/tools/javac/foreach/GenericIterator.java ! test/tools/javac/foreach/IntersectIterator.java ! test/tools/javac/foreach/ListOfListTest.java ! test/tools/javac/foreach/SpecIterable.java ! test/tools/javac/foreach/StaticBlock.java ! test/tools/javac/foreach/SuperfluousAbstract.java ! test/tools/javac/foreach/T6500701.java ! test/tools/javac/foreach/T6682380.java ! test/tools/javac/generics/5066774/T5066774.java ! test/tools/javac/generics/5086027/T5086027.java ! test/tools/javac/generics/5086027/T5086027pos.java ! test/tools/javac/generics/6182950/T6182950c.java ! test/tools/javac/generics/6192945/Method.java ! test/tools/javac/generics/6192945/MethodNeg.java ! test/tools/javac/generics/6192945/Neg.java ! test/tools/javac/generics/6192945/Neg2.java ! test/tools/javac/generics/6192945/Neg3.java ! test/tools/javac/generics/6192945/T6192945.java ! test/tools/javac/generics/6207386/Test.java ! test/tools/javac/generics/6213818/T6213818.java ! test/tools/javac/generics/6218229/T6218229.java ! test/tools/javac/generics/6227936/Orig.java ! test/tools/javac/generics/6227936/T6227936.java ! test/tools/javac/generics/6245699/T6245699.java ! test/tools/javac/generics/6245699/T6245699a.java ! test/tools/javac/generics/6245699/T6245699b.java ! test/tools/javac/generics/6245699/T6245699c.java ! test/tools/javac/generics/6268476/T6268476.java ! test/tools/javac/generics/6292765/T6292765.java ! test/tools/javac/generics/6294779/T6294779a.java ! test/tools/javac/generics/6294779/T6294779b.java ! test/tools/javac/generics/6294779/T6294779c.java ! test/tools/javac/generics/6332204/T6332204.java ! test/tools/javac/generics/6332204/T6346876.java ! test/tools/javac/generics/6356636/T6356636.java ! test/tools/javac/generics/6356636/a/AbstractFoo.java ! test/tools/javac/generics/6356636/a/Bar.java ! test/tools/javac/generics/6372782/AbstractElement.java ! test/tools/javac/generics/6372782/AbstractPlanarVector.java ! test/tools/javac/generics/6372782/AbstractVector.java ! test/tools/javac/generics/6372782/AdditionDefined.java ! test/tools/javac/generics/6372782/AdditiveClosure.java ! test/tools/javac/generics/6372782/Element.java ! test/tools/javac/generics/6372782/MultiplicationDefined.java ! test/tools/javac/generics/6372782/PlainForm.java ! test/tools/javac/generics/6372782/PlainPlanarVector.java ! test/tools/javac/generics/6372782/PlanarVector.java ! test/tools/javac/generics/6372782/PlanarVectorVariable.java ! test/tools/javac/generics/6372782/Ring.java ! test/tools/javac/generics/6372782/Scalar.java ! test/tools/javac/generics/6372782/State.java ! test/tools/javac/generics/6372782/T6372782.java ! test/tools/javac/generics/6372782/Value.java ! test/tools/javac/generics/6372782/VariableForm.java ! test/tools/javac/generics/6372782/Vector.java ! test/tools/javac/generics/6413682/T6413682.java ! test/tools/javac/generics/6413682/TestPos.java ! test/tools/javac/generics/6487370/T6487370.java ! test/tools/javac/generics/6495506/A.java ! test/tools/javac/generics/6495506/T6495506.java ! test/tools/javac/generics/6531075/T6531075.java ! test/tools/javac/generics/6531090/T6531090a.java ! test/tools/javac/generics/6531090/T6531090b.java ! test/tools/javac/generics/6729401/T6729401.java ! test/tools/javac/generics/ArrayClone.java ! test/tools/javac/generics/ArrayTypearg.java ! test/tools/javac/generics/BridgeClash.java ! test/tools/javac/generics/BridgeOrder.java ! test/tools/javac/generics/BridgeRestype.java ! test/tools/javac/generics/CastCrash.java ! test/tools/javac/generics/Casting.java ! test/tools/javac/generics/Casting2.java ! test/tools/javac/generics/Casting3.java ! test/tools/javac/generics/Casting4.java ! test/tools/javac/generics/Casting5.java ! test/tools/javac/generics/CatchTyparam.java ! test/tools/javac/generics/Conditional.java ! test/tools/javac/generics/Covar2.java ! test/tools/javac/generics/Covar3.java ! test/tools/javac/generics/Covar4.java ! test/tools/javac/generics/Crash01.java ! test/tools/javac/generics/Crash02.java ! test/tools/javac/generics/CyclicInheritance3.java ! test/tools/javac/generics/CyclicInheritance5.java ! test/tools/javac/generics/ErasureClashCrash.java ! test/tools/javac/generics/ExtendedRaw1.java ! test/tools/javac/generics/ExtendedRaw2.java ! test/tools/javac/generics/ExtendedRaw3.java ! test/tools/javac/generics/ExtendedRaw4.java ! test/tools/javac/generics/FinalBridge.java ! test/tools/javac/generics/GenLit1.java ! test/tools/javac/generics/GenLit2.java ! test/tools/javac/generics/GenericAnonCtor.java ! test/tools/javac/generics/GenericMerge.java ! test/tools/javac/generics/GenericOverride.java ! test/tools/javac/generics/GenericThrowable.java ! test/tools/javac/generics/GetClass.java ! test/tools/javac/generics/GetClass2.java ! test/tools/javac/generics/InheritanceConflict.java ! test/tools/javac/generics/InheritanceConflict2.java ! test/tools/javac/generics/InheritanceConflict3.java ! test/tools/javac/generics/InnerInterface1.java ! test/tools/javac/generics/InnerInterface2.java ! test/tools/javac/generics/InstanceOf1.java ! test/tools/javac/generics/InstanceOf2.java ! test/tools/javac/generics/InstanceOf3.java ! test/tools/javac/generics/InterfaceCast1.java ! test/tools/javac/generics/LoadOrder.java ! test/tools/javac/generics/MissingBridge.java ! test/tools/javac/generics/MissingCast.java ! test/tools/javac/generics/Multibound1.java ! test/tools/javac/generics/MultipleInheritance.java ! test/tools/javac/generics/NameOrder.java ! test/tools/javac/generics/Nonlinear.java ! test/tools/javac/generics/ParametricException.java ! test/tools/javac/generics/ParenVerify.java ! test/tools/javac/generics/PermuteBound.java ! test/tools/javac/generics/PrimitiveClass.java ! test/tools/javac/generics/PrimitiveVariant.java ! test/tools/javac/generics/RawClient.java ! test/tools/javac/generics/RefEqual.java ! test/tools/javac/generics/RelaxedArrays.java ! test/tools/javac/generics/ReverseOrder.java ! test/tools/javac/generics/SelfImplement.java ! test/tools/javac/generics/SilentUnchecked.java ! test/tools/javac/generics/SuperTypeargs.java ! test/tools/javac/generics/T4661029.java ! test/tools/javac/generics/T4683314.java ! test/tools/javac/generics/T4684378.java ! test/tools/javac/generics/T4695348.java ! test/tools/javac/generics/T4695415.java ! test/tools/javac/generics/T4695847.java ! test/tools/javac/generics/T4711570.java ! test/tools/javac/generics/T4711572.java ! test/tools/javac/generics/T4711694.java ! test/tools/javac/generics/T4738171.java ! test/tools/javac/generics/T4739399.java ! test/tools/javac/generics/T4757416.java ! test/tools/javac/generics/T4784207a.java ! test/tools/javac/generics/T4784207b.java ! test/tools/javac/generics/T4784219.java ! test/tools/javac/generics/T5011073.java ! test/tools/javac/generics/T5094318.java ! test/tools/javac/generics/T6391995.java ! test/tools/javac/generics/T6481655.java ! test/tools/javac/generics/T6507024.java ! test/tools/javac/generics/T6557954.java ! test/tools/javac/generics/T6657499.java ! test/tools/javac/generics/T6660289.java ! test/tools/javac/generics/T6751514.java ! test/tools/javac/generics/T6869075.java ! test/tools/javac/generics/TyparamLit.java ! test/tools/javac/generics/TyparamStaticScope.java ! test/tools/javac/generics/TyparamStaticScope2.java ! test/tools/javac/generics/UncheckedArray.java ! test/tools/javac/generics/UncheckedConstructor.java ! test/tools/javac/generics/UncheckedCovariance.java ! test/tools/javac/generics/UnsoundInference.java ! test/tools/javac/generics/Varargs.java ! test/tools/javac/generics/Varargs2.java ! test/tools/javac/generics/WrongNew.java ! test/tools/javac/generics/abstract/T4717181c.java ! test/tools/javac/generics/bridge1/A.java ! test/tools/javac/generics/bridge1/C.java ! test/tools/javac/generics/bridge1/D.java ! test/tools/javac/generics/bridge1/E.java ! test/tools/javac/generics/classreader/HArrayMethod.java ! test/tools/javac/generics/classreader/HMember.java ! test/tools/javac/generics/classreader/HMethod.java ! test/tools/javac/generics/classreader/HMethodImpl.java ! test/tools/javac/generics/compat/CovariantCompat1.java ! test/tools/javac/generics/compat/CovariantCompat2.java ! test/tools/javac/generics/compat/OverrideBridge1.java ! test/tools/javac/generics/compat/OverrideBridge2.java ! test/tools/javac/generics/compat/OverrideBridge3.java ! test/tools/javac/generics/compat/VisibleBridge.java ! test/tools/javac/generics/diamond/pos/Pos01.java ! test/tools/javac/generics/diamond/pos/Pos02.java ! test/tools/javac/generics/diamond/pos/Pos03.java ! test/tools/javac/generics/diamond/pos/Pos04.java ! test/tools/javac/generics/diamond/pos/Pos05.java ! test/tools/javac/generics/forwardSeparateBound/ForwardSeparateBound1.java ! test/tools/javac/generics/forwardSeparateBound/ForwardSeparateBound2.java ! test/tools/javac/generics/genericAbstract/A.java ! test/tools/javac/generics/genericAbstract/B.java ! test/tools/javac/generics/inference/4941882/T4941882.java ! test/tools/javac/generics/inference/4942040/T4942040.java ! test/tools/javac/generics/inference/4954546/T4954546.java ! test/tools/javac/generics/inference/4972073/T4972073.java ! test/tools/javac/generics/inference/4972073/T4972073a.java ! test/tools/javac/generics/inference/4972073/T4972073b.java ! test/tools/javac/generics/inference/5003431/T5003431.java ! test/tools/javac/generics/inference/5021635/T5021635.java ! test/tools/javac/generics/inference/5021635/T6299211.java ! test/tools/javac/generics/inference/5034571/T5034571.java ! test/tools/javac/generics/inference/5042462/T5042462.java ! test/tools/javac/generics/inference/5044646/T5044646.java ! test/tools/javac/generics/inference/5044646/p1/A1.java ! test/tools/javac/generics/inference/5044646/p1/B.java ! test/tools/javac/generics/inference/5044646/p1/C.java ! test/tools/javac/generics/inference/5044646/p2/A2.java ! test/tools/javac/generics/inference/5049523/T5049523.java ! test/tools/javac/generics/inference/5070671/T5070671.java ! test/tools/javac/generics/inference/5073060/GenericsAndPackages.java ! test/tools/javac/generics/inference/5073060/Neg.java ! test/tools/javac/generics/inference/5073060/NegHelper.java ! test/tools/javac/generics/inference/5073060/T5073060.java ! test/tools/javac/generics/inference/5073060/T5073060a.java ! test/tools/javac/generics/inference/5080917/T5080917.java ! test/tools/javac/generics/inference/5081782/Neg.java ! test/tools/javac/generics/inference/5081782/Pos.java ! test/tools/javac/generics/inference/6215213/T6215213.java ! test/tools/javac/generics/inference/6222762/T6222762.java ! test/tools/javac/generics/inference/6240565/T6240565.java ! test/tools/javac/generics/inference/6273455/T6273455.java ! test/tools/javac/generics/inference/6278587/T6278587.java ! test/tools/javac/generics/inference/6278587/T6278587Neg.java ! test/tools/javac/generics/inference/6302954/T6456971.java ! test/tools/javac/generics/inference/6302954/T6476073.java ! test/tools/javac/generics/inference/6302954/X.java ! test/tools/javac/generics/inference/6356673/T6365166.java ! test/tools/javac/generics/inference/6356673/Test.java ! test/tools/javac/generics/inference/6359106/Orig.java ! test/tools/javac/generics/inference/6359106/T6359106.java ! test/tools/javac/generics/inference/6365166/NewTest.java ! test/tools/javac/generics/inference/6468384/T6468384.java ! test/tools/javac/generics/inference/6569789/T6569789.java ! test/tools/javac/generics/inference/6650759/T6650759a.java ! test/tools/javac/generics/inference/6650759/T6650759b.java ! test/tools/javac/generics/inference/6650759/T6650759c.java ! test/tools/javac/generics/inference/6650759/T6650759d.java ! test/tools/javac/generics/inference/6650759/T6650759e.java ! test/tools/javac/generics/inference/6650759/T6650759f.java ! test/tools/javac/generics/inference/6650759/T6650759g.java ! test/tools/javac/generics/inference/6650759/T6650759h.java ! test/tools/javac/generics/inference/6650759/T6650759i.java ! test/tools/javac/generics/inference/6650759/T6650759j.java ! test/tools/javac/generics/inference/6650759/T6650759k.java ! test/tools/javac/generics/inference/6650759/T6650759l.java ! test/tools/javac/generics/inference/6650759/T6650759m.java ! test/tools/javac/generics/inference/T6835428.java ! test/tools/javac/generics/odersky/BadTest.java ! test/tools/javac/generics/odersky/BadTest2.java ! test/tools/javac/generics/odersky/BadTest3.java ! test/tools/javac/generics/odersky/BadTest4.java ! test/tools/javac/generics/odersky/Cell.java ! test/tools/javac/generics/odersky/List.java ! test/tools/javac/generics/odersky/Test.java ! test/tools/javac/generics/odersky/Test2.java ! test/tools/javac/generics/odersky/Test3.java ! test/tools/javac/generics/odersky/Test4.java ! test/tools/javac/generics/parametricException/J.java ! test/tools/javac/generics/parametricException/K.java ! test/tools/javac/generics/rare/Rare1.java ! test/tools/javac/generics/rare/Rare10.java ! test/tools/javac/generics/rare/Rare11.java ! test/tools/javac/generics/rare/Rare2.java ! test/tools/javac/generics/rare/Rare3.java ! test/tools/javac/generics/rare/Rare4.java ! test/tools/javac/generics/rare/Rare5.java ! test/tools/javac/generics/rare/Rare6.java ! test/tools/javac/generics/rare/Rare7.java ! test/tools/javac/generics/rare/Rare8.java ! test/tools/javac/generics/rare/Rare9.java ! test/tools/javac/generics/rawOverride/AttributeSet.java ! test/tools/javac/generics/rawOverride/Fail1.java ! test/tools/javac/generics/rawOverride/T6178365.java ! test/tools/javac/generics/rawOverride/T6846972.java ! test/tools/javac/generics/rawOverride/Warn1.java ! test/tools/javac/generics/rawOverride/Warn2.java ! test/tools/javac/generics/rawSeparate/CharScanner.java ! test/tools/javac/generics/rawSeparate/Hashtable.java ! test/tools/javac/generics/rawSeparate/RetroLexer.java ! test/tools/javac/generics/syntax/6318240/Bar.java ! test/tools/javac/generics/syntax/6318240/BarNeg1.java ! test/tools/javac/generics/syntax/6318240/BarNeg1a.java ! test/tools/javac/generics/syntax/6318240/BarNeg2.java ! test/tools/javac/generics/syntax/6318240/BarNeg2a.java ! test/tools/javac/generics/syntax/6318240/Foo.java ! test/tools/javac/generics/typeargs/Basic.java ! test/tools/javac/generics/typeargs/Metharg1.java ! test/tools/javac/generics/typeargs/Metharg2.java ! test/tools/javac/generics/typeargs/Newarg1.java ! test/tools/javac/generics/typeargs/Newarg2.java ! test/tools/javac/generics/typeargs/Superarg1.java ! test/tools/javac/generics/typeargs/Superarg2.java ! test/tools/javac/generics/typeargs/ThisArg.java ! test/tools/javac/generics/typevars/4856983/T4856983.java ! test/tools/javac/generics/typevars/4856983/T4856983a.java ! test/tools/javac/generics/typevars/4856983/T4856983b.java ! test/tools/javac/generics/typevars/5060485/Compatibility.java ! test/tools/javac/generics/typevars/5060485/Method.java ! test/tools/javac/generics/typevars/5060485/Neg1.java ! test/tools/javac/generics/typevars/5060485/Neg2.java ! test/tools/javac/generics/typevars/5060485/Pos.java ! test/tools/javac/generics/typevars/5060485/T5060485.java ! test/tools/javac/generics/typevars/5061359/Base.java ! test/tools/javac/generics/typevars/5061359/Intf.java ! test/tools/javac/generics/typevars/5061359/T5061359.java ! test/tools/javac/generics/typevars/5061359/T5061359a.java ! test/tools/javac/generics/typevars/5061359/T5061359b.java ! test/tools/javac/generics/typevars/6182630/T6182630.java ! test/tools/javac/generics/typevars/6182630/T6182630a.java ! test/tools/javac/generics/typevars/6182630/T6182630b.java ! test/tools/javac/generics/typevars/6182630/T6182630c.java ! test/tools/javac/generics/typevars/6182630/T6182630d.java ! test/tools/javac/generics/typevars/6182630/T6182630e.java ! test/tools/javac/generics/typevars/6182630/T6182630f.java ! test/tools/javac/generics/typevars/6199146/T6199146.java ! test/tools/javac/generics/typevars/6486430/T6486430.java ! test/tools/javac/generics/typevars/6486430/T6486430a.java ! test/tools/javac/generics/typevars/6569404/T6569404a.java ! test/tools/javac/generics/typevars/6569404/T6569404c.java ! test/tools/javac/generics/wildcards/6320612/T6320612.java ! test/tools/javac/generics/wildcards/6330931/T6330931.java ! test/tools/javac/generics/wildcards/6437894/A.java ! test/tools/javac/generics/wildcards/6437894/B.java ! test/tools/javac/generics/wildcards/6651719/T6651719a.java ! test/tools/javac/generics/wildcards/6762569/T6762569a.java ! test/tools/javac/generics/wildcards/6762569/T6762569b.java ! test/tools/javac/generics/wildcards/AssignmentDifferentTypes1.java ! test/tools/javac/generics/wildcards/AssignmentDifferentTypes2.java ! test/tools/javac/generics/wildcards/AssignmentDifferentTypes3.java ! test/tools/javac/generics/wildcards/AssignmentDifferentTypes4.java ! test/tools/javac/generics/wildcards/AssignmentDifferentTypes5.java ! test/tools/javac/generics/wildcards/AssignmentDifferentTypes6.java ! test/tools/javac/generics/wildcards/AssignmentDifferentTypes7.java ! test/tools/javac/generics/wildcards/AssignmentDifferentTypes8.java ! test/tools/javac/generics/wildcards/AssignmentDifferentTypes9.java ! test/tools/javac/generics/wildcards/AssignmentSameType1.java ! test/tools/javac/generics/wildcards/AssignmentSameType2.java ! test/tools/javac/generics/wildcards/AssignmentSameType3.java ! test/tools/javac/generics/wildcards/AssignmentSameType4.java ! test/tools/javac/generics/wildcards/AssignmentSameType5.java ! test/tools/javac/generics/wildcards/AssignmentSameType6.java ! test/tools/javac/generics/wildcards/AssignmentSameType7.java ! test/tools/javac/generics/wildcards/AssignmentSameType8.java ! test/tools/javac/generics/wildcards/BoundBug.java ! test/tools/javac/generics/wildcards/ContraArg.java ! test/tools/javac/generics/wildcards/T5097548.java ! test/tools/javac/generics/wildcards/T5097548b.java ! test/tools/javac/generics/wildcards/T6450290.java ! test/tools/javac/generics/wildcards/T6732484.java ! test/tools/javac/generics/wildcards/UnboundArray.java ! test/tools/javac/generics/wildcards/neg/AmbiguousCast.java ! test/tools/javac/generics/wildcards/neg/Capture.java ! test/tools/javac/generics/wildcards/neg/CastFail1.java ! test/tools/javac/generics/wildcards/neg/CastFail10.java ! test/tools/javac/generics/wildcards/neg/CastFail11.java ! test/tools/javac/generics/wildcards/neg/CastFail12.java ! test/tools/javac/generics/wildcards/neg/CastFail13.java ! test/tools/javac/generics/wildcards/neg/CastFail14.java ! test/tools/javac/generics/wildcards/neg/CastFail15.java ! test/tools/javac/generics/wildcards/neg/CastFail16.java ! test/tools/javac/generics/wildcards/neg/CastFail17.java ! test/tools/javac/generics/wildcards/neg/CastFail18.java ! test/tools/javac/generics/wildcards/neg/CastFail19.java ! test/tools/javac/generics/wildcards/neg/CastFail2.java ! test/tools/javac/generics/wildcards/neg/CastFail20.java ! test/tools/javac/generics/wildcards/neg/CastFail21.java ! test/tools/javac/generics/wildcards/neg/CastFail3.java ! test/tools/javac/generics/wildcards/neg/CastFail4.java ! test/tools/javac/generics/wildcards/neg/CastFail5.java ! test/tools/javac/generics/wildcards/neg/CastFail6.java ! test/tools/javac/generics/wildcards/neg/CastFail7.java ! test/tools/javac/generics/wildcards/neg/CastFail8.java ! test/tools/javac/generics/wildcards/neg/CastFail9.java ! test/tools/javac/generics/wildcards/neg/CastWarn10.java ! test/tools/javac/generics/wildcards/neg/CastWarn11.java ! test/tools/javac/generics/wildcards/neg/CastWarn12.java ! test/tools/javac/generics/wildcards/neg/CastWarn13.java ! test/tools/javac/generics/wildcards/neg/CastWarn14.java ! test/tools/javac/generics/wildcards/neg/CastWarn2.java ! test/tools/javac/generics/wildcards/neg/CastWarn3.java ! test/tools/javac/generics/wildcards/neg/CastWarn4.java ! test/tools/javac/generics/wildcards/neg/CastWarn5.java ! test/tools/javac/generics/wildcards/neg/CastWarn6.java ! test/tools/javac/generics/wildcards/neg/CastWarn7.java ! test/tools/javac/generics/wildcards/neg/CastWarn8.java ! test/tools/javac/generics/wildcards/neg/CastWarn9.java ! test/tools/javac/generics/wildcards/neg/ParamCast.java ! test/tools/javac/generics/wildcards/neg/Readonly.java ! test/tools/javac/generics/wildcards/neg/Unbounded.java ! test/tools/javac/generics/wildcards/pos/AmbiguousCast2.java ! test/tools/javac/generics/wildcards/pos/BoundsCollision.java ! test/tools/javac/generics/wildcards/pos/Capture.java ! test/tools/javac/generics/wildcards/pos/CastTest.java ! test/tools/javac/generics/wildcards/pos/InstanceOf.java ! test/tools/javac/generics/wildcards/pos/ParamCast.java ! test/tools/javac/generics/wildcards/pos/RvalConversion.java ! test/tools/javac/generics/wildcards/pos/UncheckedCast1.java ! test/tools/javac/implicitThis/NewBeforeOuterConstructed.java ! test/tools/javac/implicitThis/NewBeforeOuterConstructed2.java ! test/tools/javac/implicitThis/NewBeforeOuterConstructed3.java ! test/tools/javac/implicitThis/WhichImplicitThis1.java ! test/tools/javac/implicitThis/WhichImplicitThis10.java ! test/tools/javac/implicitThis/WhichImplicitThis11.java ! test/tools/javac/implicitThis/WhichImplicitThis2.java ! test/tools/javac/implicitThis/WhichImplicitThis3.java ! test/tools/javac/implicitThis/WhichImplicitThis4.java ! test/tools/javac/implicitThis/WhichImplicitThis5.java ! test/tools/javac/implicitThis/WhichImplicitThis6.java ! test/tools/javac/implicitThis/WhichImplicitThis7.java ! test/tools/javac/implicitThis/WhichImplicitThis9.java ! test/tools/javac/importChecks/ImportCanonical1.java ! test/tools/javac/importChecks/ImportCanonical2.java ! test/tools/javac/importChecks/ImportIsFullyQualified.java ! test/tools/javac/importChecks/ImportOfOwnClass.java ! test/tools/javac/importChecks/InvalidImportsNoClasses.java ! test/tools/javac/importContext/anonPackage/Foo.java ! test/tools/javac/importContext/anonPackage/bar/Baz.java ! test/tools/javac/importContext/namedPackage/Dummy.java ! test/tools/javac/importContext/namedPackage/bar/Baz.java ! test/tools/javac/importContext/namedPackage/foo/Foo.java ! test/tools/javac/importscope/A.java ! test/tools/javac/importscope/B.java ! test/tools/javac/incompatibleNoninherited/A.java ! test/tools/javac/incompatibleNoninherited/B.java ! test/tools/javac/inheritAccess/PvtMbrsNotInherit1.java ! test/tools/javac/inheritedAccess/MethodReferenceQualification_1.java ! test/tools/javac/inheritedAccess/P1/priv.java ! test/tools/javac/inheritedAccess/P1/pub.java ! test/tools/javac/innerClassFile/Driver.sh ! test/tools/javac/innerClassFile/x/B.java ! test/tools/javac/innerClassFile/x/C.java ! test/tools/javac/innerClassFile/y/Main.java ! test/tools/javac/innerClassFile/y/R1.java ! test/tools/javac/innerClassFile/y/R2.java ! test/tools/javac/innerClassFile/y/R3.java ! test/tools/javac/javazip/A.java ! test/tools/javac/javazip/Test.sh ! test/tools/javac/javazip/bad/B.java ! test/tools/javac/javazip/good/B.java ! test/tools/javac/jvm/6397652/T6397652.java ! test/tools/javac/jvm/6397652/com/test/Test.java ! test/tools/javac/limits/ArrayDims1.java ! test/tools/javac/limits/ArrayDims2.java ! test/tools/javac/limits/ArrayDims3.java ! test/tools/javac/limits/ArrayDims4.java ! test/tools/javac/limits/ArrayDims5.java ! test/tools/javac/limits/CodeSize.java ! test/tools/javac/limits/FinallyNesting.java ! test/tools/javac/limits/LongName.java ! test/tools/javac/limits/NumArgs1.java ! test/tools/javac/limits/NumArgs2.java ! test/tools/javac/limits/NumArgs3.java ! test/tools/javac/limits/NumArgs4.java ! test/tools/javac/limits/PoolSize1.java ! test/tools/javac/limits/PoolSize2.java ! test/tools/javac/limits/StringLength.java ! test/tools/javac/links/T.java ! test/tools/javac/links/b/B.java ! test/tools/javac/links/links.sh ! test/tools/javac/lint/Deprecation.java ! test/tools/javac/lint/FallThrough.java ! test/tools/javac/lint/Unchecked.java ! test/tools/javac/literals/BinaryLiterals.java ! test/tools/javac/literals/UnderscoreLiterals.java ! test/tools/javac/mandatoryWarnings/deprecated/Test.java ! test/tools/javac/mandatoryWarnings/unchecked/Test.java ! test/tools/javac/meth/InvokeDyn.java ! test/tools/javac/meth/InvokeMH.java ! test/tools/javac/meth/MakeNegTests.sh ! test/tools/javac/miranda/4686148/AbstractTest.java ! test/tools/javac/miranda/4686148/ConcreteTest.java ! test/tools/javac/miranda/4686148/Test.java ! test/tools/javac/miranda/4686811/Tryit.java ! test/tools/javac/miranda/4686811/p1/A.java ! test/tools/javac/miranda/4686811/p1/C.java ! test/tools/javac/miranda/4686811/p2/B.java ! test/tools/javac/miranda/4711056/T1.java ! test/tools/javac/miranda/4711056/T2.java ! test/tools/javac/miranda/4711056/T3.java ! test/tools/javac/miranda/4711056/T4.java ! test/tools/javac/miranda/T4279316a.java ! test/tools/javac/miranda/T4279316b.java ! test/tools/javac/miranda/T4279316c.java ! test/tools/javac/miranda/T4279316d.java ! test/tools/javac/miranda/T4528315.java ! test/tools/javac/miranda/T4711325.java ! test/tools/javac/missingClass/A.java ! test/tools/javac/missingClass/B.java ! test/tools/javac/mixedTarget/CompatibleAbstracts1.java ! test/tools/javac/mixedTarget/CompatibleAbstracts2.java ! test/tools/javac/mixedTarget/CompatibleAbstracts3.java ! test/tools/javac/mixedTarget/CompatibleAbstracts4.java ! test/tools/javac/mixedTarget/CompatibleAbstracts5.java ! test/tools/javac/mixedTarget/ExtendCovariant1.java ! test/tools/javac/mixedTarget/ExtendCovariant2.java ! test/tools/javac/multicatch/Pos01.java ! test/tools/javac/multicatch/Pos02.java ! test/tools/javac/multicatch/Pos03.java ! test/tools/javac/multicatch/Pos04.java ! test/tools/javac/multicatch/Pos05.java ! test/tools/javac/nested/4903103/T4903103.java ! test/tools/javac/nested/5009484/X.java ! test/tools/javac/nested/5009484/Y.java ! test/tools/javac/newlines/Newlines.sh ! test/tools/javac/nio/compileTest/CompileTest.java ! test/tools/javac/nio/compileTest/HelloPathWorld.java ! test/tools/javac/overload/T4494762.java ! test/tools/javac/overload/T4723909.java ! test/tools/javac/overload/T4743490.java ! test/tools/javac/overload/T5090220.java ! test/tools/javac/overload/T6776289.java ! test/tools/javac/overrridecrash/A.java ! test/tools/javac/overrridecrash/B.java ! test/tools/javac/p1/AS.java ! test/tools/javac/p1/BS.java ! test/tools/javac/p1/CS.java ! test/tools/javac/packone/Mediator.java ! test/tools/javac/packone/Secret.java ! test/tools/javac/policy/test1/A.java ! test/tools/javac/policy/test1/D.java ! test/tools/javac/policy/test1/Test1a.java ! test/tools/javac/policy/test1/Test1b.java ! test/tools/javac/policy/test2/A.java ! test/tools/javac/policy/test2/B.java ! test/tools/javac/policy/test2/Test.java ! test/tools/javac/policy/test3/Test.java ! test/tools/javac/positions/T6402077.java ! test/tools/javac/positions/T6404194.java ! test/tools/javac/processing/6348193/T6348193.java ! test/tools/javac/processing/6348499/A.java ! test/tools/javac/processing/6348499/T6348499.java ! test/tools/javac/processing/6350124/HelloWorldAP.java ! test/tools/javac/processing/6350124/Marked.java ! test/tools/javac/processing/6350124/Marker.java ! test/tools/javac/processing/6350124/T6350124.java ! test/tools/javac/processing/6359313/Foo.java ! test/tools/javac/processing/6359313/T6359313.java ! test/tools/javac/processing/6359313/package-info.java ! test/tools/javac/processing/6365040/ProcBar.java ! test/tools/javac/processing/6365040/ProcFoo.java ! test/tools/javac/processing/6365040/T6365040.java ! test/tools/javac/processing/6378728/T6378728.java ! test/tools/javac/processing/6413690/T6413690.java ! test/tools/javac/processing/6413690/TestMe.java ! test/tools/javac/processing/6413690/src/Super.java ! test/tools/javac/processing/6414633/A.java ! test/tools/javac/processing/6414633/T6414633.java ! test/tools/javac/processing/6430209/T6430209.java ! test/tools/javac/processing/6430209/b6341534.java ! test/tools/javac/processing/6430209/test0.java ! test/tools/javac/processing/6430209/test1.java ! test/tools/javac/processing/6499119/ClassProcessor.java ! test/tools/javac/processing/6499119/package-info.java ! test/tools/javac/processing/6511613/DummyProcessor.java ! test/tools/javac/processing/6511613/clss41701.java ! test/tools/javac/processing/6512707/T6512707.java ! test/tools/javac/processing/6512707/TestAnnotation.java ! test/tools/javac/processing/6512707/TestEnum.java ! test/tools/javac/processing/6634138/Dummy.java ! test/tools/javac/processing/6634138/ExerciseDependency.java ! test/tools/javac/processing/6634138/T6634138.java ! test/tools/javac/processing/T6439826.java ! test/tools/javac/processing/T6920317.java ! test/tools/javac/processing/Xprint.java ! test/tools/javac/processing/completion/TestCompletions.java ! test/tools/javac/processing/environment/HelloWorld.java ! test/tools/javac/processing/environment/TestSourceVersion.java ! test/tools/javac/processing/environment/round/AnnotatedElementInfo.java ! test/tools/javac/processing/environment/round/BuriedAnnotations.java ! test/tools/javac/processing/environment/round/C1.java ! test/tools/javac/processing/environment/round/C2.java ! test/tools/javac/processing/environment/round/Foo.java ! test/tools/javac/processing/environment/round/InheritedAnnotation.java ! test/tools/javac/processing/environment/round/Part1.java ! test/tools/javac/processing/environment/round/Part2.java ! test/tools/javac/processing/environment/round/SurfaceAnnotations.java ! test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java ! test/tools/javac/processing/errors/Foo.java ! test/tools/javac/processing/errors/TestFatalityOfParseErrors.java ! test/tools/javac/processing/errors/TestOptionSyntaxErrors.java ! test/tools/javac/processing/errors/TestReturnCode.java ! test/tools/javac/processing/filer/TestFilerConstraints.java ! test/tools/javac/processing/filer/TestGetResource.java ! test/tools/javac/processing/filer/TestPackageInfo.java ! test/tools/javac/processing/filer/foo/Foo.java ! test/tools/javac/processing/filer/foo/bar/FuBar.java ! test/tools/javac/processing/filer/foo/bar/package-info.java ! test/tools/javac/processing/messager/MessagerBasics.java ! test/tools/javac/processing/model/6194785/T6194785.java ! test/tools/javac/processing/model/6194785/T6194785a.java ! test/tools/javac/processing/model/6341534/T6341534.java ! test/tools/javac/processing/model/6341534/dir/Foo.java ! test/tools/javac/processing/model/6341534/dir/package-info.java ! test/tools/javac/processing/model/TestExceptions.java ! test/tools/javac/processing/model/element/TestAnonClassNames.java ! test/tools/javac/processing/model/element/TestAnonSourceNames.java ! test/tools/javac/processing/model/element/TestElement.java ! test/tools/javac/processing/model/element/TestNames.java ! test/tools/javac/processing/model/element/TestPackageElement.java ! test/tools/javac/processing/model/element/TypeParamBounds.java ! test/tools/javac/processing/model/testgetallmembers/Main.java ! test/tools/javac/processing/model/type/MirroredTypeEx/NpeTest.java ! test/tools/javac/processing/model/type/MirroredTypeEx/OverEager.java ! test/tools/javac/processing/model/type/NoTypes.java ! test/tools/javac/processing/model/type/TestTypeKind.java ! test/tools/javac/processing/model/util/BinaryName.java ! test/tools/javac/processing/model/util/GetTypeElemBadArg.java ! test/tools/javac/processing/model/util/NoSupers.java ! test/tools/javac/processing/model/util/OverridesSpecEx.java ! test/tools/javac/processing/model/util/Superless.java ! test/tools/javac/processing/model/util/TypesBadArg.java ! test/tools/javac/processing/model/util/deprecation/Dep1.java ! test/tools/javac/processing/model/util/deprecation/ExpectedDeprecation.java ! test/tools/javac/processing/model/util/deprecation/TestDeprecation.java ! test/tools/javac/processing/model/util/directSupersOfErr/C1.java ! test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java ! test/tools/javac/processing/model/util/elements/Foo.java ! test/tools/javac/processing/model/util/elements/TestGetConstantExpression.java ! test/tools/javac/processing/model/util/elements/TestGetPackageOf.java ! test/tools/javac/processing/model/util/elements/VacuousEnum.java ! test/tools/javac/processing/model/util/filter/ExpectedElementCounts.java ! test/tools/javac/processing/model/util/filter/Foo1.java ! test/tools/javac/processing/model/util/filter/TestIterables.java ! test/tools/javac/processing/warnings/HelloWorld.java ! test/tools/javac/processing/warnings/TestSourceVersionWarnings.java ! test/tools/javac/proprietary/WarnClass.java ! test/tools/javac/proprietary/WarnImport.java ! test/tools/javac/proprietary/WarnMethod.java ! test/tools/javac/proprietary/WarnStaticImport.java ! test/tools/javac/proprietary/WarnVariable.java ! test/tools/javac/proprietary/WarnWildcard.java ! test/tools/javac/protectedAccess/ProtectedAccess_1.java ! test/tools/javac/protectedAccess/ProtectedAccess_2.java ! test/tools/javac/protectedAccess/ProtectedAccess_3.java ! test/tools/javac/protectedAccess/ProtectedMemberAccess1.java ! test/tools/javac/protectedAccess/ProtectedMemberAccess5/Main.java ! test/tools/javac/protectedAccess/ProtectedMemberAccess5/z1/Z1.java ! test/tools/javac/protectedAccess/ProtectedMemberAccess5/z2/Z2.java ! test/tools/javac/protectedAccess/p/SuperClass.java ! test/tools/javac/protectedAccess/pkg/SuperClass.java ! test/tools/javac/protectedInner/AnonInnerClass.java ! test/tools/javac/protectedInner/InnerClass.java ! test/tools/javac/protectedInner/Outerclass.java ! test/tools/javac/protectedInner/mypackage/Superclass.java ! test/tools/javac/protectedInner/pkg1/Base.java ! test/tools/javac/protectedInner/pkg2/Sub.java ! test/tools/javac/quid/MakeNegTests.sh ! test/tools/javac/quid/QuotedIdent.java ! test/tools/javac/quid/QuotedIdent2.java ! test/tools/javac/rawDiags/Note.java ! test/tools/javac/scope/6225935/Bar.java ! test/tools/javac/scope/6225935/Baz.java ! test/tools/javac/scope/6225935/Estatico4.java ! test/tools/javac/scope/6225935/StaticImportAccess.java ! test/tools/javac/scope/6225935/T6214959.java ! test/tools/javac/scope/6225935/T6225935.java ! test/tools/javac/scope/6225935/T6381787.java ! test/tools/javac/scope/6225935/Test.java ! test/tools/javac/scope/6225935/a/Ambiguous.java ! test/tools/javac/scope/6225935/a/Named.java ! test/tools/javac/scope/6225935/a/Private.java ! test/tools/javac/scope/6225935/a/Star.java ! test/tools/javac/scope/6392998/T6392998.java ! test/tools/javac/sourcePath/SourcePath.java ! test/tools/javac/sourcePath/SourcePathA.java ! test/tools/javac/sourcePath2/SourcePath2.java ! test/tools/javac/sourcePath2/p/SourcePath2A.java ! test/tools/javac/stackmap/T4955930.java ! test/tools/javac/stackmap/T4955930.sh ! test/tools/javac/stackmap/UninitThis.java ! test/tools/javac/staticImport/6665223/T6665223.java ! test/tools/javac/staticImport/6665223/pkg/A.java ! test/tools/javac/staticImport/6665223/pkg/B.java ! test/tools/javac/staticImport/6695838/T6695838.java ! test/tools/javac/staticImport/6695838/a/Foo.java ! test/tools/javac/staticImport/6695838/a/FooInterface.java ! test/tools/javac/staticImport/Ambig1.java ! test/tools/javac/staticImport/ImportInherit.java ! test/tools/javac/staticImport/ImportPrivate.java ! test/tools/javac/staticImport/PrivateStaticImport.java ! test/tools/javac/staticImport/Shadow.java ! test/tools/javac/staticImport/StaticImport.java ! test/tools/javac/staticImport/StaticImport2.java ! test/tools/javac/staticQualifiedNew/StaticQualifiedNew.java ! test/tools/javac/staticQualifiedNew/p2/X.java ! test/tools/javac/synthesize/Boolean.java ! test/tools/javac/synthesize/Byte.java ! test/tools/javac/synthesize/Character.java ! test/tools/javac/synthesize/Cloneable.java ! test/tools/javac/synthesize/Integer.java ! test/tools/javac/synthesize/Long.java ! test/tools/javac/synthesize/Main.java ! test/tools/javac/synthesize/Number.java ! test/tools/javac/synthesize/Object.java ! test/tools/javac/synthesize/Serializable.java ! test/tools/javac/synthesize/Short.java ! test/tools/javac/synthesize/Test.java ! test/tools/javac/synthesize/Void.java ! test/tools/javac/tree/T6923080.java ! test/tools/javac/tree/TestAnnotatedAnonClass.java ! test/tools/javac/tree/TreePosTest.java ! test/tools/javac/tree/TreeScannerTest.java ! test/tools/javac/treeannotests/AnnoTreeTests.java ! test/tools/javac/treeannotests/DA.java ! test/tools/javac/treeannotests/TA.java ! test/tools/javac/treeannotests/Test.java ! test/tools/javac/treeannotests/TestProcessor.java ! test/tools/javac/typeAnnotations/InnerClass.java ! test/tools/javac/typeAnnotations/MultipleTargets.java ! test/tools/javac/typeAnnotations/TypeParameterTarget.java ! test/tools/javac/typeAnnotations/TypeUseTarget.java ! test/tools/javac/typeAnnotations/attribution/Scopes.java ! test/tools/javac/typeAnnotations/classfile/DeadCode.java ! test/tools/javac/typeAnnotations/failures/OldArray.java ! test/tools/javac/typeAnnotations/failures/VoidGenericMethod.java ! test/tools/javac/typeAnnotations/newlocations/BasicTest.java ! test/tools/javac/typeAnnotations/newlocations/ClassExtends.java ! test/tools/javac/typeAnnotations/newlocations/ClassLiterals.java ! test/tools/javac/typeAnnotations/newlocations/ClassParameters.java ! test/tools/javac/typeAnnotations/newlocations/ConstructorTypeArgs.java ! test/tools/javac/typeAnnotations/newlocations/Expressions.java ! test/tools/javac/typeAnnotations/newlocations/Fields.java ! test/tools/javac/typeAnnotations/newlocations/LocalVariables.java ! test/tools/javac/typeAnnotations/newlocations/MethodReturnType.java ! test/tools/javac/typeAnnotations/newlocations/MethodTypeArgs.java ! test/tools/javac/typeAnnotations/newlocations/MethodTypeParameters.java ! test/tools/javac/typeAnnotations/newlocations/Parameters.java ! test/tools/javac/typeAnnotations/newlocations/Receivers.java ! test/tools/javac/typeAnnotations/newlocations/Throws.java ! test/tools/javac/typeAnnotations/newlocations/TypeCasts.java ! test/tools/javac/typeAnnotations/newlocations/TypeParameters.java ! test/tools/javac/typeAnnotations/newlocations/Wildcards.java ! test/tools/javac/unicode/FirstChar.java ! test/tools/javac/unicode/FirstChar2.java ! test/tools/javac/unicode/NonasciiDigit.java ! test/tools/javac/unicode/NonasciiDigit2.java ! test/tools/javac/unicode/SubChar.java ! test/tools/javac/unicode/SupplementaryJavaID1.java ! test/tools/javac/unicode/SupplementaryJavaID2.java ! test/tools/javac/unicode/SupplementaryJavaID3.java ! test/tools/javac/unicode/SupplementaryJavaID4.java ! test/tools/javac/unicode/SupplementaryJavaID5.java ! test/tools/javac/unicode/SupplementaryJavaID6.java ! test/tools/javac/unicode/SupplementaryJavaID6.sh ! test/tools/javac/unicode/TripleQuote.java ! test/tools/javac/unicode/UnicodeAtEOL.java ! test/tools/javac/unicode/UnicodeCommentDelimiter.java ! test/tools/javac/unicode/UnicodeUnicode.java ! test/tools/javac/unicode/Unmappable.java ! test/tools/javac/unit/T6198196.java ! test/tools/javac/unit/util/convert/EnclosingCandidates.java ! test/tools/javac/unit/util/list/AbstractList.java ! test/tools/javac/unit/util/list/FromArray.java ! test/tools/javac/util/filemanager/TestName.java ! test/tools/javac/util/list/TList.java ! test/tools/javac/varargs/6730476/T6730476a.java ! test/tools/javac/varargs/6730476/T6730476b.java ! test/tools/javac/varargs/Anon.java ! test/tools/javac/varargs/BadSyntax2.java ! test/tools/javac/varargs/T6746184.java ! test/tools/javac/varargs/Varargs1.java ! test/tools/javac/varargs/VarargsOverride.java ! test/tools/javac/varargs/Warn1.java ! test/tools/javac/varargs/Warn2.java ! test/tools/javac/varargs/warning/Warn1.java ! test/tools/javac/varargs/warning/Warn2.java ! test/tools/javac/varargs/warning/Warn3.java ! test/tools/javac/versions/CheckClassFileVersion.java ! test/tools/javac/versions/check.sh ! test/tools/javac/warnings/DepAnn.java ! test/tools/javac/warnings/Finally.java ! test/tools/javac/warnings/Serial.java ! test/tools/javac/warnings/T6763518.java ! test/tools/javadoc/6176978/T6176978.java ! test/tools/javadoc/6176978/X.java ! test/tools/javadoc/BooleanConst.java ! test/tools/javadoc/BreakIteratorWarning.java ! test/tools/javadoc/FlagsTooEarly.java ! test/tools/javadoc/InlineTagsWithBraces.java ! test/tools/javadoc/LangVers.java ! test/tools/javadoc/MethodLinks.java ! test/tools/javadoc/NoStar.java ! test/tools/javadoc/T4994049/FileWithTabs.java ! test/tools/javadoc/T4994049/T4994049.java ! test/tools/javadoc/XWerror.java ! test/tools/javadoc/annotations/annotateMethodsFields/Main.java ! test/tools/javadoc/annotations/annotateMethodsFields/pkg1/A.java ! test/tools/javadoc/annotations/annotateMethodsFields/pkg1/B.java ! test/tools/javadoc/annotations/annotateMethodsFields/pkg1/E.java ! test/tools/javadoc/annotations/annotatePackage/Main.java ! test/tools/javadoc/annotations/annotatePackage/pkg1/A.java ! test/tools/javadoc/annotations/annotatePackage/pkg1/package-info.java ! test/tools/javadoc/annotations/annotatePackage/pkg2/B.java ! test/tools/javadoc/annotations/annotateParams/Main.java ! test/tools/javadoc/annotations/annotateParams/pkg1/A.java ! test/tools/javadoc/annotations/annotateParams/pkg1/C.java ! test/tools/javadoc/annotations/badVals/Main.java ! test/tools/javadoc/annotations/badVals/pkg1/A.java ! test/tools/javadoc/annotations/defaults/Main.java ! test/tools/javadoc/annotations/defaults/pkg1/A.java ! test/tools/javadoc/annotations/defaults/pkg1/B.java ! test/tools/javadoc/annotations/elementTypes/Main.java ! test/tools/javadoc/annotations/elementTypes/pkg1/A.java ! test/tools/javadoc/annotations/elementTypes/pkg1/B.java ! test/tools/javadoc/annotations/missing/Main.java ! test/tools/javadoc/annotations/missing/somepackage/MissingAnnotationClass.java ! test/tools/javadoc/annotations/shortcuts/Main.java ! test/tools/javadoc/annotations/shortcuts/pkg1/A.java ! test/tools/javadoc/annotations/shortcuts/pkg1/Array.java ! test/tools/javadoc/annotations/shortcuts/pkg1/Marker.java ! test/tools/javadoc/annotations/shortcuts/pkg1/Value.java ! test/tools/javadoc/badSuper/BadSuper.java ! test/tools/javadoc/badSuper/p/A.java ! test/tools/javadoc/badSuper/p/B.java ! test/tools/javadoc/completionFailure/CompletionFailure.java ! test/tools/javadoc/completionFailure/pkg/A.java ! test/tools/javadoc/completionFailure/pkg/B.java ! test/tools/javadoc/dupOk/DupOk.java ! test/tools/javadoc/dupOk/sp1/p/A.java ! test/tools/javadoc/dupOk/sp2/p/A.java ! test/tools/javadoc/dupOk/sp2/p/B.java ! test/tools/javadoc/enum/docComments/Main.java ! test/tools/javadoc/enum/docComments/pkg1/Operation.java ! test/tools/javadoc/enum/enumType/Main.java ! test/tools/javadoc/enum/enumType/pkg1/QuotablePerson.java ! test/tools/javadoc/generics/genericClass/Main.java ! test/tools/javadoc/generics/genericClass/pkg1/A.java ! test/tools/javadoc/generics/genericInnerAndOuter/Main.java ! test/tools/javadoc/generics/genericInnerAndOuter/pkg1/O.java ! test/tools/javadoc/generics/genericInnerAndOuter/pkg1/X.java ! test/tools/javadoc/generics/genericInterface/Main.java ! test/tools/javadoc/generics/genericInterface/pkg1/A.java ! test/tools/javadoc/generics/genericMethod/Main.java ! test/tools/javadoc/generics/genericMethod/pkg1/A.java ! test/tools/javadoc/generics/genericSuper/Main.java ! test/tools/javadoc/generics/genericSuper/pkg1/A.java ! test/tools/javadoc/generics/supertypes/Main.java ! test/tools/javadoc/generics/supertypes/pkg1/A.java ! test/tools/javadoc/generics/supertypes/pkg1/B.java ! test/tools/javadoc/generics/throwsGeneric/Main.java ! test/tools/javadoc/generics/throwsGeneric/pkg1/A.java ! test/tools/javadoc/generics/tparamCycle/Main.java ! test/tools/javadoc/generics/tparamCycle/pkg1/LikeEnum.java ! test/tools/javadoc/generics/tparamTagOnMethod/Main.java ! test/tools/javadoc/generics/tparamTagOnMethod/pkg1/A.java ! test/tools/javadoc/generics/tparamTagOnType/Main.java ! test/tools/javadoc/generics/tparamTagOnType/pkg1/A.java ! test/tools/javadoc/generics/wildcards/Main.java ! test/tools/javadoc/generics/wildcards/pkg1/A.java ! test/tools/javadoc/imports/I.java ! test/tools/javadoc/imports/MissingImport.java ! test/tools/javadoc/lib/Tester.java ! test/tools/javadoc/nestedClass/NestedClass.java ! test/tools/javadoc/nestedClass/NestedClassB.java ! test/tools/javadoc/outputRedirect/Test.java ! test/tools/javadoc/outputRedirect/p/OutputRedirect.java ! test/tools/javadoc/sourceOnly/Test.java ! test/tools/javadoc/sourceOnly/p/SourceOnly.java ! test/tools/javadoc/sourceOption/SourceOption.java ! test/tools/javadoc/sourceOption/p/A.java ! test/tools/javadoc/subpackageIgnore/SubpackageIgnore.java ! test/tools/javadoc/subpackageIgnore/pkg1/not-subpkg/SomeJavaFile.java ! test/tools/javadoc/varArgs/Main.java ! test/tools/javadoc/varArgs/pkg1/A.java ! test/tools/javah/6257087/foo.java ! test/tools/javah/6257087/foo.sh ! test/tools/javah/6572945/T6572945.java ! test/tools/javah/6572945/TestClass1.java ! test/tools/javah/6572945/TestClass2.java ! test/tools/javah/6572945/TestClass3.java ! test/tools/javah/ConstMacroTest.sh ! test/tools/javah/MissingParamClassException.java ! test/tools/javah/MissingParamClassTest.sh ! test/tools/javah/ParamClassTest.java ! test/tools/javah/ReadOldClass.sh ! test/tools/javah/SubClassConsts.java ! test/tools/javah/SuperClassConsts.java ! test/tools/javah/T5070898.java ! test/tools/javah/T6893943.java ! test/tools/javah/compareTest/CompareTest.java ! test/tools/javah/compareTest/CompareTest.sh ! test/tools/javah/compareTest/FindNativeFiles.java ! test/tools/javap/4111861/T4111861.java ! test/tools/javap/4870651/T4870651.java ! test/tools/javap/4870651/Test.java ! test/tools/javap/6937244/T6937244.java ! test/tools/javap/6937244/T6937244A.java ! test/tools/javap/ExtPath.java ! test/tools/javap/NotPackagePrivateInterface.java ! test/tools/javap/PublicInterfaceTest.sh ! test/tools/javap/T4075403.java ! test/tools/javap/T4459541.java ! test/tools/javap/T4501660.java ! test/tools/javap/T4501661.java ! test/tools/javap/T4777949.java ! test/tools/javap/T4876942.java ! test/tools/javap/T4880663.java ! test/tools/javap/T4880672.java ! test/tools/javap/T4884240.java ! test/tools/javap/T4975569.java ! test/tools/javap/T6271787.java ! test/tools/javap/T6474890.java ! test/tools/javap/T6587786.java ! test/tools/javap/T6622216.java ! test/tools/javap/T6622232.java ! test/tools/javap/T6622260.java ! test/tools/javap/T6715251.java ! test/tools/javap/T6715753.java ! test/tools/javap/T6715767.java ! test/tools/javap/T6716452.java ! test/tools/javap/T6729471.java ! test/tools/javap/T6824493.java ! test/tools/javap/T6863746.java ! test/tools/javap/T6866657.java ! test/tools/javap/T6868539.java ! test/tools/javap/T6879371.java ! test/tools/javap/classfile/6888367/T6888367.java ! test/tools/javap/classfile/T6887895.java ! test/tools/javap/classfile/deps/GetDeps.java ! test/tools/javap/classfile/deps/T6907575.java ! test/tools/javap/classfile/deps/p/C1.java ! test/tools/javap/pathsep.sh ! test/tools/javap/stackmap/T6271292.java ! test/tools/javap/stackmap/T6271292.sh ! test/tools/javap/typeAnnotations/ArrayClassLiterals.java ! test/tools/javap/typeAnnotations/ArrayClassLiterals2.java ! test/tools/javap/typeAnnotations/ClassLiterals.java ! test/tools/javap/typeAnnotations/JSR175Annotations.java ! test/tools/javap/typeAnnotations/NewArray.java ! test/tools/javap/typeAnnotations/Presence.java ! test/tools/javap/typeAnnotations/PresenceInner.java ! test/tools/javap/typeAnnotations/T6855990.java ! test/tools/javap/typeAnnotations/Visibility.java Changeset: 752bb790fc2d Author: ohair Date: 2010-05-26 10:40 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/752bb790fc2d Merge Changeset: 637c646c6412 Author: mikejwre Date: 2010-05-27 10:57 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/637c646c6412 Added tag jdk7-b95 for changeset 752bb790fc2d ! .hgtags Changeset: 593a59e40bdb Author: lana Date: 2010-05-28 12:41 -0700 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/593a59e40bdb Merge ! src/share/classes/com/sun/tools/javac/code/Types.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/Check.java From iaroslavski at mail.ru Mon May 31 12:52:16 2010 From: iaroslavski at mail.ru (Vladimir Iaroslavski) Date: Mon, 31 May 2010 16:52:16 +0400 Subject: New portion of improvements for Dual-Pivot Quicksort In-Reply-To: References: <4BF2AAEE.1040706@mail.ru> <4BF3BFFD.8010007@mail.ru> <4BF3C05C.7010300@mail.ru> <4BF69AFB.8060406@mail.ru> <4BFB716B.4020107@mail.ru> Message-ID: <4C03B100.6080809@mail.ru> Josh, Do you have any comments on last version of Dual-Pivot Quicksort? Is the implementation ready for integration? Vladimir Dmytro Sheyko wrote: > Hi Vladimir, > > As for me, everything seems good. > > Returning to the theoretical background, could you estimate number of > comparison and assignments? These should be less than in your initial > version. > > Also have you considered 7-comparison sort for sorting 5 pivot > candidates instead of 9-comparison sorting network? > > Thank you, > Dmytro Sheyko > > > Date: Tue, 25 May 2010 10:42:51 +0400 > > From: iaroslavski at mail.ru > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > To: dmytro_sheyko at hotmail.com > > CC: core-libs-dev at openjdk.java.net > > > > I added more comments, please, review attached version. > > > > >> So, we win 2-3% ! > > > > On [partial] sorted inputs new version runs more faster than few > percents: > > > > organ pipes > > this: 6896 > > prev: 7424 > > jdk7: 8018 > > jdk6: 12502 > > > > ascendant > > this: 2877 > > prev: 3845 > > jdk7: 4583 > > jdk6: 9019 > > > > descendant > > this: 3287 > > prev: 4110 > > jdk7: 4897 > > jdk6: 9132 > > > > Dmytro Sheyko wrote: > > > That's great! Thank you. > > > > > > > Date: Fri, 21 May 2010 18:38:51 +0400 > > > > From: iaroslavski at mail.ru > > > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > > > To: dmytro_sheyko at hotmail.com > > > > CC: core-libs-dev at openjdk.java.net > > > > > > > > Hello, > > > > > > > > I prepared version with your changes "Skip the last negative > > > > value (if any) or all leading negative" and with my optimization > > > > for all types. I added two while loops before partitioning to > > > > skip elements, less than pivot1 and greater than pivot2: > > > > > > > > if (pivot1 != pivot2) { > > > > /* ... */ > > > > a[e2] = a[less]; > > > > a[e4] = a[great]; > > > > > > > > ++ while (a[++less] < pivot1); > > > > ++ while (a[--great] > pivot2); > > > > > > > > /* ... */ > > > > outer: > > > > for (int k = less; k <= great; k++) { > > > > ... > > > > } > > > > > > > > Here is benchmark result (in compare with quicksort from JDK 6): > > > > > > > > client server > > > > ------ ------ > > > > previous version: 60.70% 48.20% > > > > current version: 57.22% 46.18% > > > > > > > > So, we win 2-3% ! > > > > > > > > Thank you, > > > > Vladimir > > > > > > > > Dmytro Sheyko wrote: > > > > > Hi Vladimir, > > > > > > > > > > I tried to figure out why the testcase failed on my > modification. It > > > > > appeared that number of negative zeros were changed during general > > > sort. > > > > > As I can see you already fixed this issue. Well, my > modification was > > > > > based on assumption that we can speed up eliminating explicit array > > > > > range checks. > > > > > However, such assumption is wrong because Hotspot anyway emits > range > > > > > checks at its discretion and therefore processZeros generally > does not > > > > > work as fast as I expected. > > > > > So complications I made are not worth doing. > > > > > > > > > > As for the latest code you posted. Doesn't it make sense to skip > > > leading > > > > > negative zeros before farther processing? In this case we avoid > > > > > unnecessary assigning +0.0 and then -0.0 to the same location a[k] > > > (i.e. > > > > > where k == p). > > > > > > > > > > /* > > > > > * Skip the last negative value (if any) or all leading negative > > > > > zeros > > > > > */ > > > > > while (left <= right && Double.doubleToRawLongBits(a[left]) < 0) { > > > > > left++; > > > > > } > > > > > > > > > > for (int k = left + 1, p = left; k <= right; k++) { > > > > > double ak = a[k]; > > > > > if (ak != 0.0d) { > > > > > return; > > > > > } > > > > > if (Double.doubleToRawLongBits(ak) < 0) { // ak is -0.0d > > > > > a[k] = 0.0d; > > > > > a[p++] = -0.0d; > > > > > } > > > > > } > > > > > > > > > > Thank you, > > > > > Dmytro Sheyko > > > > > > > > > > > > > > > > Date: Wed, 19 May 2010 14:41:32 +0400 > > > > > > From: iaroslavski at mail.ru > > > > > > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > > > > > > To: dmytro_sheyko at hotmail.com > > > > > > CC: core-libs-dev at openjdk.java.net > > > > > > > > > > > > resend the class with correct constructor > > > > > > > > > > > > Vladimir Iaroslavski wrote: > > > > > > > Dmytro, > > > > > > > > > > > > > > Thank you for comments, I updated double method, did little bit > > > > > > > javadoc changes and replaced in char/short/byte methods > > > > > > > "fromIndex -> left", "toIndex-1 -> right", the code became > > > > > > > consistent with main sort method and more compact. Also I use > > > > > > > more usual "i--" and "i++" in for loops (instead of "--i", > "++i. > > > > > > > > > > > > > > To accent the difference between float/double and other types, > > > > > > > I put comment where it is important: > > > > > > > > > > > > > > /* > > > > > > > * In spite of a[great] == pivot1, the assignment > > > > > > > * a[less++] = pivot1 may be incorrect, if a[great] > > > > > > > * and pivot1 are floating-point zeros of different > > > > > > > * signs, therefore in float/double methods we have > > > > > > > * to use more accurate assignment a[k] = a[great]. > > > > > > > */ > > > > > > > a[less++] = pivot1; > > > > > > > > > > > > > > and for double/float: > > > > > > > > > > > > > > /* > > > > > > > ..... > > > > > > > */ > > > > > > > a[k] = a[great]; > > > > > > > > > > > > > > See updated version in attachment. > > > > > > > > > > > > > > Thank you, > > > > > > > Vladimir > > > > > > > > > > > > > > Dmytro Sheyko wrote: > > > > > > >> Vladimir, > > > > > > >> > > > > > > >> I can see that you changed sortNegZeroAndNaN(float[]...) but > > > probably > > > > > > >> forgot to change sortNegZeroAndNaN(double[]...). > > > > > > >> > > > > > > >> You really puzzled me with failed testcase and note that > sorting > > > > > > >> algorithm (without special attention to zeros) generally may > > > change > > > > > > >> number of negative zeros. > > > > > > >> I will provide my comments later. > > > > > > >> > > > > > > >> As for counting sort, I think we should use single format > > > style over > > > > > > >> the file (unless we have valuable reason not to do this). I > > > mean to > > > > > > >> choose > > > > > > >> 1) > > > > > > >> if (toIndex - fromIndex > > > > > > > >> COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > > > > > > >> countingSort(a, fromIndex, toIndex); > > > > > > >> return; > > > > > > >> } > > > > > > >> sort(a, fromIndex, toIndex - 1, true); > > > > > > >> 2) > > > > > > >> if (toIndex - fromIndex > > > > > > > >> COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { > > > > > > >> countingSort(a, fromIndex, toIndex); > > > > > > >> } else { > > > > > > >> sort(a, fromIndex, toIndex - 1, true); > > > > > > >> } > > > > > > >> I prefer the second one. > > > > > > >> > > > > > > >> Thanks a lot, > > > > > > >> Dmytro Sheyko > > > > > > >> > > > > > > >> > Date: Tue, 18 May 2010 18:57:50 +0400 > > > > > > >> > From: iaroslavski at mail.ru > > > > > > >> > Subject: Re: New portion of improvements for Dual-Pivot > > > Quicksort > > > > > > >> > To: dmytro_sheyko at hotmail.com > > > > > > >> > CC: core-libs-dev at openjdk.java.net > > > > > > >> > > > > > > > >> > Hello, > > > > > > >> > > > > > > > >> > I've run your modification for counting sort, it real > faster. > > > > > > >> > I attached new version with your changes (I did little bit > > > > > > >> > format it) and included my case with float/double. > > > > > > >> > > > > > > > >> > Note that you modification doesn't pass test from > Sorting class, > > > > > > >> > which I sent earlier. It fails on float/double test: > > > > > > >> > > > > > > > >> > Test #3: random = 666, len = 34, a = 0, g = 6, z = 9, n = > > > 10, p = 9 > > > > > > >> > > > > > > > >> > I suggest shorter method (which is based on your idea to > skip > > > > > counting > > > > > > >> > negative zeros on Phase 1.): I found find first zero > index (or > > > > > it will > > > > > > >> > be index of first positive element if no zeros at all, > or last > > > > > > >> negative, > > > > > > >> > if no positive and zero elements) and then swap negative > > > zero to the > > > > > > >> > beginning of the sub-range. > > > > > > >> > > > > > > > >> > int hi = right; > > > > > > >> > > > > > > > >> > while (left < hi) { > > > > > > >> > int middle = (left + hi) >>> 1; > > > > > > >> > float middleValue = a[middle]; > > > > > > >> > > > > > > > >> > if (middleValue < 0.0f) { > > > > > > >> > left = middle + 1; > > > > > > >> > } else { > > > > > > >> > hi = middle; > > > > > > >> > } > > > > > > >> > } > > > > > > >> > > > > > > > >> > for (int k = left, p = left; k <= right; k++) { > > > > > > >> > float ak = a[k]; > > > > > > >> > if (ak != 0.0f) { > > > > > > >> > return; > > > > > > >> > } > > > > > > >> > if (Float.floatToRawIntBits(ak) < 0) { // ak is -0.0f > > > > > > >> > a[k] = +0.0f; > > > > > > >> > a[p++] = -0.0f; > > > > > > >> > } > > > > > > >> > } > > > > > > >> > > > > > > > >> > Important note: in partitioning loop there are several > places > > > > > > >> > (marked by // !) where potential bug with -0.0 could be > > > > > > >> > (when pivot and a[great] are zeros with different signs): > > > > > > >> > > > > > > > >> > if (a[great] == pivot1) { > > > > > > >> > a[k] = a[less]; > > > > > > >> > - a[less++] = pivot1; // ! > > > > > > >> > + a[less++] = a[great]; > > > > > > >> > } else { // pivot1 < a[great] < pivot2 > > > > > > >> > a[k] = a[great]; > > > > > > >> > } > > > > > > >> > - a[great--] = pivot2; // ! > > > > > > >> > + a[great--] = ak; > > > > > > >> > } else if (ak == pivot1) { // Move a[k] to left part > > > > > > >> > a[k] = a[less]; > > > > > > >> > - a[less++] = pivot1; // ! > > > > > > >> > + a[less++] = ak; > > > > > > >> > } > > > > > > >> > > > > > > > >> > and the same in "Pivots are equal" branch. > > > > > > >> > > > > > > > >> > I did changes "pivot1/2 -> ak" in methods for all types > > > > > > >> > and "pivot1 -> a[great]" in float/double sections only. > > > > > > >> > > > > > > > >> > Please, review format changes for counting sort and new > version > > > > > > >> > of Phase 3 for float/double. > > > > > > >> > > > > > > > >> > Thank you, > > > > > > >> > Vladimir > > > > > > >> > > > > > > > >> > Dmytro Sheyko wrote: > > > > > > >> > > Hi, > > > > > > >> > > > > > > > > >> > > About counting sort again. > > > > > > >> > > > > > > > > >> > > 1. This condition "i < count.length && k <= right" is > > > excessive. > > > > > > >> Any one > > > > > > >> > > conjunct is enough. "k <= right" seems better. > > > > > > >> > > 2. No need to calculate "short value = (short) (i + > > > > > > >> Short.MIN_VALUE)" > > > > > > >> > > when "count[i]" is zero. > > > > > > >> > > 3. For signed primitives (byte and short) we would > better loop > > > > > > >> backward. > > > > > > >> > > Thanks to "k >= fromIndex" condition we will quit looping > > > earlier > > > > > > >> > > assuming that typically we work with positive numbers. > > > > > > >> > > For unsigned primitives (char) we would better loop > forward > > > > > because > > > > > > >> > > typically we work with characters about zero (ASCII). > > > > > > >> > > > > > > > > >> > > - for (int i = 0, k = left; i < count.length && k <= > > > right; i++) { > > > > > > >> > > - short value = (short) (i + Short.MIN_VALUE); > > > > > > >> > > - for (int s = count[i]; s > 0; s--) { > > > > > > >> > > - a[k++] = value; > > > > > > >> > > - } > > > > > > >> > > - } > > > > > > >> > > > > > > > > >> > > + for (int i = NUM_SHORT_VALUES - 1, k = toIndex - 1; k >= > > > > > > >> > > fromIndex; --i) { > > > > > > >> > > + while (count[i] == 0) --i; > > > > > > >> > > + short value = (short) (i + Short.MIN_VALUE); > > > > > > >> > > + int s = count[i]; > > > > > > >> > > + do { a[k--] = value; } while (--s > 0); > > > > > > >> > > + } > > > > > > >> > > > > > > > > >> > > Thanks, > > > > > > >> > > Dmytro Sheyko > > > > > > >> > > > > > > > > >> > > > From: iaroslavski at mail.ru > > > > > > >> > > > To: dmytro_sheyko at hotmail.com > > > > > > >> > > > CC: core-libs-dev at openjdk.java.net; iaroslavski at mail.ru > > > > > > >> > > > Subject: Re[2]: New portion of improvements for > Dual-Pivot > > > > > > >> Quicksort > > > > > > >> > > > Date: Tue, 18 May 2010 01:11:19 +0400 > > > > > > >> > > > > > > > > > >> > > > Sounds good! > > > > > > >> > > > Will consider too... > > > > > > >> > > > > > > > > > >> > > > Mon, 17 May 2010 22:24:11 +0700 ?????? ?? Dmytro Sheyko > > > > > > >> > > : > > > > > > >> > > > > > > > > > >> > > > > Hi, > > > > > > >> > > > > > > > > > > >> > > > > Regarding counting sort. We can check whether we > should > > > > > > >> switch to > > > > > > >> > > counting sort only once in the beginning. > > > > > > >> > > > > > > > > > > >> > > > > > Date: Mon, 17 May 2010 17:30:37 +0400 > > > > > > >> > > > > > From: iaroslavski at mail.ru > > > > > > >> > > > > > Subject: Re: New portion of improvements for > Dual-Pivot > > > > > > >> Quicksort > > > > > > >> > > > > > To: dmytro_sheyko at hotmail.com > > > > > > >> > > > > > CC: core-libs-dev at openjdk.java.net > > > > > > >> > > > > > > > > > > > >> > > > > > Hello, > > > > > > >> > > > > > > > > > > > >> > > > > > Thank you for review, I'll check and run tests again > > > > > with you > > > > > > >> > > changes. > > > > > > >> > > > > > > > > > > > >> > > > > > Thank you, > > > > > > >> > > > > > Vladimir > > > > > > >> > > > > > > > > > > > >> > > > > > Dmytro Sheyko wrote: > > > > > > >> > > > > > > Hello, > > > > > > >> > > > > > > > > > > > > >> > > > > > > More ideas. > > > > > > >> > > > > > > > > > > > > >> > > > > > > 1. We can use > > > > > > >> > > > > > > Double.doubleToRawLongBits instead of > > > > > > >> Double.doubleToLongBits and > > > > > > >> > > > > > > Float.floatToRawIntBits instead of > > > Float.floatToIntBits. > > > > > > >> > > > > > > No need to handle NaN's because they all are > placed to > > > > > > >> the end > > > > > > >> > > of array. > > > > > > >> > > > > > > > > > > > > >> > > > > > > 2. Note that > > > > > > >> > > > > > > Double.doubleToRawLongBits(+0.0) == 0L and > > > > > > >> > > > > > > Double.doubleToRawLongBits(-0.0) == > Long.MIN_VALUE and > > > > > > >> > > > > > > Float.floatToRawIntBits(+0.0) == 0 and > > > > > > >> > > > > > > Float.floatToRawIntBits(-0.0) == > Integer.MIN_VALUE. > > > > > > >> > > > > > > > > > > > > >> > > > > > > Comparing with is zero usually more efficient > (or at > > > > > > >> least not > > > > > > >> > > worse) > > > > > > >> > > > > > > than with other values. Thus such pattern > > > > > > >> > > > > > > > > > > > > >> > > > > > > if (ak == 0.0f && NEGATIVE_ZERO == > > > > > Float.floatToIntBits(ak)) > > > > > > >> > > > > > > > > > > > > >> > > > > > > can be replaced with > > > > > > >> > > > > > > > > > > > > >> > > > > > > if (ak == 0.0f && Float.floatToIntBits(ak) < 0) > > > > > > >> > > > > > > > > > > > > >> > > > > > > 3. It would be more efficient to count > negative zeros > > > > > after > > > > > > >> > > sorting. > > > > > > >> > > > > > > General sorting algorithm puts both negative and > > > positive > > > > > > >> zeros > > > > > > >> > > together > > > > > > >> > > > > > > (but maybe not in right order). > > > > > > >> > > > > > > Therefore we have to process less elements because > > > > > > >> usually we > > > > > > >> > > have less > > > > > > >> > > > > > > zeros than other numbers. > > > > > > >> > > > > > > > > > > > > >> > > > > > > Thanks, > > > > > > >> > > > > > > Dmytro Sheyko > > > > > > >> > > > > > > > > > > > > >> > > > > > > > From: iaroslavski at mail.ru > > > > > > >> > > > > > > > To: dmytro_sheyko at hotmail.com; jjb at google.com > > > > > > >> > > > > > > > CC: core-libs-dev at openjdk.java.net; > > > iaroslavski at mail.ru > > > > > > >> > > > > > > > Subject: Re[6]: New portion of improvements for > > > > > Dual-Pivot > > > > > > >> > > Quicksort > > > > > > >> > > > > > > > Date: Fri, 14 May 2010 23:54:06 +0400 > > > > > > >> > > > > > > > > > > > > > >> > > > > > > > Hello, > > > > > > >> > > > > > > > > > > > > > >> > > > > > > > I've updated the class, please, review the > changes. > > > > > > >> > > > > > > > > > > > > > >> > > > > > > > Vladimir > > > > > > >> > > > > > > > > > > > > > >> > > > > > > > Fri, 14 May 2010 01:48:11 +0700 ?????? ?? > Dmytro > > > Sheyko > > > > > > >> > > > > > > : > > > > > > >> > > > > > > > > > > > > > >> > > > > > > > > Yes. I prefer F (Find First zero using binary > > > search) > > > > > > >> over > > > > > > >> > > C (Count > > > > > > >> > > > > > > negatives) and S (Smart Scan for zero). > > > > > > >> > > > > > > > > > > > > > > >> > > > > > > > > > From: iaroslavski at mail.ru > > > > > > >> > > > > > > > > > To: dmytro_sheyko at hotmail.com > > > > > > >> > > > > > > > > > CC: jjb at google.com; > > > core-libs-dev at openjdk.java.net; > > > > > > >> > > > > > > iaroslavski at mail.ru > > > > > > >> > > > > > > > > > Subject: Re[4]: New portion of > improvements for > > > > > > >> > > Dual-Pivot Quicksort > > > > > > >> > > > > > > > > > Date: Thu, 13 May 2010 21:34:54 +0400 > > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > Dmytro, > > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > I've tested your suggested variants, and > > > found that > > > > > > >> case "C" > > > > > > >> > > > > > > > > > (very interesting approach to find first > > > position > > > > > > >> of zero > > > > > > >> > > > > > > > > > by counting negative elements) works > slower than > > > > > > >> original > > > > > > >> > > > > > > > > > or two other cases. > > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > Implementations "F" and "S" are very close > > > to each > > > > > > >> other > > > > > > >> > > > > > > > > > and little bit faster than original. I > > > prefer case > > > > > > >> "F": > > > > > > >> > > > > > > > > > it is shorter and more clear. Do you agree? > > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > I'll prepare updated DualPivotQuicksort > file and > > > > > > >> send it > > > > > > >> > > > > > > > > > tomorrow. > > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > Thank you, > > > > > > >> > > > > > > > > > Vladimir > > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > Wed, 12 May 2010 17:04:52 +0700 ?????? > ?? Dmytro > > > > > > >> Sheyko > > > > > > >> > > > > > > : > > > > > > >> > > > > > > > > > > > > > > > >> > > > > > > > > > > Vladimir, > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > Your changes are good for me. > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > Additionally I have some > comments/proposals > > > > > > >> regarding > > > > > > >> > > dealing > > > > > > >> > > > > > > with negative zeros. > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > 1. Scanning for the first zero we can > > > avoid range > > > > > > >> check > > > > > > >> > > (i >= > > > > > > >> > > > > > > left) if we have at least one negative value. > > > > > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > > > > > 09:04:19 2010 > > > > > > >> > > > > > > > > > > +++ DualPivotQuicksortS.java Wed May 12 > > > 12:10:46 > > > > > > >> 2010 > > > > > > >> > > > > > > > > > > @@ -1705,10 +1705,15 @@ > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > > > > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > >> > > > > > > > > > > + int zeroIndex = 0; > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > - for (int i = zeroIndex - 1; i >= > left && > > > a[i] == > > > > > > >> > > 0.0f; i--) { > > > > > > >> > > > > > > > > > > - zeroIndex = i; > > > > > > >> > > > > > > > > > > + if (a[left] < 0.0f) { > > > > > > >> > > > > > > > > > > + zeroIndex = findAnyZero(a, left, n); > > > > > > >> > > > > > > > > > > + > > > > > > >> > > > > > > > > > > + // there is at least one negative > value, so > > > > > range > > > > > > >> > > check is > > > > > > >> > > > > > > not needed > > > > > > >> > > > > > > > > > > + for (int i = zeroIndex - 1; /*i >= > left &&*/ > > > > > > >> a[i] == > > > > > > >> > > 0.0f; i--) { > > > > > > >> > > > > > > > > > > + zeroIndex = i; > > > > > > >> > > > > > > > > > > + } > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > // Turn the right number of positive zeros > > > > > back into > > > > > > >> > > negative zeros > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > 2. We can find the position of the first > > > zero by > > > > > > >> counting > > > > > > >> > > > > > > negative values during preprocessing phase. > > > > > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > > > > > 09:04:19 2010 > > > > > > >> > > > > > > > > > > +++ DualPivotQuicksortC.java Wed May 12 > > > 12:01:24 > > > > > > >> 2010 > > > > > > >> > > > > > > > > > > @@ -1678,7 +1678,7 @@ > > > > > > >> > > > > > > > > > > * Phase 1: Count negative zeros and move > > > NaNs to > > > > > > >> end of > > > > > > >> > > array. > > > > > > >> > > > > > > > > > > */ > > > > > > >> > > > > > > > > > > final int NEGATIVE_ZERO = > > > > > > >> Float.floatToIntBits(-0.0f); > > > > > > >> > > > > > > > > > > - int numNegativeZeros = 0; > > > > > > >> > > > > > > > > > > + int numNegativeZeros = 0, > > > numNegativeValues = 0; > > > > > > >> > > > > > > > > > > int n = right; > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > for (int k = left; k <= n; k++) { > > > > > > >> > > > > > > > > > > @@ -1689,6 +1689,8 @@ > > > > > > >> > > > > > > > > > > } else if (ak != ak) { // i.e., ak is NaN > > > > > > >> > > > > > > > > > > a[k--] = a[n]; > > > > > > >> > > > > > > > > > > a[n--] = Float.NaN; > > > > > > >> > > > > > > > > > > + } else if (ak < 0.0f) { > > > > > > >> > > > > > > > > > > + numNegativeValues++; > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > @@ -1705,7 +1707,7 @@ > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > > > > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > >> > > > > > > > > > > + int zeroIndex = numNegativeValues; > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > for (int i = zeroIndex - 1; i >= left && > > > a[i] == > > > > > > >> 0.0f; > > > > > > >> > > i--) { > > > > > > >> > > > > > > > > > > zeroIndex = i; > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > 3. We can use binary search to find > the first > > > > > > >> zero and > > > > > > >> > > thus > > > > > > >> > > > > > > avoid linear scan. > > > > > > >> > > > > > > > > > > --- DualPivotQuicksort.java Tue May 11 > > > > > 09:04:19 2010 > > > > > > >> > > > > > > > > > > +++ DualPivotQuicksortF.java Wed May 12 > > > 12:03:58 > > > > > > >> 2010 > > > > > > >> > > > > > > > > > > @@ -1705,11 +1705,7 @@ > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > // Find first zero element > > > > > > >> > > > > > > > > > > - int zeroIndex = findAnyZero(a, left, n); > > > > > > >> > > > > > > > > > > - > > > > > > >> > > > > > > > > > > - for (int i = zeroIndex - 1; i >= > left && > > > a[i] == > > > > > > >> > > 0.0f; i--) { > > > > > > >> > > > > > > > > > > - zeroIndex = i; > > > > > > >> > > > > > > > > > > - } > > > > > > >> > > > > > > > > > > + int zeroIndex = findFirstZero(a, > left, n); > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > // Turn the right number of positive zeros > > > > > back into > > > > > > >> > > negative zeros > > > > > > >> > > > > > > > > > > for (int i = zeroIndex, m = zeroIndex + > > > > > > >> > > numNegativeZeros; i < > > > > > > >> > > > > > > m; i++) { > > > > > > >> > > > > > > > > > > @@ -1718,7 +1714,7 @@ > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > /** > > > > > > >> > > > > > > > > > > - * Returns the index of some zero > element > > > in the > > > > > > >> > > specified > > > > > > >> > > > > > > range via > > > > > > >> > > > > > > > > > > + * Returns the index of the first zero > > > element > > > > > > >> in the > > > > > > >> > > > > > > specified range via > > > > > > >> > > > > > > > > > > * binary search. The range is assumed > to be > > > > > > >> sorted, and > > > > > > >> > > must > > > > > > >> > > > > > > contain > > > > > > >> > > > > > > > > > > * at least one zero. > > > > > > >> > > > > > > > > > > * > > > > > > >> > > > > > > > > > > @@ -1726,18 +1722,17 @@ > > > > > > >> > > > > > > > > > > * @param low the index of the first > element, > > > > > > >> inclusive, > > > > > > >> > > to be > > > > > > >> > > > > > > searched > > > > > > >> > > > > > > > > > > * @param high the index of the last > element, > > > > > > >> inclusive, > > > > > > >> > > to be > > > > > > >> > > > > > > searched > > > > > > >> > > > > > > > > > > */ > > > > > > >> > > > > > > > > > > - private static int > findAnyZero(float[] a, > > > > > int low, > > > > > > >> > > int high) { > > > > > > >> > > > > > > > > > > - while (true) { > > > > > > >> > > > > > > > > > > + private static int > findFirstZero(float[] > > > a, int > > > > > > >> low, > > > > > > >> > > int high) { > > > > > > >> > > > > > > > > > > + while (low < high) { > > > > > > >> > > > > > > > > > > int middle = (low + high) >>> 1; > > > > > > >> > > > > > > > > > > float middleValue = a[middle]; > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > if (middleValue < 0.0f) { > > > > > > >> > > > > > > > > > > low = middle + 1; > > > > > > >> > > > > > > > > > > - } else if (middleValue > 0.0f) { > > > > > > >> > > > > > > > > > > - high = middle - 1; > > > > > > >> > > > > > > > > > > - } else { // middleValue == 0.0f > > > > > > >> > > > > > > > > > > - return middle; > > > > > > >> > > > > > > > > > > + } else { // middleValue >= 0.0f > > > > > > >> > > > > > > > > > > + high = middle; > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > + return low; > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > } > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > Counting negative values appeared more > > > expensive > > > > > > >> than > > > > > > >> > > any other > > > > > > >> > > > > > > variants. > > > > > > >> > > > > > > > > > > The last proposal seems to me as > efficient > > > as the > > > > > > >> current > > > > > > >> > > > > > > solution is in its worst case - when we have > only one > > > > > > >> negative > > > > > > >> > > zero (in > > > > > > >> > > > > > > the half of array). > > > > > > >> > > > > > > > > > > And it shows the best result if we > have many > > > > > zeros. > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > Regards, > > > > > > >> > > > > > > > > > > Dmytro Sheyko > > > > > > >> > > > > > > > > > > > > > > > > >> > > > > > > > > > > > From: iaroslavski at mail.ru > > > > > > >> > > > > > > > > > > > To: jjb at google.com; > > > dmytro_sheyko at hotmail.com > > > > > > >> > > > > > > > > > > > CC: core-libs-dev at openjdk.java.net; > > > > > > >> iaroslavski at mail.ru > > > > > > >> > > > > > > > > > > > Subject: Re[2]: New portion of > > > improvements for > > > > > > >> > > Dual-Pivot > > > > > > >> > > > > > > Quicksort > > > > > > >> > > > > > > > > > > > Date: Sun, 9 May 2010 23:51:27 +0400 > > > > > > >> > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > Josh, > > > > > > >> > > > > > > > > > > > Dmytro, > > > > > > >> > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > I have done more thoroughly testing > "great - > > > > > > >> less > 5 * > > > > > > >> > > > > > > seventh" vs. "less < e1 && great > e5", > > > > > > >> > > > > > > > > > > > and found that more symmetric code > "less > > > < e1 && > > > > > > >> > > great > e5" > > > > > > >> > > > > > > is little bit faster, ~0.5..0.7% > > > > > > >> > > > > > > > > > > > on both VMs. Other code has not been > > > changed. > > > > > > >> > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > Please, take the latest version in > > > attachment. > > > > > > >> > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > Vladimir > > > > > > >> > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > Tue, 4 May 2010 21:57:42 -0700 > ?????? ?? > > > Joshua > > > > > > >> Bloch > > > > > > >> > > > > > > : > > > > > > >> > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > > Vladimir, > > > > > > >> > > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > > Old: > > > > > > >> > > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > >298 if (less < e1 && great > e5) { > > > > > > >> > > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > > New: > > > > > > >> > > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > >256 if (great - less > 5 * seventh) { > > > > > > >> > > > > > > > > > > > > > > > > > >> > > > > > > > > > > > >Regards, > > > > > > >> > > > > > > > > > > > >Josh