From 42c0a49f2f301caa80fdf7a505fd2888f2dba36d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Kubitz?= Date: Mon, 18 Sep 2023 15:00:35 +0200 Subject: [PATCH] performance: avoid O(n^2) in PDEJavaHelper findPackageFragmentRoot() searches through all PackageFragment Roots and is called for every libPaths. This can be slow due to involved file access. see https://github.com/eclipse-jdt/eclipse.jdt.core/issues/303 Instead call getAllPackageFragmentRoots() only once, index the result and use O(1) hash access. --- .../pde/internal/core/util/PDEJavaHelper.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/PDEJavaHelper.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/PDEJavaHelper.java index 7818247653..35d187604a 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/PDEJavaHelper.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/PDEJavaHelper.java @@ -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; @@ -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 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()) { @@ -265,6 +270,17 @@ private static IPackageFragment getExternalPackageFragment(String packageName, S return searchWorkspaceForPackage(packageName, base); } + private static Map getRootsByPath(IJavaProject jp) throws JavaModelException { + Map 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 libPaths = new ArrayList<>(); @@ -286,9 +302,13 @@ private static IPackageFragment searchWorkspaceForPackage(String packageName, IP continue; } IJavaProject jp = JavaCore.create(projects[i]); + Map rootsByPath = null; ListIterator 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()) {