[FELIX-4942] Better use of OpenHashMap in Candidates

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1690705 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/resolver/src/main/java/org/apache/felix/resolver/Candidates.java b/resolver/src/main/java/org/apache/felix/resolver/Candidates.java
index 96bed4d..8f56fdd 100644
--- a/resolver/src/main/java/org/apache/felix/resolver/Candidates.java
+++ b/resolver/src/main/java/org/apache/felix/resolver/Candidates.java
@@ -24,15 +24,14 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.TreeMap;
 
-import org.apache.felix.resolver.util.CopyOnWriteSet;
 import org.apache.felix.resolver.util.CopyOnWriteList;
+import org.apache.felix.resolver.util.CopyOnWriteSet;
 import org.apache.felix.resolver.util.OpenHashMap;
 import org.apache.felix.resolver.util.OpenHashMapList;
 import org.apache.felix.resolver.util.OpenHashMapSet;
@@ -63,7 +62,7 @@
     // when a revision being resolved has fragments to attach to it.
     private final Map<Resource, WrappedResource> m_allWrappedHosts;
     // Map used when populating candidates to hold intermediate and final results.
-    private final Map<Resource, Object> m_populateResultCache;
+    private final OpenHashMap<Resource, Object> m_populateResultCache;
 
     // Flag to signal if fragments are present in the candidate map.
     private boolean m_fragmentsPresent = false;
@@ -81,7 +80,8 @@
         Set<Resource> mandatoryResources,
         OpenHashMapSet<Capability, Requirement> dependentMap,
         OpenHashMapList<Requirement, Capability> candidateMap,
-        Map<Resource, WrappedResource> wrappedHosts, Map<Resource, Object> populateResultCache,
+        Map<Resource, WrappedResource> wrappedHosts,
+        OpenHashMap<Resource, Object> populateResultCache,
         boolean fragmentsPresent,
         Map<Resource, Boolean> onDemandResources,
         Map<Capability, Requirement> substitutableMap,
@@ -107,9 +107,9 @@
         m_dependentMap = new OpenHashMapSet<Capability, Requirement>();
         m_candidateMap = new OpenHashMapList<Requirement, Capability>();
         m_allWrappedHosts = new HashMap<Resource, WrappedResource>();
-        m_populateResultCache = new LinkedHashMap<Resource, Object>();
+        m_populateResultCache = new OpenHashMap<Resource, Object>();
         m_validOnDemandResources = validOnDemandResources;
-        m_subtitutableMap = new LinkedHashMap<Capability, Requirement>();
+        m_subtitutableMap = new OpenHashMap<Capability, Requirement>();
         m_delta = new OpenHashMapSet<Requirement, Capability>(3);
     }
 
