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]

Reply via email to