Browse Source

remove memoization which measurably (sp?) hurts performance more than it helps

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@697032 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 17 years ago
parent
commit
9b76a8661b
2 changed files with 13 additions and 118 deletions
  1. +9
    -99
      src/main/org/apache/tools/ant/DirectoryScanner.java
  2. +4
    -19
      src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java

+ 9
- 99
src/main/org/apache/tools/ant/DirectoryScanner.java View File

@@ -280,18 +280,6 @@ public class DirectoryScanner


// CheckStyle:VisibilityModifier ON // CheckStyle:VisibilityModifier ON


/**
* Temporary table to speed up the various scanning methods.
*
* @since Ant 1.6
*/
private Map fileListMap = new HashMap();

/**
* Uses fileListMap to cache directory listings.
*/
private final TokenizedPath.FileLister fileLister = new CachedFileLister();

/** /**
* List of all scanned directories. * List of all scanned directories.
* *
@@ -402,13 +390,6 @@ public class DirectoryScanner
*/ */
private int maxLevelsOfSymlinks = MAX_LEVELS_OF_SYMLINKS; private int maxLevelsOfSymlinks = MAX_LEVELS_OF_SYMLINKS;


/**
* Temporary table to speed up checking of canonical file names.
*
* @since Ant 1.8.0
*/
private Map canonicalPathMap = new HashMap();

