Skip to content

Instantly share code, notes, and snippets.

@nirvdrum
Created April 1, 2014 15:10
Show Gist options
  • Save nirvdrum/9916141 to your computer and use it in GitHub Desktop.
Save nirvdrum/9916141 to your computer and use it in GitHub Desktop.
WIP implementation of a 'require' speedup for JRuby.
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