Skip to content

Commit

Permalink
performance: avoid O(n^2) in PDEJavaHelper
Browse files Browse the repository at this point in the history
findPackageFragmentRoot() searches through all PackageFragment Roots and
is called for every libPaths. This can be slow due to involved file
access.
see eclipse-jdt/eclipse.jdt.core#303

Instead call getAllPackageFragmentRoots() only once, index the result
and use O(1) hash access.
  • Loading branch information
EcljpseB0T authored and jukzi committed Sep 26, 2023
1 parent f5c8301 commit a6601a5
Showing 1 changed file with 22 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.ListIterator;
import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
Expand Down Expand Up @@ -246,12 +247,16 @@ private static IPackageFragment getExternalPackageFragment(String packageName, S
// else model is in folder form, try to find model's libraries on filesystem
} else {
IPluginLibrary[] libs = base.getPluginBase().getLibraries();
Map<IPath, IPackageFragmentRoot> rootsByPath = null;
for (IPluginLibrary lib : libs) {
if (IPluginLibrary.RESOURCE.equals(lib.getType())) {
continue;
}
String libName = ClasspathUtilCore.expandLibraryName(lib.getName());
IPackageFragmentRoot root = jp.findPackageFragmentRoot(path.append(libName));
if (rootsByPath == null) {
rootsByPath = getRootsByPath(jp);
}
IPackageFragmentRoot root = rootsByPath.get(path.append(libName));
if (root != null) {
IPackageFragment frag = root.getPackageFragment(packageName);
if (frag.exists()) {
Expand All @@ -265,6 +270,17 @@ private static IPackageFragment getExternalPackageFragment(String packageName, S
return searchWorkspaceForPackage(packageName, base);
}

private static Map<IPath, IPackageFragmentRoot> getRootsByPath(IJavaProject jp) throws JavaModelException {
Map<IPath, IPackageFragmentRoot> rootsByPath = new HashMap<>();
for (IPackageFragmentRoot classpathRoot : jp.getAllPackageFragmentRoots()) {
IPath classRootPath = classpathRoot.getPath();
if (classRootPath != null) {
rootsByPath.put(classRootPath, classpathRoot);
}
}
return rootsByPath;
}

private static IPackageFragment searchWorkspaceForPackage(String packageName, IPluginModelBase base) {
IPluginLibrary[] libs = base.getPluginBase().getLibraries();
ArrayList<IPath> libPaths = new ArrayList<>();
Expand All @@ -286,9 +302,13 @@ private static IPackageFragment searchWorkspaceForPackage(String packageName, IP
continue;
}
IJavaProject jp = JavaCore.create(projects[i]);
Map<IPath, IPackageFragmentRoot> rootsByPath = null;
ListIterator<IPath> li = libPaths.listIterator();
while (li.hasNext()) {
IPackageFragmentRoot root = jp.findPackageFragmentRoot(li.next());
if (rootsByPath == null) {
rootsByPath = getRootsByPath(jp);
}
IPackageFragmentRoot root = rootsByPath.get(li.next());
if (root != null) {
IPackageFragment frag = root.getPackageFragment(packageName);
if (frag.exists()) {
Expand Down

0 comments on commit a6601a5

Please sign in to comment.