@@ -373,7 +373,7 @@
 
     private void populateSubstitutables()
     {
-        for (Map.Entry<Resource, Object> populated : m_populateResultCache.entrySet())
+        for (Map.Entry<Resource, Object> populated : m_populateResultCache.fast())
         {
             if (populated.getValue() instanceof Boolean)
             {
@@ -395,16 +395,16 @@
         {
             return;
         }
-        Map<String, List<Capability>> exportNames = new LinkedHashMap<String, List<Capability>>();
+        OpenHashMap<String, List<Capability>> exportNames = new OpenHashMap<String, List<Capability>>() {
+            @Override
+            protected List<Capability> compute(String s) {
+                return new ArrayList<Capability>(1);
+            }
+        };
         for (Capability packageExport : packageExports)
         {
             String packageName = (String) packageExport.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
-            List<Capability> caps = exportNames.get(packageName);
-            if (caps == null)
-            {
-                caps = new ArrayList<Capability>(1);
-                exportNames.put(packageName, caps);
-            }
+            List<Capability> caps = exportNames.getOrCompute(packageName);
             caps.add(packageExport);
         }
         // Check if any requirements substitute one of the exported packages
@@ -413,18 +413,13 @@
             List<Capability> substitutes = m_candidateMap.get(req);
             if (substitutes != null && !substitutes.isEmpty())
             {
-                String packageName = (String) substitutes.iterator().next().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
+                String packageName = (String) substitutes.get(0).getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
                 List<Capability> exportedPackages = exportNames.get(packageName);
                 if (exportedPackages != null)
                 {
                     // The package is exported;
                     // Check if the requirement only has the bundle's own export as candidates
-                    substitutes = new ArrayList<Capability>(substitutes);
-                    for (Capability exportedPackage : exportedPackages)
-                    {
-                        substitutes.remove(exportedPackage);
-                    }
-                    if (!substitutes.isEmpty())
+                    if (!exportedPackages.containsAll(substitutes))
                     {
                         for (Capability exportedPackage : exportedPackages)
                         {
@@ -443,7 +438,7 @@
 
     ResolutionError checkSubstitutes(List<Candidates> importPermutations)
     {
-        Map<Capability, Integer> substituteStatuses = new LinkedHashMap<Capability, Integer>(m_subtitutableMap.size());
+        OpenHashMap<Capability, Integer> substituteStatuses = new OpenHashMap<Capability, Integer>(m_subtitutableMap.size());
         for (Capability substitutable : m_subtitutableMap.keySet())
         {
             // initialize with unprocessed
@@ -456,7 +451,7 @@
         }
 
         // Remove any substituted exports from candidates
-        for (Map.Entry<Capability, Integer> substituteStatus : substituteStatuses.entrySet())
+        for (Map.Entry<Capability, Integer> substituteStatus : substituteStatuses.fast())
         {
             if (substituteStatus.getValue() == SUBSTITUTED)
             {
@@ -817,7 +812,7 @@
         List<Capability> candidates = m_candidateMap.get(req);
         if (candidates != null && !candidates.isEmpty())
         {
-            return m_candidateMap.get(req).get(0);
+            return candidates.get(0);
         }
         return null;
     }
@@ -832,11 +827,7 @@
             m_candidateMap.remove(req);
         }
         // Update the delta with the removed capability
-        CopyOnWriteSet<Capability> capPath = m_delta.get(req);
-        if (capPath == null) {
-            capPath = new CopyOnWriteSet<Capability>();
-            m_delta.put(req, capPath);
-        }
+        CopyOnWriteSet<Capability> capPath = m_delta.getOrCompute(req);
         capPath.add(cap);
     }
 
@@ -845,11 +836,7 @@
         List<Capability> l = m_candidateMap.get(req);
         l.removeAll(caps);
         // Update candidates delta with the removed capabilities.
-        CopyOnWriteSet<Capability> capPath = m_delta.get(req);
-        if (capPath == null) {
-            capPath = new CopyOnWriteSet<Capability>();
-            m_delta.put(req, capPath);
-        }
+        CopyOnWriteSet<Capability> capPath = m_delta.getOrCompute(req);
         capPath.addAll(caps);
         return l;
     }
@@ -1089,18 +1076,14 @@
     {
         Map<Capability, Map<String, Map<Version, List<Requirement>>>> hostFragments =
             new HashMap<Capability, Map<String, Map<Version, List<Requirement>>>>();
-        for (Entry<Requirement, CopyOnWriteList<Capability>> entry : m_candidateMap.entrySet()) {
+        for (Entry<Requirement, CopyOnWriteList<Capability>> entry : m_candidateMap.fast())
+        {
             Requirement req = entry.getKey();
             List<Capability> caps = entry.getValue();
             for (Capability cap : caps)
             {
                 // Record the requirement as dependent on the capability.
-                CopyOnWriteSet<Requirement> dependents = m_dependentMap.get(cap);
-                if (dependents == null)
-                {
-                    dependents = new CopyOnWriteSet<Requirement>();
-                    m_dependentMap.put(cap, dependents);
-                }
+                CopyOnWriteSet<Requirement> dependents = m_dependentMap.getOrCompute(cap);
                 dependents.add(req);
 
                 // Keep track of hosts and associated fragments.