/** /**
* Sole constructor. * Sole constructor.
*/ */
@@ -938,7 +919,7 @@ public class DirectoryScanner
File canonBase = null; File canonBase = null;
if (basedir != null) { if (basedir != null) {
try { try {
canonBase = getCanonicalFile(basedir);
canonBase = basedir.getCanonicalFile();
} catch (IOException ex) { } catch (IOException ex) {
throw new BuildException(ex); throw new BuildException(ex);
} }
@@ -959,12 +940,11 @@ public class DirectoryScanner
// we need to double check. // we need to double check.
try { try {
String path = (basedir == null) String path = (basedir == null)
? getCanonicalPath(myfile)
? myfile.getCanonicalPath()
: FILE_UTILS.removeLeadingPath(canonBase, : FILE_UTILS.removeLeadingPath(canonBase,
getCanonicalFile(myfile));
myfile.getCanonicalFile());
if (!path.equals(currentelement) || ON_VMS) { if (!path.equals(currentelement) || ON_VMS) {
myfile = currentPath.findFile(basedir, true,
fileLister);
myfile = currentPath.findFile(basedir, true);
if (myfile != null && basedir != null) { if (myfile != null && basedir != null) {
currentelement = FILE_UTILS.removeLeadingPath( currentelement = FILE_UTILS.removeLeadingPath(
basedir, myfile); basedir, myfile);
@@ -981,7 +961,7 @@ public class DirectoryScanner
} }


if ((myfile == null || !myfile.exists()) && !isCaseSensitive()) { if ((myfile == null || !myfile.exists()) && !isCaseSensitive()) {
File f = currentPath.findFile(basedir, false, fileLister);
File f = currentPath.findFile(basedir, false);
if (f != null && f.exists()) { if (f != null && f.exists()) {
// adapt currentelement to the case we've // adapt currentelement to the case we've
// actually found // actually found
@@ -1169,7 +1149,7 @@ public class DirectoryScanner
if (dir == null) { if (dir == null) {
throw new BuildException("dir must not be null."); throw new BuildException("dir must not be null.");
} }
String[] newfiles = list(dir);
String[] newfiles = dir.list();
if (newfiles == null) { if (newfiles == null) {
if (!dir.exists()) { if (!dir.exists()) {
throw new BuildException(dir + DOES_NOT_EXIST_POSTFIX); throw new BuildException(dir + DOES_NOT_EXIST_POSTFIX);
@@ -1223,7 +1203,7 @@ public class DirectoryScanner
String name = vpath + newfiles[i]; String name = vpath + newfiles[i];
TokenizedPath newPath = new TokenizedPath(path, newfiles[i]); TokenizedPath newPath = new TokenizedPath(path, newfiles[i]);
File file = new File(dir, newfiles[i]); File file = new File(dir, newfiles[i]);
String[] children = list(file);
String[] children = file.list();
if (children == null) { // probably file if (children == null) { // probably file
if (isIncluded(newPath)) { if (isIncluded(newPath)) {
accountForIncludedFile(newPath, file); accountForIncludedFile(newPath, file);
@@ -1721,37 +1701,6 @@ public class DirectoryScanner
return new FileResource(basedir, name); return new FileResource(basedir, name);
} }


private static final String[] NULL_FILE_LIST = new String[0];

/**
* Return a cached result of list performed on file, if
* available. Invokes the method and caches the result otherwise.
*
* @param file File (dir) to list.
* @since Ant 1.6
*/
private String[] list(File file) {
String[] files = null;
SoftReference s = (SoftReference) fileListMap.get(file);
if (s != null) {
files = (String[]) s.get();
if (files == null) {
fileListMap.remove(file);
}
}
if (files == null) {
files = file.list();
if (files != null) {
fileListMap.put(file, new SoftReference(files));
} else {
fileListMap.put(file, new SoftReference(NULL_FILE_LIST));
}
} else if (files == NULL_FILE_LIST) {
files = null;
}
return files;
}

/** /**
* Has the directory with the given path relative to the base * Has the directory with the given path relative to the base
* directory already been scanned? * directory already been scanned?
@@ -1779,8 +1728,6 @@ public class DirectoryScanner
* @since Ant 1.6 * @since Ant 1.6
*/ */
private synchronized void clearCaches() { private synchronized void clearCaches() {
fileListMap.clear();
canonicalPathMap.clear();
includeNonPatterns.clear(); includeNonPatterns.clear();
excludeNonPatterns.clear(); excludeNonPatterns.clear();
includePatterns = null; includePatterns = null;
@@ -1845,7 +1792,7 @@ public class DirectoryScanner
LinkedList s = (LinkedList) directoryNamesFollowed.clone(); LinkedList s = (LinkedList) directoryNamesFollowed.clone();
ArrayList files = new ArrayList(); ArrayList files = new ArrayList();
File f = FILE_UTILS.resolveFile(parent, dirName); File f = FILE_UTILS.resolveFile(parent, dirName);
String target = getCanonicalPath(f);
String target = f.getCanonicalPath();
files.add(target); files.add(target);


String relPath = ""; String relPath = "";
@@ -1854,7 +1801,7 @@ public class DirectoryScanner
String dir = (String) s.removeFirst(); String dir = (String) s.removeFirst();
if (dirName.equals(dir)) { if (dirName.equals(dir)) {
f = FILE_UTILS.resolveFile(parent, relPath + dir); f = FILE_UTILS.resolveFile(parent, relPath + dir);
files.add(getCanonicalPath(f));
files.add(f.getCanonicalPath());
if (files.size() > maxLevelsOfSymlinks if (files.size() > maxLevelsOfSymlinks
&& CollectionUtils.frequency(files, target) && CollectionUtils.frequency(files, target)
> maxLevelsOfSymlinks) { > maxLevelsOfSymlinks) {
@@ -1871,41 +1818,4 @@ public class DirectoryScanner
} }
} }


/**
* Returns a cached canonical path for a given file or first
* obtains and adds it to the cache.
*
* @since Ant 1.8.0
*/
private String getCanonicalPath(File file) throws IOException {
String path = null;
SoftReference s = (SoftReference) canonicalPathMap.get(file);
if (s != null) {
path = (String) s.get();
if (path == null) {
canonicalPathMap.remove(file);
}
}
if (path == null) {
path = file.getCanonicalPath();
canonicalPathMap.put(file, new SoftReference(path));
}
return path;
}

/**
* Returns a cached canonical path for a given file or first
* obtains and adds it to the cache.
*
* @since Ant 1.8.0
*/
private File getCanonicalFile(File file) throws IOException {
return new File(getCanonicalPath(file));
}

private class CachedFileLister implements TokenizedPath.FileLister {
public String[] list(File f) {
return DirectoryScanner.this.list(f);
}
}
} }

+ 4
- 19
src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java View File

@@ -105,7 +105,7 @@ public class TokenizedPath {
* @param cs whether to scan case-sensitively. * @param cs whether to scan case-sensitively.
* @return File object that points to the file in question or null. * @return File object that points to the file in question or null.
*/ */
public File findFile(File base, final boolean cs, FileLister fileLister) {
public File findFile(File base, final boolean cs) {
String[] tokens = tokenizedPath; String[] tokens = tokenizedPath;
if (FileUtils.isAbsolutePath(path)) { if (FileUtils.isAbsolutePath(path)) {
if (base == null) { if (base == null) {
@@ -123,7 +123,7 @@ public class TokenizedPath {
tokens = SelectorUtils.tokenizePathAsArray(s); tokens = SelectorUtils.tokenizePathAsArray(s);
} }
} }
return findFile(base, tokens, cs, fileLister);
return findFile(base, tokens, cs);
} }


/** /**
@@ -170,12 +170,12 @@ public class TokenizedPath {
* @return File object that points to the file in question or null. * @return File object that points to the file in question or null.
*/ */
private static File findFile(File base, final String[] pathElements, private static File findFile(File base, final String[] pathElements,
final boolean cs, FileLister fileLister) {
final boolean cs) {
for (int current = 0; current < pathElements.length; current++) { for (int current = 0; current < pathElements.length; current++) {
if (!base.isDirectory()) { if (!base.isDirectory()) {
return null; return null;
} }
String[] files = fileLister.list(base);
String[] files = base.list();
if (files == null) { if (files == null) {
throw new BuildException("IO error scanning directory " throw new BuildException("IO error scanning directory "
+ base.getAbsolutePath()); + base.getAbsolutePath());
@@ -207,19 +207,4 @@ public class TokenizedPath {
return new TokenizedPattern(path, tokenizedPath); return new TokenizedPattern(path, tokenizedPath);
} }


/**
* Helper that obtains the listing of a directory.
*/
public static interface FileLister {
String[] list(File file);
}

/**
* Default implementation using File.list().
*/
public static final class DefaultLister implements FileLister {
public String[] list(File file) {
return file.list();
}
}
} }

Loading…
Cancel
Save