You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by bo...@apache.org on 2008/09/17 17:45:13 UTC

svn commit: r696345 - in /ant/core/trunk/src/main/org/apache/tools/ant: DirectoryScanner.java types/selectors/TokenizedPath.java types/selectors/TokenizedPattern.java

Author: bodewig
Date: Wed Sep 17 08:45:13 2008
New Revision: 696345

URL: http://svn.apache.org/viewvc?rev=696345&view=rev
Log:
avoid redundant tokenization of non-wildcard include patterns as well.

Modified:
    ant/core/trunk/src/main/org/apache/tools/ant/DirectoryScanner.java
    ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java
    ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/TokenizedPattern.java

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=696345&r1=696344&r2=696345&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 Wed Sep 17 08:45:13 2008
@@ -294,9 +294,11 @@
     private Set scannedDirs = new HashSet();
 
     /**
-     * Set of all include patterns that are full file names and don't
+     * Map of all include patterns that are full file names and don't
      * contain any wildcards.
      *
+     * <p>Maps pattern string to TokenizedPath.</p>
+     *
      * <p>If this instance is not case sensitive, the file names get
      * turned to upper case.</p>
      *
@@ -304,14 +306,16 @@
      * isIncluded or isExcluded and cleared at the end of the scan
      * method (cleared in clearCaches, actually).</p>
      *
-     * @since Ant 1.6.3
+     * @since Ant 1.8.0
      */
-    private Set includeNonPatterns = new HashSet();
+    private Map includeNonPatterns = new HashMap();
 
     /**
-     * Set of all include patterns that are full file names and don't
+     * Map of all exclude patterns that are full file names and don't
      * contain any wildcards.
      *
+     * <p>Maps pattern string to TokenizedPath.</p>
+     *
      * <p>If this instance is not case sensitive, the file names get
      * turned to upper case.</p>
      *
@@ -319,9 +323,9 @@
      * isIncluded or isExcluded and cleared at the end of the scan
      * method (cleared in clearCaches, actually).</p>
      *
-     * @since Ant 1.6.3
+     * @since Ant 1.8.0
      */
