antoine 2003/07/14 13:21:12 Modified: . WHATSNEW src/main/org/apache/tools/ant DirectoryScanner.java src/main/org/apache/tools/ant/types/selectors SelectorUtils.java Log: Optimize DirectoryScanner to take advantage of include patterns which are not beginning with wildcards PR: 20103 Revision Changes Path 1.457 +3 -0 ant/WHATSNEW Index: WHATSNEW =================================================================== RCS file: /home/cvs/ant/WHATSNEW,v retrieving revision 1.456 retrieving revision 1.457 diff -u -r1.456 -r1.457 --- WHATSNEW 11 Jul 2003 21:25:35 -0000 1.456 +++ WHATSNEW 14 Jul 2003 20:21:06 -0000 1.457 @@ -486,6 +486,9 @@ * OpenVMS is detected as a valid OS family. +* DirectoryScanner has been optimized for cases where include patterns do not start with wildcards + Bugzilla Report 20103. + Changes from Ant 1.5.2 to Ant 1.5.3 =================================== 1.43 +105 -34 ant/src/main/org/apache/tools/ant/DirectoryScanner.java Index: DirectoryScanner.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/DirectoryScanner.java,v retrieving revision 1.42 retrieving revision 1.43 diff -u -r1.42 -r1.43 --- DirectoryScanner.java 6 Jul 2003 09:57:34 -0000 1.42 +++ DirectoryScanner.java 14 Jul 2003 20:21:10 -0000 1.43 @@ -57,6 +57,9 @@ import java.io.File; import java.io.IOException; import java.util.Vector; +import java.util.Hashtable; +import java.util.Enumeration; + import org.apache.tools.ant.types.Resource; import org.apache.tools.ant.types.ResourceFactory; import org.apache.tools.ant.types.selectors.FileSelector; @@ -639,9 +642,59 @@ } else { dirsNotIncluded.addElement(""); } - scandir(basedir, "", true); + checkIncludePatterns(); + } + /** + * this routine is actually checking all the include patterns + * in order to avoid scanning everything under base dir + * @since ant1.6 + */ + private void checkIncludePatterns() { + Hashtable newroots = new Hashtable(); + // put in the newroots vector the include patterns without wildcard tokens + for (int icounter=0; icounter<includes.length; icounter++) { + String newpattern=SelectorUtils.rtrimWildcardTokens(includes[icounter]); + // check whether the candidate new pattern has a parent + boolean hasParent=false; + Enumeration myenum = newroots.keys(); + while (myenum.hasMoreElements()) { + String existingpattern=(String)myenum.nextElement(); + if (existingpattern.length() <= newpattern.length()) { + if (newpattern.indexOf(existingpattern)==0) { + hasParent=true; + } + } + } + if ( !hasParent) { + newroots.put(newpattern,includes[icounter]); + } + } + Enumeration enum2 = newroots.keys(); + while (enum2.hasMoreElements()) { + String currentelement = (String) enum2.nextElement(); + File myfile=new File(basedir,currentelement); + if (myfile.exists()) { + if (myfile.isDirectory()) { + if (isIncluded(currentelement) && currentelement.length()>0) { + accountForIncludedDir(currentelement,myfile,true); + } else { + if (currentelement.length() > 0) { + if (currentelement.charAt(currentelement.length()-1) != File.separatorChar) { + currentelement = currentelement + File.separatorChar; + } + } + scandir(myfile, currentelement, true); + } + } + else { + String originalpattern=(String)newroots.get(currentelement); + if (originalpattern.equals(currentelement)) { + accountForIncludedFile(currentelement,myfile); + } + } + } + } } - /** * Top level invocation for a slow scan. A slow scan builds up a full * list of excluded/included files/directories, whereas a fast scan @@ -745,27 +798,7 @@ File file = new File(dir, newfiles[i]); if (file.isDirectory()) { if (isIncluded(name)) { - if (!isExcluded(name)) { - if (isSelected(name, file)) { - dirsIncluded.addElement(name); - if (fast) { - scandir(file, name + File.separator, fast); - } - } else { - everythingIncluded = false; - dirsDeselected.addElement(name); - if (fast && couldHoldIncluded(name)) { - scandir(file, name + File.separator, fast); - } - } - - } else { - everythingIncluded = false; - dirsExcluded.addElement(name); - if (fast && couldHoldIncluded(name)) { - scandir(file, name + File.separator, fast); - } - } + accountForIncludedDir(name, file, fast); } else { everythingIncluded = false; dirsNotIncluded.addElement(name); @@ -778,17 +811,7 @@ } } else if (file.isFile()) { if (isIncluded(name)) { - if (!isExcluded(name)) { - if (isSelected(name, file)) { - filesIncluded.addElement(name); - } else { - everythingIncluded = false; - filesDeselected.addElement(name); - } - } else { - everythingIncluded = false; - filesExcluded.addElement(name); - } + accountForIncludedFile(name, file); } else { everythingIncluded = false; filesNotIncluded.addElement(name); @@ -796,7 +819,55 @@ } } } + /** + * process included file + * @param name path of the file relative to the directory of the fileset + * @param file included file + */ + private void accountForIncludedFile(String name, File file) { + if (!isExcluded(name)) { + if (isSelected(name, file)) { + filesIncluded.addElement(name); + } else { + everythingIncluded = false; + filesDeselected.addElement(name); + } + } else { + everythingIncluded = false; + filesExcluded.addElement(name); + } + + } + /** + * + * @param name path of the directory relative to the directory of the fileset + * @param file directory as file + * @param fast + */ + private void accountForIncludedDir(String name, File file, boolean fast) { + if (!isExcluded(name)) { + if (isSelected(name, file)) { + dirsIncluded.addElement(name); + if (fast) { + scandir(file, name + File.separator, fast); + } + } else { + everythingIncluded = false; + dirsDeselected.addElement(name); + if (fast && couldHoldIncluded(name)) { + scandir(file, name + File.separator, fast); + } + } + + } else { + everythingIncluded = false; + dirsExcluded.addElement(name); + if (fast && couldHoldIncluded(name)) { + scandir(file, name + File.separator, fast); + } + } + } /** * Tests whether or not a name matches against at least one include * pattern. 1.12 +50 -11 ant/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java Index: SelectorUtils.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- SelectorUtils.java 4 Jul 2003 23:18:49 -0000 1.11 +++ SelectorUtils.java 14 Jul 2003 20:21:11 -0000 1.12 @@ -526,16 +526,29 @@ * * @param path Path to tokenize. Must not be <code>null</code>. * - * @return a Vector of path elements from the tokenized path - */ - public static Vector tokenizePath(String path) { - Vector ret = new Vector(); - StringTokenizer st = new StringTokenizer(path, File.separator); - while (st.hasMoreTokens()) { - ret.addElement(st.nextToken()); - } - return ret; - } + * @return a Vector of path elements from the tokenized path + */ + public static Vector tokenizePath (String path) { + return tokenizePath(path, File.separator); + } + /** + * Breaks a path up into a Vector of path elements, tokenizing on + * + * @param path Path to tokenize. Must not be <code>null</code>. + * @param separator the separator against which to tokenize. + * + * @return a Vector of path elements from the tokenized path + * @since ant 1.6 + */ + public static Vector tokenizePath (String path, String separator) { + Vector ret = new Vector(); + StringTokenizer st = new StringTokenizer(path,separator); + while (st.hasMoreTokens()) { + ret.addElement(st.nextToken()); + } + return ret; + + } /** * Same as [EMAIL PROTECTED] #tokenizePath tokenizePath} but hopefully faster. @@ -649,6 +662,32 @@ } return result.toString(); } - + /** + * Tests if a string contains stars or question marks + * @param input a String which one wants to test for containing wildcard + * @return true if the string contains at least a star or a question mark + */ + public static boolean hasWildcards(String input) { + return (input.indexOf('*')!=-1 || input.indexOf('?')!=-1); + } + /** + * removes from a pattern all tokens to the right containing wildcards + * @param input + * @return the leftmost part of the pattern without wildcards + */ + public static String rtrimWildcardTokens(String input) { + Vector v = tokenizePath(input, File.separator); + StringBuffer sb = new StringBuffer(); + for (int counter=0; counter < v.size() ; counter++) { + if ( hasWildcards((String)v.elementAt(counter))) { + break; + } + if (counter >0) { + sb.append(File.separator); + } + sb.append((String)v.elementAt(counter)); + } + return sb.toString(); + } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]