Author: gnodet
Date: Mon Jul 13 15:17:54 2015
New Revision: 1690712
URL: http://svn.apache.org/r1690712
Log:
[FELIX-4942] Compute all package sources for a given resource at the same time.
[FELIX-4942]
[FELIX-4942] This is interesting when resources export the same package
multiple times. It also avoids maintaining cycles.
Modified:
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java
Modified:
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java
URL:
http://svn.apache.org/viewvc/felix/trunk/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java?rev=1690712&r1=1690711&r2=1690712&view=diff
==============================================================================
---
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java
(original)
+++
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java
Mon Jul 13 15:17:54 2015
@@ -1592,82 +1592,77 @@ public class ResolverImpl implements Res
private static Set<Capability> getPackageSources(
ResolveSession session, Capability cap, Map<Resource, Packages>
resourcePkgMap)
{
- Map<Capability, Set<Capability>> packageSourcesCache =
resourcePkgMap.get(cap.getResource()).m_sources;
- // If it is a package, then calculate sources for it.
- if (cap.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE))
+ Set<Capability> sources =
resourcePkgMap.get(cap.getResource()).m_sources.get(cap);
+ if (sources == null)
{
- Set<Capability> sources = packageSourcesCache.get(cap);
- if (sources == null)
- {
- sources = getPackageSourcesInternal(
- session.getContext(), cap, resourcePkgMap,
- new HashSet<Capability>(64), new HashSet<Capability>(64));
- packageSourcesCache.put(cap, sources);
- }
- return sources;
+ getPackageSourcesInternal(session, resourcePkgMap,
cap.getResource());
+ sources = resourcePkgMap.get(cap.getResource()).m_sources.get(cap);
}
-
- // Otherwise, need to return generic capabilies that have
- // uses constraints so they are included for consistency
- // checking.
- String uses =
cap.getDirectives().get(Namespace.CAPABILITY_USES_DIRECTIVE);
- if ((uses != null) && (uses.length() > 0))
- {
- return Collections.singleton(cap);
- }
-
- return Collections.emptySet();
+ return sources;
}
- private static Set<Capability> getPackageSourcesInternal(
- ResolveContext rc, Capability cap, Map<Resource, Packages>
resourcePkgMap,
- Set<Capability> sources, Set<Capability> cycleMap)
+ private static void getPackageSourcesInternal(
+ ResolveSession session, Map<Resource, Packages> resourcePkgMap,
Resource resource)
{
- if (cap.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE))
+ Wiring wiring = session.getContext().getWirings().get(resource);
+ List<Capability> caps = (wiring != null)
+ ? wiring.getResourceCapabilities(null)
+ : resource.getCapabilities(null);
+ OpenHashMap<String, Set<Capability>> pkgs = new OpenHashMap<String,
Set<Capability>>(caps.size()) {
+ public Set<Capability> compute(String pkgName) {
+ return new HashSet<Capability>();
+ }
+ };
+ Map<Capability, Set<Capability>> sources =
resourcePkgMap.get(resource).m_sources;
+ for (Capability sourceCap : caps)
{
- if (!cycleMap.add(cap))
+ if
(sourceCap.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE))
{
- return sources;
+ String pkgName = (String)
sourceCap.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
+ Set<Capability> pkgCaps = pkgs.getOrCompute(pkgName);
+ sources.put(sourceCap, pkgCaps);
+ // Since capabilities may come from fragments, we need to check
+ // for that case and wrap them.
+ if (!resource.equals(sourceCap.getResource()))
+ {
+ sourceCap = new WrappedCapability(resource, sourceCap);
+ }
+ pkgCaps.add(sourceCap);
}
-
- // Get the package name associated with the capability.
- String pkgName = cap.getAttributes()
- .get(PackageNamespace.PACKAGE_NAMESPACE).toString();
-
- // Since a resource can export the same package more than once, get
- // all package capabilities for the specified package name.
- Wiring wiring = rc.getWirings().get(cap.getResource());
- List<Capability> caps = (wiring != null)
- ? wiring.getResourceCapabilities(null)
- : cap.getResource().getCapabilities(null);
- for (Capability sourceCap : caps)
+ else
{
- if
(sourceCap.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE)
- &&
sourceCap.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE).equals(pkgName))
+ // Otherwise, need to return generic capabilities that have
+ // uses constraints so they are included for consistency
+ // checking.
+ String uses =
sourceCap.getDirectives().get(Namespace.CAPABILITY_USES_DIRECTIVE);
+ if ((uses != null) && !uses.isEmpty())
{
- // Since capabilities may come from fragments, we need to
check
- // for that case and wrap them.
- if (!cap.getResource().equals(sourceCap.getResource()))
- {
- sourceCap = new WrappedCapability(cap.getResource(),
sourceCap);
- }
- sources.add(sourceCap);
+ sources.put(sourceCap, Collections.singleton(sourceCap));
+ }
+ else
+ {
+ sources.put(sourceCap, Collections.<Capability>emptySet());
}
}
-
- // Then get any addition sources for the package from required
bundles.
- Packages pkgs = resourcePkgMap.get(cap.getResource());
- List<Blame> required = pkgs.m_requiredPkgs.get(pkgName);
+ }
+ for (Map.Entry<String, Set<Capability>> pkg : pkgs.fast())
+ {
+ String pkgName = pkg.getKey();
+ List<Blame> required =
resourcePkgMap.get(resource).m_requiredPkgs.get(pkgName);
if (required != null)
{
+ Set<Capability> srcs = pkg.getValue();
for (Blame blame : required)
{
- getPackageSourcesInternal(rc, blame.m_cap, resourcePkgMap,
sources, cycleMap);
+ Capability bcap = blame.m_cap;
+ if (srcs.add(bcap))
+ {
+ Set<Capability> additional =
getPackageSources(session, bcap, resourcePkgMap);
+ srcs.addAll(additional);
+ }
}
}
}
-
- return sources;
}
private static Resource getDeclaredResource(Resource resource)