-    private Set excludeNonPatterns = new HashSet();
+    private Map excludeNonPatterns = new HashMap();
 
     /**
      * Array of all include patterns that contain wildcards.
@@ -897,35 +901,25 @@
     private void checkIncludePatterns() {
         ensureNonPatternSetsReady();
         Map newroots = new HashMap();
+
         // put in the newroots map the include patterns without
         // wildcard tokens
-        int wildcardPatternIndex = 0;
-        for (int i = 0; i < includes.length; i++) {
-            boolean wildcards = SelectorUtils.hasWildcards(includes[i]);
-            if (FileUtils.isAbsolutePath(includes[i])) {
-                //skip abs. paths not under basedir, if set:
-                if (basedir != null
-                    && !SelectorUtils.matchPatternStart(includes[i],
-                    basedir.getAbsolutePath(), isCaseSensitive())) {
-                    if (wildcards) {
-                        wildcardPatternIndex++;
-                    }
-                    continue;
-                }
-            } else if (basedir == null) {
-                //skip non-abs. paths if basedir == null:
-                if (wildcards) {
-                    wildcardPatternIndex++;
-                }
-                continue;
+        for (int i = 0; i < includePatterns.length; i++) {
+            String pattern = includePatterns[i].toString();
+            if (!shouldSkipPattern(pattern)) {
+                newroots.put(includePatterns[i].rtrimWildcardTokens(),
+                             pattern);
             }
-            if (wildcards) {
-                newroots.put(includePatterns[wildcardPatternIndex++]
-                             .rtrimWildcardTokens(), includes[i]);
-            } else {
-                newroots.put(new TokenizedPath(includes[i]), includes[i]);
+        }
+        for (Iterator iter = includeNonPatterns.entrySet().iterator();
+             iter.hasNext(); ) {
+            Map.Entry entry = (Map.Entry) iter.next();
+            String pattern = (String) entry.getKey();
+            if (!shouldSkipPattern(pattern)) {
+                newroots.put((TokenizedPath) entry.getValue(), pattern);
             }
         }
+
         if (newroots.containsKey(TokenizedPath.EMPTY_PATH)
             && basedir != null) {
             // we are going to scan everything anyway
@@ -1018,6 +1012,28 @@
     }
 
     /**
+     * true if the pattern specifies a relative path without basedir
+     * or an absolute path not inside basedir.
+     *
+     * @since Ant 1.8.0
+     */
+    private boolean shouldSkipPattern(String pattern) {
+        if (FileUtils.isAbsolutePath(pattern)) {
+            //skip abs. paths not under basedir, if set:
+            if (basedir != null
+                && !SelectorUtils.matchPatternStart(pattern,
+                                                    basedir.getAbsolutePath(),
+                                                    isCaseSensitive())) {
+                return true;
+            }
+        } else if (basedir == null) {
+            //skip non-abs. paths if basedir == null:
+            return true;
+        }
+        return false;
+    }
+
+    /**
      * Clear the result caches for a scan.
      */
     protected synchronized void clearResults() {
@@ -1322,8 +1338,8 @@
         ensureNonPatternSetsReady();
 
         if (isCaseSensitive()
-            ? includeNonPatterns.contains(path.toString())
-            : includeNonPatterns.contains(path.toString().toUpperCase())) {
+            ? includeNonPatterns.containsKey(path.toString())
+            : includeNonPatterns.containsKey(path.toString().toUpperCase())) {
             return true;
         }
         for (int i = 0; i < includePatterns.length; i++) {
@@ -1355,18 +1371,15 @@
      *         least one include pattern, or <code>false</code> otherwise.
      */
     private boolean couldHoldIncluded(TokenizedPath tokenizedName) {
-        int wildCardCount = 0;
-        for (int i = 0; i < includes.length; i++) {
-            TokenizedPattern tokenizedInclude;
-            boolean wildcard = SelectorUtils.hasWildcards(includes[i]);
-            if (wildcard) {
-                tokenizedInclude = includePatterns[wildCardCount++];
-            } else {
-                tokenizedInclude = new TokenizedPattern(includes[i]);
+        for (int i = 0; i < includePatterns.length; i++) {
+            if (couldHoldIncluded(tokenizedName, includePatterns[i])) {
+                return true;
             }
-            if (tokenizedInclude.matchStartOf(tokenizedName, isCaseSensitive())
-                && isMorePowerfulThanExcludes(tokenizedName.toString())
-                && isDeeper(tokenizedInclude, tokenizedName)) {
+        }
+        for (Iterator iter = includeNonPatterns.values().iterator();
+             iter.hasNext(); ) {
+            if (couldHoldIncluded(tokenizedName,
+                                  ((TokenizedPath) iter.next()).toPattern())) {
                 return true;
             }
         }
@@ -1374,6 +1387,21 @@
     }
 
     /**
+     * Test whether or not a name matches the start of the given
+     * include pattern.
+     *
+     * @param tokenizedName The name to match. Must not be <code>null</code>.
+     * @return <code>true</code> when the name matches against the start of the
+     *         include pattern, or <code>false</code> otherwise.
+     */
+    private boolean couldHoldIncluded(TokenizedPath tokenizedName,
+                                      TokenizedPattern tokenizedInclude) {
+        return tokenizedInclude.matchStartOf(tokenizedName, isCaseSensitive())
+            && isMorePowerfulThanExcludes(tokenizedName.toString())
+            && isDeeper(tokenizedInclude, tokenizedName);
+    }
+
+    /**
      * Verify that a pattern specifies files deeper
      * than the level of the specified file.
      * @param pattern the pattern to check.
@@ -1453,8 +1481,8 @@
         ensureNonPatternSetsReady();
 
         if (isCaseSensitive()
-            ? excludeNonPatterns.contains(name.toString())
-            : excludeNonPatterns.contains(name.toString().toUpperCase())) {
+            ? excludeNonPatterns.containsKey(name.toString())
+            : excludeNonPatterns.containsKey(name.toString().toUpperCase())) {
             return true;
         }
         for (int i = 0; i < excludePatterns.length; i++) {
@@ -1771,16 +1799,17 @@
      * Add all patterns that are not real patterns (do not contain
      * wildcards) to the set and returns the real patterns.
      *
-     * @param set Set to populate.
+     * @param map Map to populate.
      * @param patterns String[] of patterns.
-     * @since Ant 1.6.3
+     * @since Ant 1.8.0
      */
-    private TokenizedPattern[] fillNonPatternSet(Set set, String[] patterns) {
+    private TokenizedPattern[] fillNonPatternSet(Map map, 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());
+                String s = isCaseSensitive()
+                    ? patterns[i] : patterns[i].toUpperCase();
+                map.put(s, new TokenizedPath(s));
             } else {
                 al.add(new TokenizedPattern(patterns[i]));
             }

Modified: ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java?rev=696345&r1=696344&r2=696345&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java Wed Sep 17 08:45:13 2008
@@ -198,4 +198,8 @@
         }
         return pathElements.length == 0 && !base.isDirectory() ? null : base;
     }
+
+    public TokenizedPattern toPattern() {
+        return new TokenizedPattern(path, tokenizedPath);
+    }
 }

Modified: ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/TokenizedPattern.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/TokenizedPattern.java?rev=696345&r1=696344&r2=696345&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/TokenizedPattern.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/types/selectors/TokenizedPattern.java Wed Sep 17 08:45:13 2008
@@ -49,7 +49,7 @@
         this(pattern, SelectorUtils.tokenizePathAsArray(pattern));
     }
     
-    private TokenizedPattern(String pattern, String[] tokens) {
+    TokenizedPattern(String pattern, String[] tokens) {
         this.pattern = pattern;
         this.tokenizedPattern = tokens;
     }