Please, don't hesitate to comment this change. In particular, I'm not sure where to place the PathPattern class. I currently put it in org/apache/tools/ant/types/selectors so that I don't have to make the methods of SelectorUtils public, but I feel like it is not the right package. I'm worndering if something only visible to the DirectoryScanner wouldn't be better. WDYT ?
By the way, I also removed some explicit nulling. I don't think they offered any performance gain. Did they? 2008/8/21 <[EMAIL PROTECTED]>: > Author: gscokart > Date: Thu Aug 21 07:18:59 2008 > New Revision: 687768 > > URL: http://svn.apache.org/viewvc?rev=687768&view=rev > Log: > Enhance performance of DirectoryScanner by parsing the patterns only once. > Introduce a PathPattern to do that. (# 44226) > > Added: > > ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/PathPattern.java > (with props) > Modified: > ant/core/trunk/WHATSNEW > ant/core/trunk/src/main/org/apache/tools/ant/DirectoryScanner.java > > ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java > > Modified: ant/core/trunk/WHATSNEW > URL: > http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?rev=687768&r1=687767&r2=687768&view=diff > ============================================================================== > --- ant/core/trunk/WHATSNEW (original) > +++ ant/core/trunk/WHATSNEW Thu Aug 21 07:18:59 2008 > @@ -1,4 +1,4 @@ > -Changes from Ant 1.7.x TO current SVN version > +eol-styleChanges from Ant 1.7.x TO current SVN version > ============================================= > > Changes that could break older environments: > @@ -158,8 +158,6 @@ > filter tokens > Bugzilla Report 44226. > > - * Enhance performance of Project.fireMessageLoggedEvent > - Bugzilla Report 45651. > > Other changes: > -------------- > @@ -274,6 +272,9 @@ > expression. > Bugzilla Report 45284 > > + * Enhanced performance of Project.fireMessageLoggedEvent and > DirectoryScanner > + Bugzilla Report 45651 & 45665 > + > * The package list location for offline links can now be specified as > an URL. > Bugzilla Report 28881 > > Modified: ant/core/trunk/src/main/org/apache/tools/ant/DirectoryScanner.java > URL: > http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/DirectoryScanner.java?rev=687768&r1=687767&r2=687768&view=diff > ============================================================================== > --- ant/core/trunk/src/main/org/apache/tools/ant/DirectoryScanner.java > (original) > +++ ant/core/trunk/src/main/org/apache/tools/ant/DirectoryScanner.java Thu > Aug 21 07:18:59 2008 > @@ -34,6 +34,7 @@ > import org.apache.tools.ant.types.ResourceFactory; > import org.apache.tools.ant.types.resources.FileResource; > import org.apache.tools.ant.types.selectors.FileSelector; > +import org.apache.tools.ant.types.selectors.PathPattern; > import org.apache.tools.ant.types.selectors.SelectorScanner; > import org.apache.tools.ant.types.selectors.SelectorUtils; > import org.apache.tools.ant.util.FileUtils; > @@ -319,10 +320,8 @@ > * <p>Gets lazily initialized on the first invocation of > * isIncluded or isExcluded and cleared at the end of the scan > * method (cleared in clearCaches, actually).</p> > - * > - * @since Ant 1.6.3 > */ > - private String[] includePatterns; > + private PathPattern[] includePatterns; > > /** > * Array of all exclude patterns that contain wildcards. > @@ -330,10 +329,8 @@ > * <p>Gets lazily initialized on the first invocation of > * isIncluded or isExcluded and cleared at the end of the scan > * method (cleared in clearCaches, actually).</p> > - * > - * @since Ant 1.6.3 > */ > - private String[] excludePatterns; > + private PathPattern[] excludePatterns; > > /** > * Have the non-pattern sets and pattern arrays for in- and > @@ -1196,7 +1193,7 @@ > return true; > } > for (int i = 0; i < includePatterns.length; i++) { > - if (matchPath(includePatterns[i], name, isCaseSensitive())) { > + if (includePatterns[i].matchPath(name, isCaseSensitive())) { > return true; > } > } > @@ -1296,7 +1293,7 @@ > return true; > } > for (int i = 0; i < excludePatterns.length; i++) { > - if (matchPath(excludePatterns[i], name, isCaseSensitive())) { > + if (excludePatterns[i].matchPath(name, isCaseSensitive())) { > return true; > } > } > @@ -1696,18 +1693,17 @@ > * @param patterns String[] of patterns. > * @since Ant 1.6.3 > */ > - private String[] fillNonPatternSet(Set set, String[] patterns) { > + private PathPattern[] fillNonPatternSet(Set set, String[] patterns) { > ArrayList al = new ArrayList(patterns.length); > for (int i = 0; i < patterns.length; i++) { > if (!SelectorUtils.hasWildcards(patterns[i])) { > set.add(isCaseSensitive() ? patterns[i] > : patterns[i].toUpperCase()); > } else { > - al.add(patterns[i]); > + al.add(new PathPattern(patterns[i])); > } > } > - return set.size() == 0 ? patterns > - : (String[]) al.toArray(new String[al.size()]); > + return (PathPattern[]) al.toArray(new PathPattern[al.size()]); > } > > } > > Added: > ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/PathPattern.java > URL: > http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/PathPattern.java?rev=687768&view=auto > ============================================================================== > --- > ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/PathPattern.java > (added) > +++ > ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/PathPattern.java > Thu Aug 21 07:18:59 2008 > @@ -0,0 +1,82 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one or more > + * contributor license agreements. See the NOTICE file distributed with > + * this work for additional information regarding copyright ownership. > + * The ASF licenses this file to You 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. > + * > + */ > + > +package org.apache.tools.ant.types.selectors; > + > +/** > + * Provides reusable path pattern matching. PathPattern is preferable to > equivalent > + * SelectorUtils methods if you need to execute multiple matching with the > same pattern > + * because here the pattern itself will be parsed only once. > + * @see SelectorUtils#matchPath(String, String) > + * @see SelectorUtils#matchPath(String, String, boolean) > + * @since 1.8 > + */ > +public class PathPattern { > + > + private final String pattern; > + private final String tokenizedPattern[]; > + > + /** > + * Initialize the PathPattern by parsing it. > + * @param pattern The pattern to match against. Must not be > + * <code>null</code>. > + */ > + public PathPattern(String pattern) { > + this.pattern = pattern; > + this.tokenizedPattern = SelectorUtils.tokenizePathAsArray(pattern); > + } > + > + /** > + * Tests whether or not a given path matches a given pattern. > + * > + * @param str The path to match, as a String. Must not be > + * <code>null</code>. > + * > + * @return <code>true</code> if the pattern matches against the string, > + * or <code>false</code> otherwise. > + */ > + public boolean matchPath(String str) { > + return SelectorUtils.matchPath(tokenizedPattern, str, true); > + } > + > + /** > + * Tests whether or not a given path matches a given pattern. > + * > + * @param str The path to match, as a String. Must not be > + * <code>null</code>. > + * @param isCaseSensitive Whether or not matching should be performed > + * case sensitively. > + * > + * @return <code>true</code> if the pattern matches against the string, > + * or <code>false</code> otherwise. > + */ > + public boolean matchPath(String str, boolean isCaseSensitive) { > + return SelectorUtils.matchPath(tokenizedPattern, str, > isCaseSensitive); > + } > + > + /** > + * @return The pattern String > + */ > + public String toString() { > + return pattern; > + } > + > + public String getPattern() { > + return pattern; > + } > +} > > Propchange: > ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/PathPattern.java > ------------------------------------------------------------------------------ > svn:eol-style = native > > Modified: > ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java > URL: > http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java?rev=687768&r1=687767&r2=687768&view=diff > ============================================================================== > --- > ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java > (original) > +++ > ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java > Thu Aug 21 07:18:59 2008 > @@ -38,7 +38,7 @@ > */ > public final class SelectorUtils { > > - private static SelectorUtils instance = new SelectorUtils(); > + private static final SelectorUtils instance = new SelectorUtils(); > private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); > > /** > @@ -144,6 +144,11 @@ > /** > * Tests whether or not a given path matches a given pattern. > * > + * If you need to call this method multiple times with the same > + * pattern you should rather use PathPattern > + * > + * @see PathPattern > + * > * @param pattern The pattern to match against. Must not be > * <code>null</code>. > * @param str The path to match, as a String. Must not be > @@ -153,12 +158,18 @@ > * or <code>false</code> otherwise. > */ > public static boolean matchPath(String pattern, String str) { > - return matchPath(pattern, str, true); > + String[] patDirs = tokenizePathAsArray(pattern); > + return matchPath(patDirs, str, true); > } > > /** > * Tests whether or not a given path matches a given pattern. > + * > + * If you need to call this method multiple times with the same > + * pattern you should rather use PathPattern > * > + * @see PathPattern > + * > * @param pattern The pattern to match against. Must not be > * <code>null</code>. > * @param str The path to match, as a String. Must not be > @@ -172,22 +183,28 @@ > public static boolean matchPath(String pattern, String str, > boolean isCaseSensitive) { > String[] patDirs = tokenizePathAsArray(pattern); > + return matchPath(patDirs, str, isCaseSensitive); > + } > + > + /** > + * Core implementation of matchPath. It is isolated so that it can be > called from > + * PathPattern. > + */ > + static boolean matchPath(String[] tokenizedPattern, String str, boolean > isCaseSensitive) { > String[] strDirs = tokenizePathAsArray(str); > > int patIdxStart = 0; > - int patIdxEnd = patDirs.length - 1; > + int patIdxEnd = tokenizedPattern.length - 1; > int strIdxStart = 0; > int strIdxEnd = strDirs.length - 1; > > // up to first '**' > while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) { > - String patDir = patDirs[patIdxStart]; > + String patDir = tokenizedPattern[patIdxStart]; > if (patDir.equals("**")) { > break; > } > if (!match(patDir, strDirs[strIdxStart], isCaseSensitive)) { > - patDirs = null; > - strDirs = null; > return false; > } > patIdxStart++; > @@ -196,9 +213,7 @@ > if (strIdxStart > strIdxEnd) { > // String is exhausted > for (int i = patIdxStart; i <= patIdxEnd; i++) { > - if (!patDirs[i].equals("**")) { > - patDirs = null; > - strDirs = null; > + if (!tokenizedPattern[i].equals("**")) { > return false; > } > } > @@ -206,21 +221,17 @@ > } else { > if (patIdxStart > patIdxEnd) { > // String not exhausted, but pattern is. Failure. > - patDirs = null; > - strDirs = null; > return false; > } > } > > // up to last '**' > while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) { > - String patDir = patDirs[patIdxEnd]; > + String patDir = tokenizedPattern[patIdxEnd]; > if (patDir.equals("**")) { > break; > } > if (!match(patDir, strDirs[strIdxEnd], isCaseSensitive)) { > - patDirs = null; > - strDirs = null; > return false; > } > patIdxEnd--; > @@ -229,9 +240,7 @@ > if (strIdxStart > strIdxEnd) { > // String is exhausted > for (int i = patIdxStart; i <= patIdxEnd; i++) { > - if (!patDirs[i].equals("**")) { > - patDirs = null; > - strDirs = null; > + if (!tokenizedPattern[i].equals("**")) { > return false; > } > } > @@ -241,7 +250,7 @@ > while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) { > int patIdxTmp = -1; > for (int i = patIdxStart + 1; i <= patIdxEnd; i++) { > - if (patDirs[i].equals("**")) { > + if (tokenizedPattern[i].equals("**")) { > patIdxTmp = i; > break; > } > @@ -259,7 +268,7 @@ > strLoop: > for (int i = 0; i <= strLength - patLength; i++) { > for (int j = 0; j < patLength; j++) { > - String subPat = patDirs[patIdxStart + j + 1]; > + String subPat = tokenizedPattern[patIdxStart > + j + 1]; > String subStr = strDirs[strIdxStart + i + j]; > if (!match(subPat, subStr, isCaseSensitive)) { > continue strLoop; > @@ -271,8 +280,6 @@ > } > > if (foundIdx == -1) { > - patDirs = null; > - strDirs = null; > return false; > } > > @@ -281,9 +288,7 @@ > } > > for (int i = patIdxStart; i <= patIdxEnd; i++) { > - if (!patDirs[i].equals("**")) { > - patDirs = null; > - strDirs = null; > + if (!tokenizedPattern[i].equals("**")) { > return false; > } > } > @@ -507,7 +512,7 @@ > /** > * Same as [EMAIL PROTECTED] #tokenizePath tokenizePath} but hopefully > faster. > */ > - private static String[] tokenizePathAsArray(String path) { > + /*package*/ static String[] tokenizePathAsArray(String path) { > String root = null; > if (FileUtils.isAbsolutePath(path)) { > String[] s = FILE_UTILS.dissect(path); > > > -- Gilles Scokart --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]