# HG changeset patch # User wetmore # Date 1250192267 25200 # Node ID 7f4a3f1021495d601910457b79062bfc0e686895 # Parent 118efe1eaf39122817fef23c3920fd36351cf598# Parent 422105639b62b639fc12f643864aba6222f28ed8 Merge diff -r 118efe1eaf39 -r 7f4a3f102149 jdk/src/share/classes/java/lang/String.java --- a/jdk/src/share/classes/java/lang/String.java Thu Aug 13 12:36:10 2009 -0700 +++ b/jdk/src/share/classes/java/lang/String.java Thu Aug 13 12:37:47 2009 -0700 @@ -2301,6 +2301,54 @@ * @spec JSR-51 */ public String[] split(String regex, int limit) { + /* fastpath if the regex is a + (1)one-char String and this character is not one of the + RegEx's meta characters ".$|()[{^?*+\\", or + (2)two-char String and the first char is the backslash and + the second is not the ascii digit or ascii letter. + */ + char ch = 0; + if (((regex.count == 1 && + ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) || + (regex.length() == 2 && + regex.charAt(0) == '\\' && + (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 && + ((ch-'a')|('z'-ch)) < 0 && + ((ch-'A')|('Z'-ch)) < 0)) && + (ch < Character.MIN_HIGH_SURROGATE || + ch > Character.MAX_LOW_SURROGATE)) + { + int off = 0; + int next = 0; + boolean limited = limit > 0; + ArrayList list = new ArrayList(); + while ((next = indexOf(ch, off)) != -1) { + if (!limited || list.size() < limit - 1) { + list.add(substring(off, next)); + off = next + 1; + } else { // last one + //assert (list.size() == limit - 1); + list.add(substring(off, count)); + off = count; + break; + } + } + // If no match was found, return this + if (off == 0) + return new String[] { this }; + + // Add remaining segment + if (!limited || list.size() < limit) + list.add(substring(off, count)); + + // Construct result + int resultSize = list.size(); + if (limit == 0) + while (resultSize > 0 && list.get(resultSize-1).length() == 0) + resultSize--; + String[] result = new String[resultSize]; + return list.subList(0, resultSize).toArray(result); + } return Pattern.compile(regex).split(this, limit); } diff -r 118efe1eaf39 -r 7f4a3f102149 jdk/test/java/lang/String/Split.java --- a/jdk/test/java/lang/String/Split.java Thu Aug 13 12:36:10 2009 -0700 +++ b/jdk/test/java/lang/String/Split.java Thu Aug 13 12:37:47 2009 -0700 @@ -23,14 +23,18 @@ /** * @test + * @bug 6840246 * @summary test String.split() */ +import java.util.Arrays; +import java.util.Random; import java.util.regex.*; public class Split { public static void main(String[] args) throws Exception { String source = "0123456789"; + for (int limit=-2; limit<3; limit++) { for (int x=0; x<10; x++) { String[] result = source.split(Integer.toString(x), limit); @@ -80,5 +84,48 @@ throw new RuntimeException("String.split failure 8"); if (!result[0].equals(source)) throw new RuntimeException("String.split failure 9"); + + // check fastpath of String.split() + source = "0123456789abcdefgABCDEFG"; + Random r = new Random(); + + for (boolean doEscape: new boolean[] {false, true}) { + for (int cp = 0; cp < 0x11000; cp++) { + Pattern p = null; + String regex = new String(Character.toChars(cp)); + if (doEscape) + regex = "\\" + regex; + try { + p = Pattern.compile(regex); + } catch (PatternSyntaxException pse) { + // illegal syntax + try { + "abc".split(regex); + } catch (PatternSyntaxException pse0) { + continue; + } + throw new RuntimeException("String.split failure 11"); + } + int off = r.nextInt(source.length()); + String[] srcStrs = new String[] { + "", + source, + regex + source, + source + regex, + source.substring(0, 3) + + regex + source.substring(3, 9) + + regex + source.substring(9, 15) + + regex + source.substring(15), + source.substring(0, off) + regex + source.substring(off) + }; + for (String src: srcStrs) { + for (int limit=-2; limit<3; limit++) { + if (!Arrays.equals(src.split(regex, limit), + p.split(src, limit))) + throw new RuntimeException("String.split failure 12"); + } + } + } + } } }