Applied patch (FELIX-977) to try to optimize OBR's resolver.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@759998 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResolverImpl.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResolverImpl.java
index c9b17de..d0ddcc1 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResolverImpl.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResolverImpl.java
@@ -31,12 +31,13 @@
private final RepositoryAdmin m_admin;
private final Logger m_logger;
private final LocalRepositoryImpl m_local;
- private Set m_addedSet = new HashSet();
- private Set m_resolveSet = new HashSet();
- private Set m_requiredSet = new HashSet();
- private Set m_optionalSet = new HashSet();
- private Map m_reasonMap = new HashMap();
- private Map m_unsatisfiedMap = new HashMap();
+ private final Set m_addedSet = new HashSet();
+ private final Set m_failedSet = new HashSet();
+ private final Set m_resolveSet = new HashSet();
+ private final Set m_requiredSet = new HashSet();
+ private final Set m_optionalSet = new HashSet();
+ private final Map m_reasonMap = new HashMap();
+ private final Map m_unsatisfiedMap = new HashMap();
private boolean m_resolved = false;
private long m_resolveTimeStamp;
@@ -116,6 +117,7 @@
m_resolveTimeStamp = m_local.getLastModified();
// Reset instance values.
+ m_failedSet.clear();
m_resolveSet.clear();
m_requiredSet.clear();
m_optionalSet.clear();
@@ -155,7 +157,11 @@
// Check for cycles.
if (m_resolveSet.contains(resource))
{
- return result;
+ return true;
+ }
+ else if (m_failedSet.contains(resource))
+ {
+ return false;
}
// Add to resolve map to avoid cycles.
@@ -224,22 +230,25 @@
}
else if (candidate != null)
{
- // The resolved succeeded; record the candidate
- // as either optional or required.
- if (reqs[reqIdx].isOptional())
- {
- m_optionalSet.add(candidate);
- }
- else
- {
- m_requiredSet.add(candidate);
- }
-
- // Add the reason why the candidate was selected.
- addReason(candidate, reqs[reqIdx]);
// Try to resolve the candidate.
- if (!resolve(candidate))
+ if (resolve(candidate))
+ {
+ // The resolved succeeded; record the candidate
+ // as either optional or required.
+ if (reqs[reqIdx].isOptional())
+ {
+ m_optionalSet.add(candidate);
+ }
+ else
+ {
+ m_requiredSet.add(candidate);
+ }
+
+ // Add the reason why the candidate was selected.
+ addReason(candidate, reqs[reqIdx]);
+ }
+ else
{
result = false;
}
@@ -247,13 +256,12 @@
}
}
- // If the resource did not resolve, then remove it from
- // the resolve set, since to keep it consistent for iterative
- // resolving, such as what happens when determining the best
- // available candidate.
+ // If the resolve failed, remove the resource from the resolve set and
+ // add it to the failed set to avoid trying to resolve it again.
if (!result)
{
m_resolveSet.remove(resource);
+ m_failedSet.add(resource);
}
return result;
@@ -282,17 +290,16 @@
private Resource searchResolvingResources(Requirement req)
{
- Resource[] resources = (Resource[])
- m_resolveSet.toArray(new Resource[m_resolveSet.size()]);
- for (int resIdx = 0; (resources != null) && (resIdx < resources.length); resIdx++)
+ for (Iterator iterator = m_resolveSet.iterator(); iterator.hasNext(); )
{
- Capability[] caps = resources[resIdx].getCapabilities();
+ Resource resource = (Resource) iterator.next();
+ Capability[] caps = resource.getCapabilities();
for (int capIdx = 0; (caps != null) && (capIdx < caps.length); capIdx++)
{
if (caps[capIdx].getName().equals(req.getName())
&& req.isSatisfied(caps[capIdx]))
{
- return resources[resIdx];
+ return resource;
}
}
}
@@ -311,13 +318,18 @@
Resource[] resources = m_local.getResources();
for (int resIdx = 0; (resources != null) && (resIdx < resources.length); resIdx++)
{
- Capability[] caps = resources[resIdx].getCapabilities();
- for (int capIdx = 0; (caps != null) && (capIdx < caps.length); capIdx++)
+ // We don't need to look at resources we've already looked at.
+ if (!m_failedSet.contains(resources[resIdx])
+ && !m_resolveSet.contains(resources[resIdx]))
{
- if (caps[capIdx].getName().equals(req.getName())
- && req.isSatisfied(caps[capIdx]))
+ Capability[] caps = resources[resIdx].getCapabilities();
+ for (int capIdx = 0; (caps != null) && (capIdx < caps.length); capIdx++)
{
- matchingCandidates.add(resources[resIdx]);
+ if (caps[capIdx].getName().equals(req.getName())
+ && req.isSatisfied(caps[capIdx]))
+ {
+ matchingCandidates.add(resources[resIdx]);
+ }
}
}
}
@@ -340,13 +352,18 @@
Resource[] resources = repos[repoIdx].getResources();
for (int resIdx = 0; (resources != null) && (resIdx < resources.length); resIdx++)
{
- Capability[] caps = resources[resIdx].getCapabilities();
- for (int capIdx = 0; (caps != null) && (capIdx < caps.length); capIdx++)
+ // We don't need to look at resources we've already looked at.
+ if (!m_failedSet.contains(resources[resIdx])
+ && !m_resolveSet.contains(resources[resIdx]))
{
- if (caps[capIdx].getName().equals(req.getName())
- && req.isSatisfied(caps[capIdx]))
+ Capability[] caps = resources[resIdx].getCapabilities();
+ for (int capIdx = 0; (caps != null) && (capIdx < caps.length); capIdx++)
{
- matchingCandidates.add(resources[resIdx]);
+ if (caps[capIdx].getName().equals(req.getName())
+ && req.isSatisfied(caps[capIdx]))
+ {
+ matchingCandidates.add(resources[resIdx]);
+ }
}
}
}
@@ -362,7 +379,8 @@
* @param resources
* @return
*/
- private Resource getBestResource(List resources) {
+ private Resource getBestResource(List resources)
+ {
Version bestVersion = null;
Resource best = null;