From 8f2e760dd320f13eaea7dc6203fc73d27f8a4c92 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Wed, 18 Nov 2020 15:00:04 +0100 Subject: [PATCH 1/5] Use non synchronized collections --- .../plexus/util/DirectoryScanner.java | 100 +++++++----------- 1 file changed, 40 insertions(+), 60 deletions(-) diff --git a/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java b/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java index c17a9781..6985ffd3 100644 --- a/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java +++ b/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java @@ -58,7 +58,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Vector; /** *

Class for scanning a directory for files/directories which match certain criteria.

@@ -144,42 +143,42 @@ public class DirectoryScanner /** * The files which matched at least one include and no excludes and were selected. */ - protected Vector filesIncluded; + protected ArrayList filesIncluded; /** * The files which did not match any includes or selectors. */ - protected Vector filesNotIncluded; + protected ArrayList filesNotIncluded; /** * The files which matched at least one include and at least one exclude. */ - protected Vector filesExcluded; + protected ArrayList filesExcluded; /** * The directories which matched at least one include and no excludes and were selected. */ - protected Vector dirsIncluded; + protected ArrayList dirsIncluded; /** * The directories which were found and did not match any includes. */ - protected Vector dirsNotIncluded; + protected ArrayList dirsNotIncluded; /** * The directories which matched at least one include and at least one exclude. */ - protected Vector dirsExcluded; + protected ArrayList dirsExcluded; /** * The files which matched at least one include and no excludes and which a selector discarded. */ - protected Vector filesDeselected; + protected ArrayList filesDeselected; /** * The directories which matched at least one include and no excludes but which a selector discarded. */ - protected Vector dirsDeselected; + protected ArrayList dirsDeselected; /** * Whether or not our results were built by a slow scan. @@ -287,14 +286,14 @@ public void scan() setupDefaultFilters(); setupMatchPatterns(); - filesIncluded = new Vector(); - filesNotIncluded = new Vector(); - filesExcluded = new Vector(); - filesDeselected = new Vector(); - dirsIncluded = new Vector(); - dirsNotIncluded = new Vector(); - dirsExcluded = new Vector(); - dirsDeselected = new Vector(); + filesIncluded = new ArrayList(); + filesNotIncluded = new ArrayList(); + filesExcluded = new ArrayList(); + filesDeselected = new ArrayList(); + dirsIncluded = new ArrayList(); + dirsNotIncluded = new ArrayList(); + dirsExcluded = new ArrayList(); + dirsDeselected = new ArrayList(); if ( isIncluded( "", tokenizedEmpty ) ) { @@ -303,21 +302,21 @@ public void scan() { if ( isSelected( "", basedir ) ) { - dirsIncluded.addElement( "" ); + dirsIncluded.add( "" ); } else { - dirsDeselected.addElement( "" ); + dirsDeselected.add( "" ); } } else { - dirsExcluded.addElement( "" ); + dirsExcluded.add( "" ); } } else { - dirsNotIncluded.addElement( "" ); + dirsNotIncluded.add( "" ); } scandir( basedir, "", true ); } @@ -336,11 +335,8 @@ protected void slowScan() return; } - String[] excl = new String[dirsExcluded.size()]; - dirsExcluded.copyInto( excl ); - - String[] notIncl = new String[dirsNotIncluded.size()]; - dirsNotIncluded.copyInto( notIncl ); + String[] excl = dirsExcluded.toArray( new String[dirsExcluded.size()] ); + String[] notIncl = dirsNotIncluded.toArray( new String[dirsNotIncluded.size()] ); for ( String anExcl : excl ) { @@ -416,11 +412,11 @@ protected void scandir( File dir, String vpath, boolean fast ) File file = new File( dir, newfile ); if ( file.isDirectory() ) { - dirsExcluded.addElement( name ); + dirsExcluded.add( name ); } else { - filesExcluded.addElement( name ); + filesExcluded.add( name ); } } else @@ -458,7 +454,7 @@ protected void scandir( File dir, String vpath, boolean fast ) { if ( isSelected( name, file ) ) { - dirsIncluded.addElement( name ); + dirsIncluded.add( name ); if ( fast ) { scandir( file, name + File.separator, fast ); @@ -467,7 +463,7 @@ protected void scandir( File dir, String vpath, boolean fast ) else { everythingIncluded = false; - dirsDeselected.addElement( name ); + dirsDeselected.add( name ); if ( fast && couldHoldIncluded( name ) ) { scandir( file, name + File.separator, fast ); @@ -478,7 +474,7 @@ protected void scandir( File dir, String vpath, boolean fast ) else { everythingIncluded = false; - dirsExcluded.addElement( name ); + dirsExcluded.add( name ); if ( fast && couldHoldIncluded( name ) ) { scandir( file, name + File.separator, fast ); @@ -488,7 +484,7 @@ protected void scandir( File dir, String vpath, boolean fast ) else { everythingIncluded = false; - dirsNotIncluded.addElement( name ); + dirsNotIncluded.add( name ); if ( fast && couldHoldIncluded( name ) ) { scandir( file, name + File.separator, fast ); @@ -507,24 +503,24 @@ else if ( file.isFile() ) { if ( isSelected( name, file ) ) { - filesIncluded.addElement( name ); + filesIncluded.add( name ); } else { everythingIncluded = false; - filesDeselected.addElement( name ); + filesDeselected.add( name ); } } else { everythingIncluded = false; - filesExcluded.addElement( name ); + filesExcluded.add( name ); } } else { everythingIncluded = false; - filesNotIncluded.addElement( name ); + filesNotIncluded.add( name ); } } } @@ -553,9 +549,7 @@ protected boolean isSelected( String name, File file ) @Override public String[] getIncludedFiles() { - String[] files = new String[filesIncluded.size()]; - filesIncluded.copyInto( files ); - return files; + return filesIncluded.toArray( new String[filesIncluded.size()] ); } /** @@ -568,9 +562,7 @@ public String[] getIncludedFiles() public String[] getNotIncludedFiles() { slowScan(); - String[] files = new String[filesNotIncluded.size()]; - filesNotIncluded.copyInto( files ); - return files; + return filesNotIncluded.toArray( new String[filesNotIncluded.size()] ); } /** @@ -585,9 +577,7 @@ public String[] getNotIncludedFiles() public String[] getExcludedFiles() { slowScan(); - String[] files = new String[filesExcluded.size()]; - filesExcluded.copyInto( files ); - return files; + return filesExcluded.toArray( new String[filesExcluded.size()] ); } /** @@ -602,9 +592,7 @@ public String[] getExcludedFiles() public String[] getDeselectedFiles() { slowScan(); - String[] files = new String[filesDeselected.size()]; - filesDeselected.copyInto( files ); - return files; + return filesDeselected.toArray( new String[filesDeselected.size()] ); } /** @@ -617,9 +605,7 @@ public String[] getDeselectedFiles() @Override public String[] getIncludedDirectories() { - String[] directories = new String[dirsIncluded.size()]; - dirsIncluded.copyInto( directories ); - return directories; + return dirsIncluded.toArray( new String[dirsIncluded.size()] ); } /** @@ -632,9 +618,7 @@ public String[] getIncludedDirectories() public String[] getNotIncludedDirectories() { slowScan(); - String[] directories = new String[dirsNotIncluded.size()]; - dirsNotIncluded.copyInto( directories ); - return directories; + return dirsNotIncluded.toArray( new String[dirsNotIncluded.size()] ); } /** @@ -649,9 +633,7 @@ public String[] getNotIncludedDirectories() public String[] getExcludedDirectories() { slowScan(); - String[] directories = new String[dirsExcluded.size()]; - dirsExcluded.copyInto( directories ); - return directories; + return dirsExcluded.toArray( new String[dirsExcluded.size()] ); } /** @@ -666,9 +648,7 @@ public String[] getExcludedDirectories() public String[] getDeselectedDirectories() { slowScan(); - String[] directories = new String[dirsDeselected.size()]; - dirsDeselected.copyInto( directories ); - return directories; + return dirsDeselected.toArray( new String[dirsDeselected.size()] ); } /** From 2c69fc480dee7512f004b0e043a9faf39285f7c2 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Wed, 18 Nov 2020 15:08:49 +0100 Subject: [PATCH 2/5] Use empty arrays when transforming collections to arrays --- .../codehaus/plexus/util/AbstractScanner.java | 4 +-- .../plexus/util/DirectoryScanner.java | 26 ++++++++++--------- .../codehaus/plexus/util/ExceptionUtils.java | 8 +++--- .../org/codehaus/plexus/util/FileUtils.java | 5 +--- .../codehaus/plexus/util/MatchPattern.java | 2 +- .../codehaus/plexus/util/MatchPatterns.java | 2 +- .../codehaus/plexus/util/SelectorUtils.java | 2 +- .../codehaus/plexus/util/cli/shell/Shell.java | 2 +- 8 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/codehaus/plexus/util/AbstractScanner.java b/src/main/java/org/codehaus/plexus/util/AbstractScanner.java index 414b60b8..a64fd33b 100644 --- a/src/main/java/org/codehaus/plexus/util/AbstractScanner.java +++ b/src/main/java/org/codehaus/plexus/util/AbstractScanner.java @@ -246,7 +246,7 @@ public void setIncludes( String[] includes ) list.add( normalizePattern( include ) ); } } - this.includes = list.toArray( new String[list.size()] ); + this.includes = list.toArray( new String[0] ); } } @@ -276,7 +276,7 @@ public void setExcludes( String[] excludes ) list.add( normalizePattern( exclude ) ); } } - this.excludes = list.toArray( new String[list.size()] ); + this.excludes = list.toArray( new String[0] ); } } diff --git a/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java b/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java index 6985ffd3..ef04f146 100644 --- a/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java +++ b/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java @@ -135,6 +135,8 @@ public class DirectoryScanner extends AbstractScanner { + private static final String[] EMPTY_STRING_ARRAY = new String[0]; + /** * The base directory to be scanned. */ @@ -335,8 +337,8 @@ protected void slowScan() return; } - String[] excl = dirsExcluded.toArray( new String[dirsExcluded.size()] ); - String[] notIncl = dirsNotIncluded.toArray( new String[dirsNotIncluded.size()] ); + String[] excl = dirsExcluded.toArray( EMPTY_STRING_ARRAY ); + String[] notIncl = dirsNotIncluded.toArray( EMPTY_STRING_ARRAY ); for ( String anExcl : excl ) { @@ -394,7 +396,7 @@ protected void scandir( File dir, String vpath, boolean fast ) * [bentmann] A null array will also be returned from list() on NTFS when dir refers to a soft link or * junction point whose target is not existent. */ - newfiles = new String[0]; + newfiles = EMPTY_STRING_ARRAY; // throw new IOException( "IO error scanning directory " + dir.getAbsolutePath() ); } @@ -432,7 +434,7 @@ protected void scandir( File dir, String vpath, boolean fast ) noLinks.add( newfile ); } } - newfiles = noLinks.toArray( new String[noLinks.size()] ); + newfiles = noLinks.toArray( EMPTY_STRING_ARRAY ); } if ( filenameComparator != null ) @@ -549,7 +551,7 @@ protected boolean isSelected( String name, File file ) @Override public String[] getIncludedFiles() { - return filesIncluded.toArray( new String[filesIncluded.size()] ); + return filesIncluded.toArray( EMPTY_STRING_ARRAY ); } /** @@ -562,7 +564,7 @@ public String[] getIncludedFiles() public String[] getNotIncludedFiles() { slowScan(); - return filesNotIncluded.toArray( new String[filesNotIncluded.size()] ); + return filesNotIncluded.toArray( EMPTY_STRING_ARRAY ); } /** @@ -577,7 +579,7 @@ public String[] getNotIncludedFiles() public String[] getExcludedFiles() { slowScan(); - return filesExcluded.toArray( new String[filesExcluded.size()] ); + return filesExcluded.toArray( EMPTY_STRING_ARRAY ); } /** @@ -592,7 +594,7 @@ public String[] getExcludedFiles() public String[] getDeselectedFiles() { slowScan(); - return filesDeselected.toArray( new String[filesDeselected.size()] ); + return filesDeselected.toArray( EMPTY_STRING_ARRAY ); } /** @@ -605,7 +607,7 @@ public String[] getDeselectedFiles() @Override public String[] getIncludedDirectories() { - return dirsIncluded.toArray( new String[dirsIncluded.size()] ); + return dirsIncluded.toArray( EMPTY_STRING_ARRAY ); } /** @@ -618,7 +620,7 @@ public String[] getIncludedDirectories() public String[] getNotIncludedDirectories() { slowScan(); - return dirsNotIncluded.toArray( new String[dirsNotIncluded.size()] ); + return dirsNotIncluded.toArray( EMPTY_STRING_ARRAY ); } /** @@ -633,7 +635,7 @@ public String[] getNotIncludedDirectories() public String[] getExcludedDirectories() { slowScan(); - return dirsExcluded.toArray( new String[dirsExcluded.size()] ); + return dirsExcluded.toArray( EMPTY_STRING_ARRAY ); } /** @@ -648,7 +650,7 @@ public String[] getExcludedDirectories() public String[] getDeselectedDirectories() { slowScan(); - return dirsDeselected.toArray( new String[dirsDeselected.size()] ); + return dirsDeselected.toArray( EMPTY_STRING_ARRAY ); } /** diff --git a/src/main/java/org/codehaus/plexus/util/ExceptionUtils.java b/src/main/java/org/codehaus/plexus/util/ExceptionUtils.java index 341dc80d..540dbe98 100644 --- a/src/main/java/org/codehaus/plexus/util/ExceptionUtils.java +++ b/src/main/java/org/codehaus/plexus/util/ExceptionUtils.java @@ -112,7 +112,7 @@ public static void addCauseMethodName( String methodName ) { List list = new ArrayList( Arrays.asList( CAUSE_METHOD_NAMES ) ); list.add( methodName ); - CAUSE_METHOD_NAMES = list.toArray( new String[list.size()] ); + CAUSE_METHOD_NAMES = list.toArray( new String[0] ); } } @@ -350,7 +350,7 @@ public static Throwable[] getThrowables( Throwable throwable ) list.add( throwable ); throwable = getCause( throwable ); } - return list.toArray( new Throwable[list.size()] ); + return list.toArray( new Throwable[0] ); } /** @@ -479,7 +479,7 @@ public static String[] getRootCauseStackTrace( Throwable t ) frames.add( aTrace ); } } - return frames.toArray( new String[frames.size()] ); + return frames.toArray( new String[0] ); } /** @@ -625,7 +625,7 @@ static String[] getStackFrames( String stackTrace ) { list.add( frames.nextToken() ); } - return list.toArray( new String[list.size()] ); + return list.toArray( new String[0] ); } /** diff --git a/src/main/java/org/codehaus/plexus/util/FileUtils.java b/src/main/java/org/codehaus/plexus/util/FileUtils.java index fe80c7d4..31e12a2b 100644 --- a/src/main/java/org/codehaus/plexus/util/FileUtils.java +++ b/src/main/java/org/codehaus/plexus/util/FileUtils.java @@ -625,10 +625,7 @@ public static String[] getFilesFromExtension( String directory, String[] extensi } // ok... move the Vector into the files list... - String[] foundFiles = new String[files.size()]; - files.toArray( foundFiles ); - - return foundFiles; + return files.toArray( new String[0] ); } /** diff --git a/src/main/java/org/codehaus/plexus/util/MatchPattern.java b/src/main/java/org/codehaus/plexus/util/MatchPattern.java index dade194a..f88f9b8d 100644 --- a/src/main/java/org/codehaus/plexus/util/MatchPattern.java +++ b/src/main/java/org/codehaus/plexus/util/MatchPattern.java @@ -124,7 +124,7 @@ static String[] tokenizePathToString( String path, String separator ) { ret.add( st.nextToken() ); } - return ret.toArray( new String[ret.size()] ); + return ret.toArray( new String[0] ); } public static MatchPattern fromString( String source ) diff --git a/src/main/java/org/codehaus/plexus/util/MatchPatterns.java b/src/main/java/org/codehaus/plexus/util/MatchPatterns.java index f871f8e1..ded32073 100644 --- a/src/main/java/org/codehaus/plexus/util/MatchPatterns.java +++ b/src/main/java/org/codehaus/plexus/util/MatchPatterns.java @@ -85,7 +85,7 @@ private static MatchPattern[] getMatchPatterns( Iterable items ) { result.add( MatchPattern.fromString( string ) ); } - return result.toArray( new MatchPattern[result.size()] ); + return result.toArray( new MatchPattern[0] ); } } diff --git a/src/main/java/org/codehaus/plexus/util/SelectorUtils.java b/src/main/java/org/codehaus/plexus/util/SelectorUtils.java index 2686cfee..de39f4fe 100644 --- a/src/main/java/org/codehaus/plexus/util/SelectorUtils.java +++ b/src/main/java/org/codehaus/plexus/util/SelectorUtils.java @@ -772,7 +772,7 @@ private static String[] tokenizePathToString( String path, String separator ) { ret.add( st.nextToken() ); } - return ret.toArray( new String[ret.size()] ); + return ret.toArray( new String[0] ); } /** diff --git a/src/main/java/org/codehaus/plexus/util/cli/shell/Shell.java b/src/main/java/org/codehaus/plexus/util/cli/shell/Shell.java index 6082849c..c3c911dd 100644 --- a/src/main/java/org/codehaus/plexus/util/cli/shell/Shell.java +++ b/src/main/java/org/codehaus/plexus/util/cli/shell/Shell.java @@ -119,7 +119,7 @@ public String[] getShellArgs() } else { - return shellArgs.toArray( new String[shellArgs.size()] ); + return shellArgs.toArray( new String[0] ); } } From 83f8c8150107c05f90fd6d683c348e2377e80f03 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Wed, 18 Nov 2020 15:14:49 +0100 Subject: [PATCH 3/5] Avoid tokenizing each file name twice --- .../org/codehaus/plexus/util/AbstractScanner.java | 10 ++++++++++ .../org/codehaus/plexus/util/DirectoryScanner.java | 4 ++-- .../java/org/codehaus/plexus/util/MatchPattern.java | 11 +++++++++++ .../java/org/codehaus/plexus/util/MatchPatterns.java | 5 +++++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/codehaus/plexus/util/AbstractScanner.java b/src/main/java/org/codehaus/plexus/util/AbstractScanner.java index a64fd33b..af3fbc4a 100644 --- a/src/main/java/org/codehaus/plexus/util/AbstractScanner.java +++ b/src/main/java/org/codehaus/plexus/util/AbstractScanner.java @@ -331,6 +331,11 @@ protected boolean isIncluded( String name, String[] tokenizedName ) return includesPatterns.matches( name, tokenizedName, isCaseSensitive ); } + protected boolean isIncluded( String name, char[][] tokenizedName ) + { + return includesPatterns.matches( name, tokenizedName, isCaseSensitive ); + } + /** * Tests whether or not a name matches the start of at least one include pattern. * @@ -360,6 +365,11 @@ protected boolean isExcluded( String name, String[] tokenizedName ) return excludesPatterns.matches( name, tokenizedName, isCaseSensitive ); } + protected boolean isExcluded( String name, char[][] tokenizedName ) + { + return excludesPatterns.matches( name, tokenizedName, isCaseSensitive ); + } + /** * Adds default exclusions to the current exclusions set. */ diff --git a/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java b/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java index ef04f146..d08b86cb 100644 --- a/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java +++ b/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java @@ -199,7 +199,7 @@ public class DirectoryScanner */ protected boolean everythingIncluded = true; - private final String[] tokenizedEmpty = MatchPattern.tokenizePathToString( "", File.separator ); + private final char[][] tokenizedEmpty = MatchPattern.tokenizePathToCharArray( "", File.separator ); /** * Sole constructor. @@ -445,7 +445,7 @@ protected void scandir( File dir, String vpath, boolean fast ) for ( String newfile : newfiles ) { String name = vpath + newfile; - String[] tokenizedName = MatchPattern.tokenizePathToString( name, File.separator ); + char[][] tokenizedName = MatchPattern.tokenizePathToCharArray( name, File.separator ); File file = new File( dir, newfile ); if ( file.isDirectory() ) { diff --git a/src/main/java/org/codehaus/plexus/util/MatchPattern.java b/src/main/java/org/codehaus/plexus/util/MatchPattern.java index f88f9b8d..de57de21 100644 --- a/src/main/java/org/codehaus/plexus/util/MatchPattern.java +++ b/src/main/java/org/codehaus/plexus/util/MatchPattern.java @@ -127,6 +127,17 @@ static String[] tokenizePathToString( String path, String separator ) return ret.toArray( new String[0] ); } + static char[][] tokenizePathToCharArray( String path, String separator ) + { + String[] tokenizedName = tokenizePathToString( path, separator ); + char[][] tokenizedNameChar = new char[tokenizedName.length][]; + for ( int i = 0; i < tokenizedName.length; i++ ) + { + tokenizedNameChar[i] = tokenizedName[i].toCharArray(); + } + return tokenizedNameChar; + } + public static MatchPattern fromString( String source ) { return new MatchPattern( source, File.separator ); diff --git a/src/main/java/org/codehaus/plexus/util/MatchPatterns.java b/src/main/java/org/codehaus/plexus/util/MatchPatterns.java index ded32073..35f9ea22 100644 --- a/src/main/java/org/codehaus/plexus/util/MatchPatterns.java +++ b/src/main/java/org/codehaus/plexus/util/MatchPatterns.java @@ -40,6 +40,11 @@ public boolean matches( String name, String[] tokenizedName, boolean isCaseSensi { tokenizedNameChar[i] = tokenizedName[i].toCharArray(); } + return matches(name, tokenizedNameChar, isCaseSensitive); + } + + public boolean matches(String name, char[][] tokenizedNameChar, boolean isCaseSensitive) + { for ( MatchPattern pattern : patterns ) { if ( pattern.matchPath( name, tokenizedNameChar, isCaseSensitive ) ) From 26d86148ca06057f3d0874d2600e72dd5e21acc0 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Wed, 18 Nov 2020 15:16:02 +0100 Subject: [PATCH 4/5] Save a bunch of file system accesses If the parent directory is a symbolic link, this is true for all the children, so invert the loop --- .../plexus/util/DirectoryScanner.java | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java b/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java index d08b86cb..5db6a903 100644 --- a/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java +++ b/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java @@ -403,12 +403,11 @@ protected void scandir( File dir, String vpath, boolean fast ) if ( !followSymlinks ) { - ArrayList noLinks = new ArrayList(); - for ( String newfile : newfiles ) + try { - try + if ( isParentSymbolicLink( dir, null ) ) { - if ( isParentSymbolicLink( dir, newfile ) ) + for ( String newfile : newfiles ) { String name = vpath + newfile; File file = new File( dir, newfile ); @@ -421,20 +420,15 @@ protected void scandir( File dir, String vpath, boolean fast ) filesExcluded.add( name ); } } - else - { - noLinks.add( newfile ); - } - } - catch ( IOException ioe ) - { - String msg = "IOException caught while checking " + "for links, couldn't get canonical path!"; - // will be caught and redirected to Ant's logging system - System.err.println( msg ); - noLinks.add( newfile ); + return; } } - newfiles = noLinks.toArray( EMPTY_STRING_ARRAY ); + catch ( IOException ioe ) + { + String msg = "IOException caught while checking for links!"; + // will be caught and redirected to Ant's logging system + System.err.println( msg ); + } } if ( filenameComparator != null ) From 642616622cce48e632efe8546afcd9b42ecc9873 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Wed, 18 Nov 2020 16:23:00 +0100 Subject: [PATCH 5/5] Save a few percent on parsing --- .../plexus/util/xml/pull/MXParser.java | 417 +++++++----------- .../util/xml/pull/MXParserPerfTest.java | 79 ++++ src/test/resources/xml/pom.xml | 140 ++++++ 3 files changed, 378 insertions(+), 258 deletions(-) create mode 100644 src/test/java/org/codehaus/plexus/util/xml/pull/MXParserPerfTest.java create mode 100644 src/test/resources/xml/pom.xml diff --git a/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java b/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java index 6874eefa..a612e6be 100644 --- a/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java +++ b/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java @@ -36,26 +36,26 @@ public class MXParser implements XmlPullParser { // NOTE: no interning of those strings --> by Java leng spec they MUST be already interned - protected final static String XML_URI = "http://www.w3.org/XML/1998/namespace"; + private final static String XML_URI = "http://www.w3.org/XML/1998/namespace"; - protected final static String XMLNS_URI = "http://www.w3.org/2000/xmlns/"; + private final static String XMLNS_URI = "http://www.w3.org/2000/xmlns/"; - protected final static String FEATURE_XML_ROUNDTRIP = + private final static String FEATURE_XML_ROUNDTRIP = // "http://xmlpull.org/v1/doc/features.html#xml-roundtrip"; "http://xmlpull.org/v1/doc/features.html#xml-roundtrip"; - protected final static String FEATURE_NAMES_INTERNED = "http://xmlpull.org/v1/doc/features.html#names-interned"; + private final static String FEATURE_NAMES_INTERNED = "http://xmlpull.org/v1/doc/features.html#names-interned"; - protected final static String PROPERTY_XMLDECL_VERSION = + private final static String PROPERTY_XMLDECL_VERSION = "http://xmlpull.org/v1/doc/properties.html#xmldecl-version"; - protected final static String PROPERTY_XMLDECL_STANDALONE = + private final static String PROPERTY_XMLDECL_STANDALONE = "http://xmlpull.org/v1/doc/properties.html#xmldecl-standalone"; - protected final static String PROPERTY_XMLDECL_CONTENT = + private final static String PROPERTY_XMLDECL_CONTENT = "http://xmlpull.org/v1/doc/properties.html#xmldecl-content"; - protected final static String PROPERTY_LOCATION = "http://xmlpull.org/v1/doc/properties.html#location"; + private final static String PROPERTY_LOCATION = "http://xmlpull.org/v1/doc/properties.html#location"; /** * Implementation notice: the is instance variable that controls if newString() is interning. @@ -65,19 +65,19 @@ public class MXParser *

* NOTE: by default in this minimal implementation it is false! */ - protected boolean allStringsInterned; + private boolean allStringsInterned; - protected void resetStringCache() + private void resetStringCache() { // System.out.println("resetStringCache() minimum called"); } - protected String newString( char[] cbuf, int off, int len ) + private String newString( char[] cbuf, int off, int len ) { return new String( cbuf, off, len ); } - protected String newStringIntern( char[] cbuf, int off, int len ) + private String newStringIntern( char[] cbuf, int off, int len ) { return ( new String( cbuf, off, len ) ).intern(); } @@ -85,48 +85,48 @@ protected String newStringIntern( char[] cbuf, int off, int len ) private static final boolean TRACE_SIZING = false; // NOTE: features are not resetable and typically defaults to false ... - protected boolean processNamespaces; + private boolean processNamespaces; - protected boolean roundtripSupported; + private boolean roundtripSupported; // global parser state - protected String location; + private String location; - protected int lineNumber; + private int lineNumber; - protected int columnNumber; + private int columnNumber; - protected boolean seenRoot; + private boolean seenRoot; - protected boolean reachedEnd; + private boolean reachedEnd; - protected int eventType; + private int eventType; - protected boolean emptyElementTag; + private boolean emptyElementTag; // element stack - protected int depth; + private int depth; - protected char[] elRawName[]; + private char[] elRawName[]; - protected int elRawNameEnd[]; + private int elRawNameEnd[]; - protected int elRawNameLine[]; + private int elRawNameLine[]; - protected String elName[]; + private String elName[]; - protected String elPrefix[]; + private String elPrefix[]; - protected String elUri[]; + private String elUri[]; - // protected String elValue[]; - protected int elNamespaceCount[]; + // private String elValue[]; + private int elNamespaceCount[]; /** * Make sure that we have enough space to keep element stack if passed size. It will always create one additional * slot then current depth */ - protected void ensureElementsCapacity() + private void ensureElementsCapacity() { final int elStackSize = elName != null ? elName.length : 0; if ( ( depth + 1 ) >= elStackSize ) @@ -204,24 +204,24 @@ protected void ensureElementsCapacity() } // attribute stack - protected int attributeCount; + private int attributeCount; - protected String attributeName[]; + private String attributeName[]; - protected int attributeNameHash[]; + private int attributeNameHash[]; - // protected int attributeNameStart[]; - // protected int attributeNameEnd[]; - protected String attributePrefix[]; + // private int attributeNameStart[]; + // private int attributeNameEnd[]; + private String attributePrefix[]; - protected String attributeUri[]; + private String attributeUri[]; - protected String attributeValue[]; - // protected int attributeValueStart[]; - // protected int attributeValueEnd[]; + private String attributeValue[]; + // private int attributeValueStart[]; + // private int attributeValueEnd[]; // Make sure that in attributes temporary array is enough space. - protected void ensureAttributesCapacity( int size ) + private void ensureAttributesCapacity( int size ) { final int attrPosSize = attributeName != null ? attributeName.length : 0; if ( size >= attrPosSize ) @@ -268,15 +268,15 @@ protected void ensureAttributesCapacity( int size ) } // namespace stack - protected int namespaceEnd; + private int namespaceEnd; - protected String namespacePrefix[]; + private String namespacePrefix[]; - protected int namespacePrefixHash[]; + private int namespacePrefixHash[]; - protected String namespaceUri[]; + private String namespaceUri[]; - protected void ensureNamespacesCapacity( int size ) + private void ensureNamespacesCapacity( int size ) { final int namespaceSize = namespacePrefix != null ? namespacePrefix.length : 0; if ( size >= namespaceSize ) @@ -314,7 +314,7 @@ protected void ensureNamespacesCapacity( int size ) // simplistic implementation of hash function that has constant time to compute - so it also means // diminishing hash quality for long strings but for XML parsing it should be good enough ... - protected static final int fastHash( char ch[], int off, int len ) + private static final int fastHash( char ch[], int off, int len ) { if ( len == 0 ) return 0; @@ -337,21 +337,21 @@ protected static final int fastHash( char ch[], int off, int len ) } // entity replacement stack - protected int entityEnd; + private int entityEnd; - protected String entityName[]; + private String entityName[]; - protected char[] entityNameBuf[]; + private char[] entityNameBuf[]; - protected String entityReplacement[]; + private String entityReplacement[]; - protected char[] entityReplacementBuf[]; + private char[] entityReplacementBuf[]; - protected int entityNameHash[]; + private int entityNameHash[]; private final EntityReplacementMap replacementMapTemplate; - protected void ensureEntityCapacity() + private void ensureEntityCapacity() { final int entitySize = entityReplacementBuf != null ? entityReplacementBuf.length : 0; if ( entityEnd >= entitySize ) @@ -390,72 +390,72 @@ protected void ensureEntityCapacity() } // input buffer management - protected static final int READ_CHUNK_SIZE = 8 * 1024; // max data chars in one read() call + private static final int READ_CHUNK_SIZE = 8 * 1024; // max data chars in one read() call - protected Reader reader; + private Reader reader; - protected String inputEncoding; + private String inputEncoding; - protected int bufLoadFactor = 95; // 99% - // protected int bufHardLimit; // only matters when expanding + private int bufLoadFactor = 95; // 99% + // private int bufHardLimit; // only matters when expanding - protected float bufferLoadFactor = bufLoadFactor / 100f; + private float bufferLoadFactor = bufLoadFactor / 100f; - protected char buf[] = new char[Runtime.getRuntime().freeMemory() > 1000000L ? READ_CHUNK_SIZE : 256]; + private char buf[] = new char[Runtime.getRuntime().freeMemory() > 1000000L ? READ_CHUNK_SIZE : 256]; - protected int bufSoftLimit = (int) ( bufferLoadFactor * buf.length ); // desirable size of buffer + private int bufSoftLimit = (int) ( bufferLoadFactor * buf.length ); // desirable size of buffer - protected boolean preventBufferCompaction; + private boolean preventBufferCompaction; - protected int bufAbsoluteStart; // this is buf + private int bufAbsoluteStart; // this is buf - protected int bufStart; + private int bufStart; - protected int bufEnd; + private int bufEnd; - protected int pos; + private int pos; - protected int posStart; + private int posStart; - protected int posEnd; + private int posEnd; - protected char pc[] = new char[Runtime.getRuntime().freeMemory() > 1000000L ? READ_CHUNK_SIZE : 64]; + private char pc[] = new char[Runtime.getRuntime().freeMemory() > 1000000L ? READ_CHUNK_SIZE : 64]; - protected int pcStart; + private int pcStart; - protected int pcEnd; + private int pcEnd; // parsing state - // protected boolean needsMore; - // protected boolean seenMarkup; - protected boolean usePC; + // private boolean needsMore; + // private boolean seenMarkup; + private boolean usePC; - protected boolean seenStartTag; + private boolean seenStartTag; - protected boolean seenEndTag; + private boolean seenEndTag; - protected boolean pastEndTag; + private boolean pastEndTag; - protected boolean seenAmpersand; + private boolean seenAmpersand; - protected boolean seenMarkup; + private boolean seenMarkup; - protected boolean seenDocdecl; + private boolean seenDocdecl; // transient variable set during each call to next/Token() - protected boolean tokenize; + private boolean tokenize; - protected String text; + private String text; - protected String entityRefName; + private String entityRefName; - protected String xmlDeclVersion; + private String xmlDeclVersion; - protected Boolean xmlDeclStandalone; + private Boolean xmlDeclStandalone; - protected String xmlDeclContent; + private String xmlDeclContent; - protected void reset() + private void reset() { // System.out.println("reset() called"); location = null; @@ -719,7 +719,7 @@ public void defineEntityReplacementText( String entityName, String replacementTe } } - // protected char[] entityReplacement[]; + // private char[] entityReplacement[]; ensureEntityCapacity(); // this is to make sure that if interning works we will take advantage of it ... @@ -742,7 +742,7 @@ public void defineEntityReplacementText( String entityName, String replacementTe public int getNamespaceCount( int depth ) throws XmlPullParserException { - if ( processNamespaces == false || depth == 0 ) + if ( !processNamespaces || depth == 0 ) { return 0; } @@ -1102,7 +1102,7 @@ public String getAttributeNamespace( int index ) { if ( eventType != START_TAG ) throw new IndexOutOfBoundsException( "only START_TAG can have attributes" ); - if ( processNamespaces == false ) + if ( !processNamespaces ) return NO_NAMESPACE; if ( index < 0 || index >= attributeCount ) throw new IndexOutOfBoundsException( "attribute position must be 0.." + ( attributeCount - 1 ) + " and not " @@ -1126,7 +1126,7 @@ public String getAttributePrefix( int index ) { if ( eventType != START_TAG ) throw new IndexOutOfBoundsException( "only START_TAG can have attributes" ); - if ( processNamespaces == false ) + if ( !processNamespaces ) return null; if ( index < 0 || index >= attributeCount ) throw new IndexOutOfBoundsException( "attribute position must be 0.." + ( attributeCount - 1 ) + " and not " @@ -1225,7 +1225,7 @@ public int getEventType() public void require( int type, String namespace, String name ) throws XmlPullParserException, IOException { - if ( processNamespaces == false && namespace != null ) + if ( !processNamespaces && namespace != null ) { throw new XmlPullParserException( "processing namespaces must be enabled on parser (or factory)" + " to have possible namespaces declared on elements" + ( " (position:" + getPositionDescription() ) @@ -1365,7 +1365,7 @@ public int nextToken() return nextImpl(); } - protected int nextImpl() + private int nextImpl() throws XmlPullParserException, IOException { text = null; @@ -1640,7 +1640,7 @@ else if ( ch == '&' ) hadCharData = true; boolean normalizedCR = false; - final boolean normalizeInput = tokenize == false || roundtripSupported == false; + final boolean normalizeInput = !tokenize || !roundtripSupported; // use loop locality here!!!! boolean seenBracket = false; boolean seenBracketBracket = false; @@ -1741,7 +1741,7 @@ else if ( ch == '\n' ) } } - protected int parseProlog() + private int parseProlog() throws XmlPullParserException, IOException { // [2] prolog: ::= XMLDecl? Misc* (doctypedecl Misc*)? and look for [39] element @@ -1775,7 +1775,7 @@ protected int parseProlog() seenMarkup = false; boolean gotS = false; posStart = pos - 1; - final boolean normalizeIgnorableWS = tokenize == true && roundtripSupported == false; + final boolean normalizeIgnorableWS = tokenize && !roundtripSupported; boolean normalizedCR = false; while ( true ) { @@ -1907,7 +1907,7 @@ else if ( ch == '\n' ) } } - protected int parseEpilog() + private int parseEpilog() throws XmlPullParserException, IOException { if ( eventType == END_DOCUMENT ) @@ -1919,7 +1919,7 @@ protected int parseEpilog() return eventType = END_DOCUMENT; } boolean gotS = false; - final boolean normalizeIgnorableWS = tokenize == true && roundtripSupported == false; + final boolean normalizeIgnorableWS = tokenize && !roundtripSupported; boolean normalizedCR = false; try { @@ -2077,19 +2077,12 @@ else if ( ch == '\n' ) { reachedEnd = true; } - if ( reachedEnd ) - { - if ( tokenize && gotS ) - { - posEnd = pos; // well - this is LAST available character pos - return eventType = IGNORABLE_WHITESPACE; - } - return eventType = END_DOCUMENT; - } - else + if ( tokenize && gotS ) { - throw new XmlPullParserException( "internal error in parseEpilog" ); + posEnd = pos; // well - this is LAST available character pos + return eventType = IGNORABLE_WHITESPACE; } + return eventType = END_DOCUMENT; } public int parseEndTag() @@ -2258,7 +2251,6 @@ else if ( isNameStartChar( ch ) ) { ch = parseAttribute(); ch = more(); - continue; } else { @@ -2370,7 +2362,7 @@ else if ( isNameStartChar( ch ) ) return eventType = START_TAG; } - protected char parseAttribute() + private char parseAttribute() throws XmlPullParserException, IOException { // parse attribute @@ -2691,9 +2683,9 @@ else if ( ch == '\t' || ch == '\n' || ch == '\r' ) return ch; } - protected char[] charRefOneCharBuf = new char[1]; + private char[] charRefOneCharBuf = new char[1]; - protected char[] parseEntityRef() + private char[] parseEntityRef() throws XmlPullParserException, IOException { // entity reference http://www.w3.org/TR/2000/REC-xml-20001006#NT-Reference @@ -2769,7 +2761,7 @@ else if ( ch >= 'A' && ch <= 'F' ) posEnd = pos - 1; try { - charRefOneCharBuf = toChars( Integer.parseInt( sb.toString(), isHex ? 16 : 10 ) ); + charRefOneCharBuf = Character.toChars( Integer.parseInt( sb.toString(), isHex ? 16 : 10 ) ); } catch ( IllegalArgumentException e ) { @@ -2873,7 +2865,7 @@ else if ( len == 4 && buf[posStart] == 'q' && buf[posStart + 1] == 'u' && buf[po } } - protected char[] lookuEntityReplacement( int entityNameLen ) + private char[] lookuEntityReplacement( int entityNameLen ) throws XmlPullParserException, IOException { @@ -2913,7 +2905,7 @@ protected char[] lookuEntityReplacement( int entityNameLen ) return null; } - protected void parseComment() + private void parseComment() throws XmlPullParserException, IOException { // implements XML 1.0 Section 2.5 Comments @@ -2929,7 +2921,7 @@ protected void parseComment() final int curColumn = columnNumber; try { - final boolean normalizeIgnorableWS = tokenize == true && roundtripSupported == false; + final boolean normalizeIgnorableWS = tokenize && !roundtripSupported; boolean normalizedCR = false; boolean seenDash = false; @@ -2952,7 +2944,6 @@ protected void parseComment() else { seenDashDash = true; - seenDash = false; } } else if ( ch == '>' ) @@ -2961,10 +2952,6 @@ else if ( ch == '>' ) { break; // found end sequence!!!! } - else - { - seenDashDash = false; - } seenDash = false; } else @@ -3037,7 +3024,7 @@ else if ( ch == '\n' ) } } - protected boolean parsePI() + private boolean parsePI() throws XmlPullParserException, IOException { // implements XML 1.0 Section 2.6 Processing Instructions @@ -3051,7 +3038,7 @@ protected boolean parsePI() final int curColumn = columnNumber; int piTargetStart = pos; int piTargetEnd = -1; - final boolean normalizeIgnorableWS = tokenize == true && roundtripSupported == false; + final boolean normalizeIgnorableWS = tokenize && !roundtripSupported; boolean normalizedCR = false; try @@ -3211,17 +3198,17 @@ else if ( ch == '\n' ) // protected final static char[] YES = {'y','e','s'}; // protected final static char[] NO = {'n','o'}; - protected final static char[] VERSION = "version".toCharArray(); + private final static char[] VERSION = "version".toCharArray(); - protected final static char[] NCODING = "ncoding".toCharArray(); + private final static char[] NCODING = "ncoding".toCharArray(); - protected final static char[] TANDALONE = "tandalone".toCharArray(); + private final static char[] TANDALONE = "tandalone".toCharArray(); - protected final static char[] YES = "yes".toCharArray(); + private final static char[] YES = "yes".toCharArray(); - protected final static char[] NO = "no".toCharArray(); + private final static char[] NO = "no".toCharArray(); - protected void parseXmlDecl( char ch ) + private void parseXmlDecl( char ch ) throws XmlPullParserException, IOException { // [23] XMLDecl ::= '' @@ -3269,9 +3256,9 @@ protected void parseXmlDecl( char ch ) parseXmlDeclWithVersion( versionStart, versionEnd ); preventBufferCompaction = false; // allow again buffer compaction - pos MAY change } - // protected String xmlDeclVersion; + // private String xmlDeclVersion; - protected void parseXmlDeclWithVersion( int versionStart, int versionEnd ) + private void parseXmlDeclWithVersion( int versionStart, int versionEnd ) throws XmlPullParserException, IOException { // check version is "1.0" @@ -3390,7 +3377,7 @@ else if ( ch == 'n' ) } - protected void parseDocdecl() + private void parseDocdecl() throws XmlPullParserException, IOException { // ASSUMPTION: seen ' int bracketLevel = 0; - final boolean normalizeIgnorableWS = tokenize == true && roundtripSupported == false; + final boolean normalizeIgnorableWS = tokenize && !roundtripSupported; boolean normalizedCR = false; while ( true ) { @@ -3481,7 +3468,7 @@ else if ( ch == '\n' ) posEnd = pos - 1; } - protected void parseCDSect( boolean hadCharData ) + private void parseCDSect( boolean hadCharData ) throws XmlPullParserException, IOException { // implements XML 1.0 Section 2.7 CDATA Sections @@ -3515,7 +3502,7 @@ protected void parseCDSect( boolean hadCharData ) final int cdStart = pos + bufAbsoluteStart; final int curLine = lineNumber; final int curColumn = columnNumber; - final boolean normalizeInput = tokenize == false || roundtripSupported == false; + final boolean normalizeInput = !tokenize || !roundtripSupported; try { if ( normalizeInput ) @@ -3640,7 +3627,7 @@ else if ( ch == '\n' ) posEnd = pos - 3; } - protected void fillBuf() + private void fillBuf() throws IOException, XmlPullParserException { if ( reader == null ) @@ -3650,28 +3637,9 @@ protected void fillBuf() if ( bufEnd > bufSoftLimit ) { - // expand buffer it makes sense!!!! - boolean compact = bufStart > bufSoftLimit; - boolean expand = false; - if ( preventBufferCompaction ) - { - compact = false; - expand = true; - } - else if ( !compact ) - { - // freeSpace - if ( bufStart < buf.length / 2 ) - { - // less then half buffer available for compacting --> expand instead!!! - expand = true; - } - else - { - // at least half of buffer can be reclaimed --> worthwhile effort!!! - compact = true; - } - } + // check if we need to compact or expand the buffer + boolean compact = !preventBufferCompaction + && ( bufStart > bufSoftLimit || bufStart >= buf.length / 2 ); // if buffer almost full then compact it if ( compact ) @@ -3682,13 +3650,13 @@ else if ( !compact ) if ( TRACE_SIZING ) System.out.println( "TRACE_SIZING fillBuf() compacting " + bufStart + " bufEnd=" + bufEnd + " pos=" + pos + " posStart=" + posStart + " posEnd=" + posEnd + " buf first 100 chars:" - + new String( buf, bufStart, bufEnd - bufStart < 100 ? bufEnd - bufStart : 100 ) ); + + new String( buf, bufStart, Math.min(bufEnd - bufStart, 100)) ); } - else if ( expand ) + else { final int newSize = 2 * buf.length; - final char newBuf[] = new char[newSize]; + final char[] newBuf = new char[newSize]; if ( TRACE_SIZING ) System.out.println( "TRACE_SIZING fillBuf() " + buf.length + " => " + newSize ); System.arraycopy( buf, bufStart, newBuf, 0, bufEnd - bufStart ); @@ -3700,10 +3668,6 @@ else if ( expand ) } } - else - { - throw new XmlPullParserException( "internal error in fillBuffer()" ); - } bufEnd -= bufStart; pos -= bufStart; posStart -= bufStart; @@ -3713,17 +3677,17 @@ else if ( expand ) if ( TRACE_SIZING ) System.out.println( "TRACE_SIZING fillBuf() after bufEnd=" + bufEnd + " pos=" + pos + " posStart=" + posStart + " posEnd=" + posEnd + " buf first 100 chars:" - + new String( buf, 0, bufEnd < 100 ? bufEnd : 100 ) ); + + new String( buf, 0, Math.min(bufEnd, 100)) ); } // at least one character must be read or error - final int len = buf.length - bufEnd > READ_CHUNK_SIZE ? READ_CHUNK_SIZE : buf.length - bufEnd; + final int len = Math.min(buf.length - bufEnd, READ_CHUNK_SIZE); final int ret = reader.read( buf, bufEnd, len ); if ( ret > 0 ) { bufEnd += ret; if ( TRACE_SIZING ) System.out.println( "TRACE_SIZING fillBuf() after filling in buffer" + " buf first 100 chars:" - + new String( buf, 0, bufEnd < 100 ? bufEnd : 100 ) ); + + new String( buf, 0, Math.min(bufEnd, 100)) ); return; } @@ -3808,7 +3772,7 @@ else if ( expand ) } } - protected char more() + private char more() throws IOException, XmlPullParserException { if ( pos >= bufEnd ) @@ -3843,7 +3807,7 @@ protected char more() // return pos + bufAbsoluteStart; // } - protected void ensurePC( int end ) + private void ensurePC( int end ) { // assert end >= pc.length; final int newSize = end > READ_CHUNK_SIZE ? 2 * end : 2 * READ_CHUNK_SIZE; @@ -3855,7 +3819,7 @@ protected void ensurePC( int end ) // assert end < pc.length; } - protected void joinPC() + private void joinPC() { // assert usePC == false; // assert posEnd > posStart; @@ -3870,7 +3834,7 @@ protected void joinPC() } - protected char requireInput( char ch, char[] input ) + private char requireInput( char ch, char[] input ) throws XmlPullParserException, IOException { for ( char anInput : input ) @@ -3885,7 +3849,7 @@ protected char requireInput( char ch, char[] input ) return ch; } - protected char requireNextS() + private char requireNextS() throws XmlPullParserException, IOException { final char ch = more(); @@ -3896,7 +3860,7 @@ protected char requireNextS() return skipS( ch ); } - protected char skipS( char ch ) + private char skipS( char ch ) throws XmlPullParserException, IOException { while ( isS( ch ) ) @@ -3907,23 +3871,23 @@ protected char skipS( char ch ) } // nameStart / name lookup tables based on XML 1.1 http://www.w3.org/TR/2001/WD-xml11-20011213/ - protected static final int LOOKUP_MAX = 0x400; + private static final int LOOKUP_MAX = 0x400; - protected static final char LOOKUP_MAX_CHAR = (char) LOOKUP_MAX; + private static final char LOOKUP_MAX_CHAR = (char) LOOKUP_MAX; - // protected static int lookupNameStartChar[] = new int[ LOOKUP_MAX_CHAR / 32 ]; - // protected static int lookupNameChar[] = new int[ LOOKUP_MAX_CHAR / 32 ]; - protected static boolean lookupNameStartChar[] = new boolean[LOOKUP_MAX]; + // private static int lookupNameStartChar[] = new int[ LOOKUP_MAX_CHAR / 32 ]; + // private static int lookupNameChar[] = new int[ LOOKUP_MAX_CHAR / 32 ]; + private static final boolean[] lookupNameStartChar = new boolean[LOOKUP_MAX]; - protected static boolean lookupNameChar[] = new boolean[LOOKUP_MAX]; + private static final boolean[] lookupNameChar = new boolean[LOOKUP_MAX]; - private static final void setName( char ch ) + private static void setName( char ch ) // { lookupNameChar[ (int)ch / 32 ] |= (1 << (ch % 32)); } { lookupNameChar[ch] = true; } - private static final void setNameStart( char ch ) + private static void setNameStart( char ch ) // { lookupNameStartChar[ (int)ch / 32 ] |= (1 << (ch % 32)); setName(ch); } { lookupNameStartChar[ch] = true; @@ -3954,10 +3918,10 @@ private static final void setNameStart( char ch ) setName( ch ); } - // private final static boolean isNameStartChar(char ch) { - protected boolean isNameStartChar( char ch ) + // protected boolean isNameStartChar( char ch ) + private static boolean isNameStartChar( char ch ) { - return ( ch < LOOKUP_MAX_CHAR && lookupNameStartChar[ch] ) || ( ch >= LOOKUP_MAX_CHAR && ch <= '\u2027' ) + return ch < LOOKUP_MAX_CHAR ? lookupNameStartChar[ch] : ( ch <= '\u2027' ) || ( ch >= '\u202A' && ch <= '\u218F' ) || ( ch >= '\u2800' && ch <= '\uFFEF' ); // if(ch < LOOKUP_MAX_CHAR) return lookupNameStartChar[ ch ]; @@ -3981,14 +3945,14 @@ protected boolean isNameStartChar( char ch ) // else return (supportXml11 && ( (ch < '\u2027') || (ch > '\u2029' && ch < '\u2200') ... } - // private final static boolean isNameChar(char ch) { - protected boolean isNameChar( char ch ) + // protected boolean isNameChar( char ch ) + private static boolean isNameChar( char ch ) { // return isNameStartChar(ch); // if(ch < LOOKUP_MAX_CHAR) return (lookupNameChar[ (int)ch / 32 ] & (1 << (ch % 32))) != 0; - return ( ch < LOOKUP_MAX_CHAR && lookupNameChar[ch] ) || ( ch >= LOOKUP_MAX_CHAR && ch <= '\u2027' ) + return ch < LOOKUP_MAX_CHAR ? lookupNameChar[ch] : ( ch <= '\u2027' ) || ( ch >= '\u202A' && ch <= '\u218F' ) || ( ch >= '\u2800' && ch <= '\uFFEF' ); // return false; // return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == ':' @@ -4006,7 +3970,7 @@ protected boolean isNameChar( char ch ) // else return false; } - protected boolean isS( char ch ) + private static boolean isS( char ch ) { return ( ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' ); // || (supportXml11 && (ch == '\u0085' || ch == '\u2028'); @@ -4015,8 +3979,8 @@ protected boolean isS( char ch ) // protected boolean isChar(char ch) { return (ch < '\uD800' || ch > '\uDFFF') // ch != '\u0000' ch < '\uFFFE' - // protected char printable(char ch) { return ch; } - protected String printable( char ch ) + // private char printable(char ch) { return ch; } + private static String printable( char ch ) { if ( ch == '\n' ) { @@ -4041,7 +4005,7 @@ else if ( ch == '\'' ) return "" + ch; } - protected String printable( String s ) + private static String printable( String s ) { if ( s == null ) return null; @@ -4055,69 +4019,6 @@ protected String printable( String s ) return s; } - // - // Imported code from ASF Harmony project rev 770909 - // http://svn.apache.org/repos/asf/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/Character.java - // - - private static int toCodePoint( char high, char low ) - { - // See RFC 2781, Section 2.2 - // http://www.faqs.org/rfcs/rfc2781.html - int h = ( high & 0x3FF ) << 10; - int l = low & 0x3FF; - return ( h | l ) + 0x10000; - } - - private static final char MIN_HIGH_SURROGATE = '\uD800'; - - private static final char MAX_HIGH_SURROGATE = '\uDBFF'; - - private static boolean isHighSurrogate( char ch ) - { - return ( MIN_HIGH_SURROGATE <= ch && MAX_HIGH_SURROGATE >= ch ); - } - - private static final int MAX_CODE_POINT = 0x10FFFF; - - private static final int MIN_SUPPLEMENTARY_CODE_POINT = 0x10000; - - /** - * Check if the provided parameter is a valid Char, according to: {@link https://www.w3.org/TR/REC-xml/#NT-Char} - * - * @param codePoint the numeric value to check - * @return true if it is a valid numeric character reference. False otherwise. - */ - private static boolean isValidCodePoint( int codePoint ) - { - // Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] - return codePoint == 0x9 || codePoint == 0xA || codePoint == 0xD || ( 0x20 <= codePoint && codePoint <= 0xD7FF ) - || ( 0xE000 <= codePoint && codePoint <= 0xFFFD ) || ( 0x10000 <= codePoint && codePoint <= 0x10FFFF ); - } - - private static boolean isSupplementaryCodePoint( int codePoint ) - { - return ( MIN_SUPPLEMENTARY_CODE_POINT <= codePoint && MAX_CODE_POINT >= codePoint ); - } - - // TODO add javadoc - public static char[] toChars( int codePoint ) - { - if ( !isValidCodePoint( codePoint ) ) - { - throw new IllegalArgumentException(); - } - - if ( isSupplementaryCodePoint( codePoint ) ) - { - int cpPrime = codePoint - 0x10000; - int high = 0xD800 | ( ( cpPrime >> 10 ) & 0x3FF ); - int low = 0xDC00 | ( cpPrime & 0x3FF ); - return new char[] { (char) high, (char) low }; - } - - return new char[] { (char) codePoint }; - } } /* diff --git a/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserPerfTest.java b/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserPerfTest.java new file mode 100644 index 00000000..934f8083 --- /dev/null +++ b/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserPerfTest.java @@ -0,0 +1,79 @@ +package org.codehaus.plexus.util.xml.pull; + +/* + * Copyright The Codehaus Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.TimeUnit; + +import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.codehaus.plexus.util.xml.Xpp3DomBuilder; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; +import org.openjdk.jmh.runner.options.TimeValue; + +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Warmup(iterations = 3, time = 3, timeUnit = TimeUnit.SECONDS) +public class MXParserPerfTest { + + @State(Scope.Benchmark) + static public class AdditionState { + + byte[] data; + + @Setup(Level.Iteration) + public void setUp() throws IOException, XmlPullParserException { + try (InputStream buf = getClass().getResourceAsStream( "/xml/pom.xml" ) ) + { + data = new byte[ buf.available() ]; + buf.read( data, 0, data.length ); + } + } + } + + + @Benchmark + public Xpp3Dom benchmarkBuild( AdditionState state ) throws IOException, XmlPullParserException + { + return Xpp3DomBuilder.build( new ByteArrayInputStream( state.data ), null ); + } + + public static void main( String... args ) + throws RunnerException + { + Options opts = new OptionsBuilder() + .measurementIterations( 3 ) + .measurementTime( TimeValue.milliseconds( 3000 ) ) + .forks( 1 ) + .include( "org.codehaus.plexus.util.xml.pull.MXParserPerfTest" ) + .build(); + new Runner( opts ).run(); + } +} diff --git a/src/test/resources/xml/pom.xml b/src/test/resources/xml/pom.xml new file mode 100644 index 00000000..6aa94399 --- /dev/null +++ b/src/test/resources/xml/pom.xml @@ -0,0 +1,140 @@ + + + + + + 4.0.0 + + + org.codehaus.plexus + plexus + 6.5 + + + plexus-utils + 3.4.0-SNAPSHOT + + Plexus Common Utilities + A collection of various utility classes to ease working with strings, files, command lines, XML and + more. + + + + scm:git:git@github.com:codehaus-plexus/plexus-utils.git + scm:git:git@github.com:codehaus-plexus/plexus-utils.git + http://github.com/codehaus-plexus/plexus-utils + HEAD + + + github + http://github.com/codehaus-plexus/plexus-utils/issues + + + + github:gh-pages + ${project.scm.developerConnection} + + + + + 2020-01-20T18:52:37Z + + + + + org.apache.maven.shared + maven-plugin-testing-harness + 1.1 + test + + + org.openjdk.jmh + jmh-core + 1.26 + test + + + org.openjdk.jmh + jmh-generator-annprocess + 1.26 + test + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + + 2.7 + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.2.0 + + + + + + org.apache.maven.plugins + maven-scm-publish-plugin + + ${project.reporting.outputDirectory} + + + + scm-publish + site-deploy + + publish-scm + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + true + + org/codehaus/plexus/util/FileBasedTestCase.java + **/Test*.java + + + + JAVA_HOME + ${JAVA_HOME} + + + M2_HOME + ${M2_HOME} + + + + + + + +