[FELIX-4942] Make computation of package sources parallel for all resources that do not have required packages.
[FELIX-4942] Make sure getPackageSources() does not compute anything, recursion is done directly using getPackageSourcesInternal()
[FELIX-4942] Remove unused session parameter in getPackageSources() and isCompatible()
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1690729 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java b/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java
index 98f9799..930e1a5 100644
--- a/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java
+++ b/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java
@@ -983,7 +983,7 @@
return;
}
- for (Capability candSourceCap : getPackageSources(session, mergeCap, resourcePkgMap))
+ for (Capability candSourceCap : getPackageSources(mergeCap, resourcePkgMap))
{
List<String> uses;
// TODO: RFC-112 - Need impl-specific type
@@ -1109,7 +1109,7 @@
}
// Parallel get all exported packages
- final Map<Resource, Packages> allPackages = new OpenHashMap<Resource, Packages>(allCandidates.getNbResources());
+ final OpenHashMap<Resource, Packages> allPackages = new OpenHashMap<Resource, Packages>(allCandidates.getNbResources());
for (final Resource resource : allWireCandidates.keySet())
{
final Packages packages = new Packages(resource);
@@ -1137,12 +1137,37 @@
}
executor.await();
- // Sequential compute package sources
- // TODO: make that parallel
- for (Resource resource : allWireCandidates.keySet())
+ // Compute package sources
+ // First, sequentially compute packages for resources
+ // that have required packages, so that all recursive
+ // calls can be done without threading problems
+ for (Map.Entry<Resource, Packages> entry : allPackages.fast())
{
- getPackageSourcesInternal(session, allPackages, resource);
+ final Resource resource = entry.getKey();
+ final Packages packages = entry.getValue();
+ if (!packages.m_requiredPkgs.isEmpty())
+ {
+ getPackageSourcesInternal(session, allPackages, resource, packages);
+ }
}
+ // Next, for all remaining resources, we can compute them
+ // in parallel, as they won't refer to other resource packages
+ for (Map.Entry<Resource, Packages> entry : allPackages.fast())
+ {
+ final Resource resource = entry.getKey();
+ final Packages packages = entry.getValue();
+ if (packages.m_sources.isEmpty())
+ {
+ executor.execute(new Runnable()
+ {
+ public void run()
+ {
+ getPackageSourcesInternal(session, allPackages, resource, packages);
+ }
+ });
+ }
+ }
+ executor.await();
// Parallel compute uses
for (final Resource resource : allWireCandidates.keySet())
@@ -1290,7 +1315,7 @@
}
for (UsedBlames usedBlames : pkgBlames.values())
{
- if (!isCompatible(session, exportBlame, usedBlames.m_cap, resourcePkgMap))
+ if (!isCompatible(exportBlame, usedBlames.m_cap, resourcePkgMap))
{
for (Blame usedBlame : usedBlames.m_blames)
{
@@ -1387,7 +1412,7 @@
for (UsedBlames usedBlames : pkgBlames.values())
{
- if (!isCompatible(session, requirementBlames, usedBlames.m_cap, resourcePkgMap))
+ if (!isCompatible(requirementBlames, usedBlames.m_cap, resourcePkgMap))
{
// Split packages, need to think how to get a good message for split packages (sigh)
// For now we just use the first requirement that brings in the package that conflicts
@@ -1600,21 +1625,21 @@
}
private static boolean isCompatible(
- ResolveSession session, Blame currentBlame, Capability candCap,
+ Blame currentBlame, Capability candCap,
Map<Resource, Packages> resourcePkgMap)
{
if (currentBlame.m_cap.equals(candCap))
{
return true;
}
- Set<Capability> candSources = getPackageSources(session, candCap, resourcePkgMap);
- Set<Capability> currentSources = getPackageSources(session, currentBlame.m_cap, resourcePkgMap);
+ Set<Capability> candSources = getPackageSources(candCap, resourcePkgMap);
+ Set<Capability> currentSources = getPackageSources(currentBlame.m_cap, resourcePkgMap);
return currentSources.containsAll(candSources)
|| candSources.containsAll(currentSources);
}
private static boolean isCompatible(
- ResolveSession session, List<Blame> currentBlames, Capability candCap,
+ List<Blame> currentBlames, Capability candCap,
Map<Resource, Packages> resourcePkgMap)
{
int size = currentBlames.size();
@@ -1623,34 +1648,29 @@
case 0:
return true;
case 1:
- return isCompatible(session, currentBlames.get(0), candCap, resourcePkgMap);
+ return isCompatible(currentBlames.get(0), candCap, resourcePkgMap);
default:
Set<Capability> currentSources = new HashSet<Capability>(currentBlames.size());
for (Blame currentBlame : currentBlames)
{
- Set<Capability> blameSources = getPackageSources(session, currentBlame.m_cap, resourcePkgMap);
+ Set<Capability> blameSources = getPackageSources(currentBlame.m_cap, resourcePkgMap);
currentSources.addAll(blameSources);
}
- Set<Capability> candSources = getPackageSources(session, candCap, resourcePkgMap);
+ Set<Capability> candSources = getPackageSources(candCap, resourcePkgMap);
return currentSources.containsAll(candSources)
|| candSources.containsAll(currentSources);
}
}
private static Set<Capability> getPackageSources(
- ResolveSession session, Capability cap, Map<Resource, Packages> resourcePkgMap)
+ Capability cap, Map<Resource, Packages> resourcePkgMap)
{
- Set<Capability> sources = resourcePkgMap.get(cap.getResource()).m_sources.get(cap);
- if (sources == null)
- {
- getPackageSourcesInternal(session, resourcePkgMap, cap.getResource());
- sources = resourcePkgMap.get(cap.getResource()).m_sources.get(cap);
- }
- return sources;
+ return resourcePkgMap.get(cap.getResource()).m_sources.get(cap);
}
private static void getPackageSourcesInternal(
- ResolveSession session, Map<Resource, Packages> resourcePkgMap, Resource resource)
+ ResolveSession session, Map<Resource, Packages> resourcePkgMap,
+ Resource resource, Packages packages)
{
Wiring wiring = session.getContext().getWirings().get(resource);
List<Capability> caps = (wiring != null)
@@ -1661,7 +1681,7 @@
return new HashSet<Capability>();
}
};
- Map<Capability, Set<Capability>> sources = resourcePkgMap.get(resource).m_sources;
+ Map<Capability, Set<Capability>> sources = packages.m_sources;
for (Capability sourceCap : caps)
{
if (sourceCap.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE))
@@ -1696,7 +1716,7 @@
for (Map.Entry<String, Set<Capability>> pkg : pkgs.fast())
{
String pkgName = pkg.getKey();
- List<Blame> required = resourcePkgMap.get(resource).m_requiredPkgs.get(pkgName);
+ List<Blame> required = packages.m_requiredPkgs.get(pkgName);
if (required != null)
{
Set<Capability> srcs = pkg.getValue();
@@ -1705,7 +1725,14 @@
Capability bcap = blame.m_cap;
if (srcs.add(bcap))
{
- Set<Capability> additional = getPackageSources(session, bcap, resourcePkgMap);
+ Resource capResource = bcap.getResource();
+ Packages capPackages = resourcePkgMap.get(capResource);
+ Set<Capability> additional = capPackages.m_sources.get(bcap);
+ if (additional == null)
+ {
+ getPackageSourcesInternal(session, resourcePkgMap, capResource, capPackages);
+ additional = capPackages.m_sources.get(bcap);
+ }
srcs.addAll(additional);
}
}