Author: rickhall
Date: Tue Dec  8 16:28:14 2009
New Revision: 888470

URL: http://svn.apache.org/viewvc?rev=888470&view=rev
Log:
Try to simplify main resolver loop.

Modified:
    
felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/prototype/ProtoResolver.java

Modified: 
felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/prototype/ProtoResolver.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/prototype/ProtoResolver.java?rev=888470&r1=888469&r2=888470&view=diff
==============================================================================
--- 
felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/prototype/ProtoResolver.java
 (original)
+++ 
felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/prototype/ProtoResolver.java
 Tue Dec  8 16:28:14 2009
@@ -93,7 +93,7 @@
         m_resolvingConstraintCache.clear();
         m_resolvedConstraintCache.clear();
         m_verifyCache.clear();
-        Map<Requirement, Set<Capability>> candidateMap = resolve(
+        Map<Requirement, Set<Capability>> candidateMap = resolveRoot(
             module,
             null,
             module,
@@ -108,7 +108,7 @@
         return populateWireMap(module, candidateMap, new HashMap<Module, 
List<Wire>>());
     }
 
-    private Map<Requirement, Set<Capability>> resolve(
+    private Map<Requirement, Set<Capability>> resolveRoot(
         Module module, Capability capGoal, Module blameModule,
         Map<Requirement, Set<Capability>> candidateMap,
         Map<String, Blame> existingConstrains,
@@ -132,190 +132,151 @@
                 Map<String, Blame> existingConstraintsCopy =
                     new HashMap<String, Blame>(existingConstrains);
 
-                try
+                // Add the module to the cycle map; use Boolean.FALSE to
+                // mark it as in the process of being resolved.
+                cycleMap.put(module, Boolean.FALSE);
+
+                m_rootModule = module;
+                m_candidatePermutations.clear();
+
+                // Find candidates for all imports for the target module.
+                List<Requirement> reqs = module.getRequirements();
+                for (Requirement req : reqs)
                 {
-                    // If the module is in the process of being resolved, then
-                    // we are going to want to just return the candidate map
-                    // to break the cycle.
-                    Boolean found = cycleMap.get(module);
-                    if (found != null)
-                    {
-                        // If the modules is in the process of being resolved, 
but
-                        // we have already selected all candidates for it, 
then we
-                        // need to verify consistency before returning the
-                        // candidate map.
-                        if (found.booleanValue())
-                        {
-
-                            Map<String, Blame> currentConstraints =
-                                calculateResolvingConstraints(module, 
blameModule);
-                            checkConsistency(module, capGoal, candidateMap,
-                                existingConstraintsCopy, currentConstraints);
-                            existingConstrains.putAll(existingConstraintsCopy);
-                        }
-                        return candidateMap;
+                    Set<Capability> exporters = findExporters(req);
+                    if ((exporters.size() == 0) && !req.isOptional())
+                    {
+                        throw new RuntimeException("Unable to resolve " + 
module
+                            + ": missing requirement " + req);
                     }
-
-                    // Add the module to the cycle map; use Boolean.FALSE to
-                    // mark it as in the process of being resolved.
-                    cycleMap.put(module, Boolean.FALSE);
-
-                    // If this is the starting module, then remember it.
-                    if (m_rootModule == null)
+                    else if (exporters.size() > 0)
                     {
-                        m_rootModule = module;
-                        m_candidatePermutations.clear();
+                        candidateMap.put(req, exporters);
                     }
+                }
 
-                    // Find candidates for all imports for the target module.
-                    List<Requirement> reqs = module.getRequirements();
+                // Calculate current package constraints for the target module.
+                Map<String, Blame> currentConstraints =
+                    calculateConstraints(module, blameModule);
+
+                // Make copy of current package constraints, since we need to
+                // be able to freely modify, but we may need to revert if a
+                // candidate resolve fails.
+                Map <String, Blame> currentConstraintsCopy = new 
HashMap<String, Blame>();
+
+                m_candidatePermutations.add(candidateMap);
+
+                // Verify current candidates are resolvable and consistent.
+                ResolveException rethrow;
+                do
+                {
+                    rethrow = null;
+
+                    m_resolvingConstraintCache.clear();
+                    m_verifyCache.clear();
+
+                    currentConstraintsCopy.clear();
+                    currentConstraintsCopy.putAll(currentConstraints);
+
+                    candidateMap = m_candidatePermutations.remove(0);
+//System.out.println("+++ TRYING CANDIDATE MAP: " + candidateMap);
+
+                    // Loop through all of the target module's imports and see
+                    // if there is a consistent candidate provider.
                     for (Requirement req : reqs)
                     {
-                        // If we are using a permutated candidate map, then 
the target
-                        // module's candidates may have already been 
calculated, so use
-                        // those instead, otherwise find the matching 
providers.
-                        if (candidateMap.get(req) == null)
+                        // Get the current candidate capability for the 
current import.
+                        Set<Capability> exporters = candidateMap.get(req);
+                        // Optional imports may not have any exporters.
+                        if (exporters == null)
                         {
-                            Set<Capability> exporters = findExporters(req);
-                            if ((exporters.size() == 0) && !req.isOptional())
-                            {
-                                throw new RuntimeException("Unable to resolve 
" + module
-                                    + ": missing requirement " + req);
-                            }
-                            else if (exporters.size() > 0)
-                            {
-                                candidateMap.put(req, exporters);
-                            }
+                            continue;
                         }
-                    }
 
-                    // Calculate current package constraints for the target 
module.
-                    Map<String, Blame> currentConstraints =
-                        calculateConstraints(module, blameModule);
-
-                    // Make copy of current package constraints, since we need 
to
-                    // be able to freely modify, but we may need to revert if a
-                    // candidate resolve fails.
-                    Map <String, Blame> currentConstraintsCopy =
-                        new HashMap<String, Blame>(currentConstraints);
-
-                    // Verify current candidates are resolvable and consistent.
-                    boolean repeat;
-                    do
-                    {
-                        repeat = false;
-
-                        // Loop through all of the target module's imports and 
see
-                        // if there is a consistent candidate provider.
-                        for (Requirement req : reqs)
+                        // Find a consistent candidate.
+                        Capability selectedCandidate = null;
+                        Iterator<Capability> itExporters = 
exporters.iterator();
+                        while ((selectedCandidate == null) && 
itExporters.hasNext())
                         {
-                            // Get the current candidate capability for the 
current import.
-                            Set<Capability> exporters = candidateMap.get(req);
-                            // Optional imports may not have any exporters.
-                            if (exporters == null)
-                            {
-                                continue;
-                            }
-
-                            // Find a consistent candidate.
-                            Capability selectedCandidate = null;
-                            Iterator<Capability> itExporters = 
exporters.iterator();
-                            while ((selectedCandidate == null) && 
itExporters.hasNext())
-                            {
-                                Capability cap = itExporters.next();
+                            Capability cap = itExporters.next();
 //System.out.println("+++ RESOLVING " + cap + " FOR " + module);
-                                try
+                            try
+                            {
+                                // If current candidate is resolved, then try 
to merge
+                                // in its constraints with the existing 
constraints.
+                                if (cap.getModule().isResolved())
                                 {
-                                    // If current candidate is resolved, then 
try to merge
-                                    // in its constraints with the existing 
constraints.
-                                    if (cap.getModule().isResolved())
-                                    {
-                                        mergeResolvedConstraints(
-                                            module, candidateMap, 
currentConstraintsCopy,
-                                            cap);
-                                    }
-                                    // If current candidate is the same as the 
module being
-                                    // resolved, then just directly add it as 
a constraint.
-                                    else if (cap.getModule().equals(module))
-                                    {
-                                        currentConstraintsCopy.put(
-                                            (String) 
cap.getAttribute(Capability.PACKAGE_ATTR).getValue(),
-                                            new Blame(cap, blameModule));
-                                    }
-                                    // If the current candidate is not 
resolved, then try to resolve
-                                    // it, which will also merge packages 
while verify constraints.
-                                    else
-                                    {
-                                        resolve(
-                                            cap.getModule(),
-                                            cap,
-                                            module,
-                                            candidateMap,
-                                            currentConstraintsCopy,
-                                            cycleMap);
-                                    }
-
-                                    // This candidate was consistent, so 
select it.
-                                    selectedCandidate = cap;
+                                    mergeResolvedConstraints(
+                                        module, candidateMap, 
currentConstraintsCopy,
+                                        cap);
+                                }
+                                // If current candidate is the same as the 
module being
+                                // resolved, then just directly add it as a 
constraint.
+                                else if (cap.getModule().equals(module))
+                                {
+                                    currentConstraintsCopy.put(
+                                        (String) 
cap.getAttribute(Capability.PACKAGE_ATTR).getValue(),
+                                        new Blame(cap, blameModule));
                                 }
-                                // If we have a resolve exception, then the 
current candidate
-                                // should be removed. If we are at the root, 
we should try the
-                                // next permutated candidate map if there are 
no more candidates.
-                                catch (ResolveException ex)
+                                // If the current candidate is not resolved, 
then try to resolve
+                                // it, which will also merge packages while 
verify constraints.
+                                else
                                 {
+                                    resolveCandidate(
+                                        cap.getModule(),
+                                        cap,
+                                        module,
+                                        candidateMap,
+                                        currentConstraintsCopy,
+                                        cycleMap);
+                                }
+
+                                // This candidate was consistent, so select it.
+                                selectedCandidate = cap;
+                            }
+                            // If we have a resolve exception, then the 
current candidate
+                            // should be removed. If we are at the root, we 
should try the
+                            // next permutated candidate map if there are no 
more candidates.
+                            catch (ResolveException ex)
+                            {
+// TODO: PROTO RESOLVER: This should be logged.
+                                System.out.println("DEBUG: " + ex);
 System.out.println("RE " + ex);
 ex.printStackTrace();
 //System.out.println("Current candidate map   : " + candidateMap);
-                                    // Remove offending candidate.
-                                    itExporters.remove();
+                                // Remove offending candidate.
+                                itExporters.remove();
 //System.out.println("Updated candidate map   : " + candidateMap);
-                                    if (!itExporters.hasNext() && 
!req.isOptional())
-                                    {
-                                        // TODO: PROTO RESOLVER - Maybe this 
should be moved.
-                                        if ((module == m_rootModule) && 
(m_candidatePermutations.size() > 0))
-                                        {
-                                            currentConstraintsCopy.clear();
-                                            
currentConstraintsCopy.putAll(currentConstraints);
-                                            candidateMap = 
m_candidatePermutations.remove(0);
-//System.out.println("+++ TRYING ALTERNATIVE: " + candidateMap);
-                                            // Flush various caches for new 
candidates.
-                                            m_resolvingConstraintCache.clear();
-                                            m_verifyCache.clear();
-                                            repeat = true;
-                                        }
-                                        else
-                                        {
-                                            candidateMap.remove(req);
-                                            throw new 
ResolveException("Unresolved constraint "
-                                                + req + " in " + module);
-                                        }
-                                    }
+                                if (!itExporters.hasNext() && 
!req.isOptional())
+                                {
+                                    candidateMap.remove(req);
+                                    rethrow = new ResolveException("Unresolved 
constraint "
+                                        + req + " in " + module);
                                 }
                             }
                         }
                     }
-                    while (repeat);
+                }
+                while ((rethrow != null) && (m_candidatePermutations.size() > 
0));
 
-                    // At this point, we have selected a candidate capability 
for
-                    // every import, so we need to merge the calculated 
constraints
-                    // with the existing constraints, checking the consistency
-                    // while we do it.
+                if (rethrow != null)
+                {
+                    throw rethrow;
+                }
+
+                // At this point, we have selected a candidate capability for
+                // every import, so we need to merge the calculated constraints
+                // with the existing constraints, checking the consistency
+                // while we do it.
 //System.out.println("+++ existingConstraints: " + existingConstraintsCopy);
 //System.out.println("+++ currentConstraints : " + currentConstraints);
-                    checkConsistency(
-                        module, capGoal, candidateMap, 
existingConstraintsCopy, currentConstraintsCopy);
-                    // If we are here, then the candidates were consistent with
-                    // existing constraints, so cache the result.
-                    m_resolvingConstraintCache.put(module, 
existingConstraintsCopy);
-                    // Finally, modify the original existing constraints.
-                    existingConstrains.putAll(existingConstraintsCopy);
-                }
-                catch (RuntimeException ex)
-                {
-                    // Any exception should remove the target module from the 
cycle map.
-                    cycleMap.remove(module);
-                    throw ex;
-                }
+                checkConsistency(
+                    module, capGoal, candidateMap, existingConstraintsCopy, 
currentConstraintsCopy);
+                // If we are here, then the candidates were consistent with
+                // existing constraints, so cache the result.
+                m_resolvingConstraintCache.put(module, 
existingConstraintsCopy);
+                // Finally, modify the original existing constraints.
+                existingConstrains.putAll(existingConstraintsCopy);
             }
 
             // Update the cycle map to mark the module as finished.
@@ -326,12 +287,196 @@
         }
         finally
         {
-            // If we are done with the root target module, then forget about 
it.
-            if (module == m_rootModule)
+            m_rootModule = null;
+        }
+    }
+
+    private Map<Requirement, Set<Capability>> resolveCandidate(
+        Module module, Capability capGoal, Module blameModule,
+        Map<Requirement, Set<Capability>> candidateMap,
+        Map<String, Blame> existingConstrains,
+        Map<Module, Boolean> cycleMap)
+    {
+        if (m_isInvokeCount)
+        {
+            String methodName = new 
Exception().fillInStackTrace().getStackTrace()[0].getMethodName();
+            Long count = m_invokeCounts.get(methodName);
+            count = (count == null) ? new Long(1) : new Long(count.longValue() 
+ 1);
+            m_invokeCounts.put(methodName, count);
+        }
+
+        // If the module is already resolved, then do nothing.
+        if (!module.isResolved())
+        {
+            // Copy the existing constraints, since we need to be able
+            // to freely modify them.
+            Map<String, Blame> existingConstraintsCopy =
+                new HashMap<String, Blame>(existingConstrains);
+
+            try
+            {
+                // If the module is in the process of being resolved, then
+                // we are going to want to just return the candidate map
+                // to break the cycle.
+                Boolean found = cycleMap.get(module);
+                if (found != null)
+                {
+                    // If the modules is in the process of being resolved, but
+                    // we have already selected all candidates for it, then we
+                    // need to verify consistency before returning the
+                    // candidate map.
+                    if (found.booleanValue())
+                    {
+
+                        Map<String, Blame> currentConstraints =
+                            calculateResolvingConstraints(module, blameModule);
+                        checkConsistency(module, capGoal, candidateMap,
+                            existingConstraintsCopy, currentConstraints);
+                        existingConstrains.putAll(existingConstraintsCopy);
+                    }
+                    return candidateMap;
+                }
+
+                // Add the module to the cycle map; use Boolean.FALSE to
+                // mark it as in the process of being resolved.
+                cycleMap.put(module, Boolean.FALSE);
+
+                // Find candidates for all imports for the target module.
+                List<Requirement> reqs = module.getRequirements();
+                for (Requirement req : reqs)
+                {
+                    // If we are using a permutated candidate map, then the 
target
+                    // module's candidates may have already been calculated, 
so use
+                    // those instead, otherwise find the matching providers.
+                    if (candidateMap.get(req) == null)
+                    {
+                        Set<Capability> exporters = findExporters(req);
+                        if ((exporters.size() == 0) && !req.isOptional())
+                        {
+                            throw new RuntimeException("Unable to resolve " + 
module
+                                + ": missing requirement " + req);
+                        }
+                        else if (exporters.size() > 0)
+                        {
+                            candidateMap.put(req, exporters);
+                        }
+                    }
+                }
+
+                // Calculate current package constraints for the target module.
+                Map<String, Blame> currentConstraints =
+                    calculateConstraints(module, blameModule);
+
+                // Make copy of current package constraints, since we need to
+                // be able to freely modify, but we may need to revert if a
+                // candidate resolve fails.
+                Map <String, Blame> currentConstraintsCopy =
+                    new HashMap<String, Blame>(currentConstraints);
+
+                // Verify current candidates are resolvable and consistent.
+                // Loop through all of the target module's imports and see
+                // if there is a consistent candidate provider.
+                for (Requirement req : reqs)
+                {
+                    // Get the current candidate capability for the current 
import.
+                    Set<Capability> exporters = candidateMap.get(req);
+                    // Optional imports may not have any exporters.
+                    if (exporters == null)
+                    {
+                        continue;
+                    }
+
+                    // Find a consistent candidate.
+                    Capability selectedCandidate = null;
+                    Iterator<Capability> itExporters = exporters.iterator();
+                    while ((selectedCandidate == null) && 
itExporters.hasNext())
+                    {
+                        Capability cap = itExporters.next();
+//System.out.println("+++ RESOLVING " + cap + " FOR " + module);
+                        try
+                        {
+                            // If current candidate is resolved, then try to 
merge
+                            // in its constraints with the existing 
constraints.
+                            if (cap.getModule().isResolved())
+                            {
+                                mergeResolvedConstraints(
+                                    module, candidateMap, 
currentConstraintsCopy,
+                                    cap);
+                            }
+                            // If current candidate is the same as the module 
being
+                            // resolved, then just directly add it as a 
constraint.
+                            else if (cap.getModule().equals(module))
+                            {
+                                currentConstraintsCopy.put(
+                                    (String) 
cap.getAttribute(Capability.PACKAGE_ATTR).getValue(),
+                                    new Blame(cap, blameModule));
+                            }
+                            // If the current candidate is not resolved, then 
try to resolve
+                            // it, which will also merge packages while verify 
constraints.
+                            else
+                            {
+                                resolveCandidate(
+                                    cap.getModule(),
+                                    cap,
+                                    module,
+                                    candidateMap,
+                                    currentConstraintsCopy,
+                                    cycleMap);
+                            }
+
+                            // This candidate was consistent, so select it.
+                            selectedCandidate = cap;
+                        }
+                        // If we have a resolve exception, then the current 
candidate
+                        // should be removed. If we are at the root, we should 
try the
+                        // next permutated candidate map if there are no more 
candidates.
+                        catch (ResolveException ex)
+                        {
+// TODO: PROTO RESOLVER: This should be logged.
+                                System.out.println("DEBUG: " + ex);
+System.out.println("RE " + ex);
+ex.printStackTrace();
+//System.out.println("Current candidate map   : " + candidateMap);
+                            // Remove offending candidate.
+                            itExporters.remove();
+//System.out.println("Updated candidate map   : " + candidateMap);
+                            if (!itExporters.hasNext() && !req.isOptional())
+                            {
+                                candidateMap.remove(req);
+                                throw new ResolveException("Unresolved 
constraint "
+                                    + req + " in " + module);
+                            }
+                        }
+                    }
+                }
+
+                // At this point, we have selected a candidate capability for
+                // every import, so we need to merge the calculated constraints
+                // with the existing constraints, checking the consistency
+                // while we do it.
+//System.out.println("+++ existingConstraints: " + existingConstraintsCopy);
+//System.out.println("+++ currentConstraints : " + currentConstraints);
+                checkConsistency(
+                    module, capGoal, candidateMap, existingConstraintsCopy, 
currentConstraintsCopy);
+                // If we are here, then the candidates were consistent with
+                // existing constraints, so cache the result.
+                m_resolvingConstraintCache.put(module, 
existingConstraintsCopy);
+                // Finally, modify the original existing constraints.
+                existingConstrains.putAll(existingConstraintsCopy);
+            }
+            catch (RuntimeException ex)
             {
-                m_rootModule = null;
+                // Any exception should remove the target module from the 
cycle map.
+                cycleMap.remove(module);
+                throw ex;
             }
         }
+
+        // Update the cycle map to mark the module as finished.
+        cycleMap.put(module, Boolean.TRUE);
+
+        // Return the updated candidate map.
+        return candidateMap;
     }
 
     private Map<String, Blame> calculateResolvingConstraints(Module module, 
Module blameModule)


Reply via email to