From 82b408e1d333a9e0a40a88604ba91c079f3c3071 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 4 Apr 2013 18:09:53 +0400 Subject: [PATCH] [r=nik] optimizations: less string operations --- .../jps/javac/OptimizedFileManager17.java | 50 +++++++++++++----- jps/lib/optimizedFileManager.jar | Bin 20328 -> 20937 bytes 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager17.java b/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager17.java index 2d96145a20c9..3b0c1731ba2d 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager17.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager17.java @@ -47,6 +47,12 @@ class OptimizedFileManager17 extends com.sun.tools.javac.file.JavacFileManager { private final Map myDirectoryCache = new HashMap(); public static final File[] NULL_FILE_ARRAY = new File[0]; + private static final String _OS_NAME = System.getProperty("os.name").toLowerCase(Locale.US); + private static final boolean isWindows = _OS_NAME.startsWith("windows"); + private static final boolean isOS2 = _OS_NAME.startsWith("os/2") || _OS_NAME.startsWith("os2"); + private static final boolean isMac = _OS_NAME.startsWith("mac"); + private static final boolean isFileSystemCaseSensitive = !isWindows && !isOS2 && !isMac; + public OptimizedFileManager17() throws Throwable { super(new Context(), true, null); final Field archivesField = com.sun.tools.javac.file.JavacFileManager.class.getDeclaredField("archives"); @@ -214,7 +220,7 @@ class OptimizedFileManager17 extends com.sun.tools.javac.file.JavacFileManager { private class InputFileObject extends BaseFileObject { private String name; - final File file; + private final File file; private Reference absFileRef; public InputFileObject(JavacFileManager fileManager, File f) { @@ -285,20 +291,38 @@ class OptimizedFileManager17 extends com.sun.tools.javac.file.JavacFileManager { @Override protected String inferBinaryName(Iterable path) { - String fPath = file.getPath(); - //System.err.println("RegularFileObject " + file + " " +r.getPath()); + final String fPath = file.getPath(); for (File dir: path) { - //System.err.println("dir: " + dir); - String dPath = dir.getPath(); - if (dPath.length() == 0) - dPath = System.getProperty("user.dir"); - if (!dPath.endsWith(File.separator)) - dPath += File.separator; - if (fPath.regionMatches(true, 0, dPath, 0, dPath.length()) - && new File(fPath.substring(0, dPath.length())).equals(new File(dPath))) { - String relativeName = fPath.substring(dPath.length()); - return removeExtension(relativeName).replace(File.separatorChar, '.'); + String dirPath = dir.getPath(); + if (dirPath.length() == 0) { + dirPath = System.getProperty("user.dir"); } + if (!fPath.regionMatches(!isFileSystemCaseSensitive, 0, dirPath, 0, dirPath.length())) { + continue; + } + final int pathLength = fPath.length(); + final boolean endsWithSeparator = dirPath.endsWith(File.separator); + if (!endsWithSeparator) { + // need to check if the next char in fPath is file separator + final int separatorIdx = dirPath.length(); + if (pathLength <= separatorIdx || fPath.charAt(separatorIdx) != File.separatorChar) { + continue; + } + } + // fPath starts with dirPath + final int startIndex = endsWithSeparator ? dirPath.length() : dirPath.length() + 1; + int endIndex = fPath.lastIndexOf('.'); + if (endIndex <= startIndex) { + endIndex = fPath.length(); + } + final int length = endIndex - startIndex; + final StringBuilder buf = new StringBuilder(length).append(fPath, startIndex, endIndex); + for (int idx = 0; idx < length; idx++) { + if (buf.charAt(idx) == File.separatorChar) { + buf.setCharAt(idx, '.'); + } + } + return buf.toString(); } return null; } diff --git a/jps/lib/optimizedFileManager.jar b/jps/lib/optimizedFileManager.jar index cc5355bc32a6fb93315cf3ae3a1d704d36585d95..ce76aa5dbc8dd3a5050ce84a03b2565cd1a787ce 100644 GIT binary patch delta 8614 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 auOk1O>PpBc|C~VoyP!yLaNElNME?c$t7l~Z delta 8009 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