Created
April 1, 2014 15:10
-
-
Save nirvdrum/9916141 to your computer and use it in GitHub Desktop.
WIP implementation of a 'require' speedup for JRuby.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/core/src/main/java/org/jruby/runtime/load/LoadService.java b/core/src/main/java/org/jruby/runtime/load/LoadService.java | |
index a7d5a2c..8462a03 100644 | |
--- a/core/src/main/java/org/jruby/runtime/load/LoadService.java | |
+++ b/core/src/main/java/org/jruby/runtime/load/LoadService.java | |
@@ -42,12 +42,7 @@ import java.net.MalformedURLException; | |
import java.net.URISyntaxException; | |
import java.net.URI; | |
import java.net.URL; | |
-import java.util.ArrayList; | |
-import java.util.Collections; | |
-import java.util.HashMap; | |
-import java.util.Iterator; | |
-import java.util.List; | |
-import java.util.Map; | |
+import java.util.*; | |
import java.util.concurrent.ConcurrentHashMap; | |
import java.util.concurrent.atomic.AtomicInteger; | |
import java.util.concurrent.locks.ReentrantLock; | |
@@ -213,6 +208,7 @@ public class LoadService { | |
protected final Map<String, Library> builtinLibraries = new HashMap<String, Library>(); | |
protected final Map<String, JarFile> jarFiles = new HashMap<String, JarFile>(); | |
+ private final Map<String, Set<File>> filesystemLookups = new HashMap<String, Set<File>>(); | |
protected final Ruby runtime; | |
@@ -1425,7 +1421,50 @@ public class LoadService { | |
try { | |
if (!Ruby.isSecurityRestricted()) { | |
String reportedPath = loadPathEntry + "/" + namePlusSuffix; | |
+ String[] nameParts = namePlusSuffix.split("/"); | |
+ | |
+ if (nameParts.length == 1) | |
+ { | |
+ if (! filesystemLookups.containsKey(loadPathEntry)) | |
+ { | |
+ File[] children = new File(loadPathEntry).listFiles(); | |
+ filesystemLookups.put(loadPathEntry, children == null ? new HashSet<File>() : new HashSet(Arrays.asList(children))); | |
+ } | |
+ | |
+ if (! filesystemLookups.get(loadPathEntry).contains(new java.io.File(reportedPath))) { | |
+ return null; | |
+ } | |
+ | |
+ } else { | |
+ String path = loadPathEntry; | |
+ | |
+ for (int i = 0; i < nameParts.length - 1; i++) { | |
+ path = path + "/" + nameParts[i]; | |
+ | |
+ if (! filesystemLookups.containsKey(path)) | |
+ { | |
+ File[] children = new File(path).listFiles(); | |
+ filesystemLookups.put(path, children == null ? new HashSet<File>() : new HashSet(Arrays.asList(children))); | |
+ | |
+ // Since filesystem paths are nested, if any parent doesn't exist, we can assume any child also | |
+ // does not exist and short-circuit the search here. | |
+ if (children == null) { | |
+ return null; | |
+ } | |
+ } else { | |
+ if (! filesystemLookups.get(path).contains(new java.io.File(path + "/" + nameParts[i + 1]))) { | |
+ return null; | |
+ } | |
+ } | |
+ } | |
+ | |
+ if (! filesystemLookups.get(path).contains(new java.io.File(reportedPath))) { | |
+ return null; | |
+ } | |
+ } | |
+ | |
boolean absolute = true; | |
+ /* | |
// we check length == 0 for 'load', which does not use load path | |
if (!new File(reportedPath).isAbsolute()) { | |
absolute = false; | |
@@ -1435,10 +1474,27 @@ public class LoadService { | |
} | |
loadPathEntry = JRubyFile.create(runtime.getCurrentDirectory(), loadPathEntry).getAbsolutePath(); | |
} | |
- JRubyFile actualPath = JRubyFile.create(loadPathEntry, RubyFile.expandUserPath(runtime.getCurrentContext(), namePlusSuffix)); | |
+ */ | |
+ | |
+ //JRubyFile actualPath = JRubyFile.create(loadPathEntry, RubyFile.expandUserPath(runtime.getCurrentContext(), namePlusSuffix)); | |
+ | |
+ JRubyFile actualPath = new JRubyFile(reportedPath); | |
if (RubyInstanceConfig.DEBUG_LOAD_SERVICE) { | |
debugLogTry("resourceFromLoadPath", "'" + actualPath.toString() + "' " + actualPath.isFile() + " " + actualPath.canRead()); | |
} | |
+ | |
+ /* | |
+ String parent = actualPath.getParent(); | |
+ if (! filesystemLookups.containsKey(parent)) { | |
+ File[] children = new File(parent).listFiles(); | |
+ filesystemLookups.put(parent, children == null ? new HashSet<File>() : new HashSet(Arrays.asList(children))); | |
+ } | |
+ | |
+ if (! filesystemLookups.get(parent).contains(actualPath)) { | |
+ return null; | |
+ } | |
+*/ | |
+ | |
if (actualPath.canRead()) { | |
foundResource = new LoadServiceResource(actualPath, reportedPath, absolute); | |
debugLogFound(foundResource); | |
diff --git a/core/src/main/java/org/jruby/util/JRubyFile.java b/core/src/main/java/org/jruby/util/JRubyFile.java | |
index d2c3e1b..db318a6 100644 | |
--- a/core/src/main/java/org/jruby/util/JRubyFile.java | |
+++ b/core/src/main/java/org/jruby/util/JRubyFile.java | |
@@ -115,7 +115,7 @@ public class JRubyFile extends JavaSecuredFile { | |
this(file.getAbsolutePath()); | |
} | |
- protected JRubyFile(String filename) { | |
+ public JRubyFile(String filename) { | |
super(filename); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment