karaf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cschnei...@apache.org
Subject [1/3] karaf git commit: KARAF-5314 Added a features cache that increases the performance of the filtering of the required features from the available features.
Date Mon, 21 Aug 2017 08:25:03 GMT
Repository: karaf
Updated Branches:
  refs/heads/master 658ee488f -> 5a8133dbb


KARAF-5314 Added a features cache that increases the performance of the filtering of the required
features from the available features.

The performance of the filtering logic decresed when the java streams API was used in 4.1
compared to for loops in 4.0. I reverted the filtering logic to use for loops and also introduced
a features cache. This increased the performance by a huge margin, almost 20X faster when
there are ~900 available features and ~300 required features from a highly complex and huge
feature dependency tree.


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/3cbd810e
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/3cbd810e
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/3cbd810e

Branch: refs/heads/master
Commit: 3cbd810ea37e837950f1f8427f793c878423ba7a
Parents: 658ee48
Author: Vinay Shankar (e24113) <Vinay.Shankar@cmegroup.com>
Authored: Fri Aug 18 13:55:58 2017 -0500
Committer: Christian Schneider <chris@die-schneider.net>
Committed: Fri Aug 18 23:22:25 2017 +0200

----------------------------------------------------------------------
 .../apache/karaf/profile/assembly/Builder.java  | 38 +++++++++++++++-----
 1 file changed, 30 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/3cbd810e/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java
----------------------------------------------------------------------
diff --git a/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java b/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java
index 27b83a6..e9cc67e 100644
--- a/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java
+++ b/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java
@@ -39,6 +39,7 @@ import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.TreeMap;
 import java.util.TreeSet;
@@ -49,7 +50,6 @@ import java.util.function.Function;
 import java.util.jar.Attributes;
 import java.util.jar.Manifest;
 import java.util.regex.Pattern;
-import java.util.stream.Collectors;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
@@ -805,10 +805,11 @@ public class Builder {
             allInstalledFeatures.addAll(repo.getFeature());
         }
         Set<Feature> installedFeatures = new LinkedHashSet<>();
+        Map<String, Map<Version, Feature>> featuresCache = new HashMap<>();
         // Add boot features for search
         allInstalledFeatures.addAll(allBootFeatures);
         for (String feature : installedEffective.getFeatures()) {
-            addFeatures(allInstalledFeatures, feature, installedFeatures, true);
+            addFeatures(allInstalledFeatures, feature, installedFeatures, true, featuresCache);
         }
         ArtifactInstaller installer = new ArtifactInstaller(systemDirectory, downloader,
blacklistedBundles);
         for (Feature feature : installedFeatures) {
@@ -882,7 +883,8 @@ public class Builder {
 
         // Compute startup feature dependencies
         Set<Feature> bootFeatures = new HashSet<>();
-        addFeatures(allBootFeatures, generated.getName(), bootFeatures, true);
+        Map<String, Map<Version, Feature>> featuresCache = new HashMap<>();
+        addFeatures(allBootFeatures, generated.getName(), bootFeatures, true, featuresCache);
         for (Feature feature : bootFeatures) {
             // the feature is a startup feature, updating startup.properties file
             LOGGER.info("   Feature " + feature.getId() + " is defined as a boot feature");
@@ -1239,14 +1241,16 @@ public class Builder {
         return startupEffective;
     }
 
-    private void addFeatures(Set<Feature> allFeatures, String feature, Set<Feature>
features, boolean mandatory) {
+    private void addFeatures(Set<Feature> allFeatures, String feature, Set<Feature>
features, boolean mandatory, Map<String, Map<Version, Feature>> featuresCache)
{
         String name;
+        Version osgiVersion;
         VersionRange range;
         int idx = feature.indexOf('/');
         if (idx > 0) {
             name = feature.substring(0, idx);
             String version = feature.substring(idx + 1);
             version = version.trim();
+            osgiVersion = VersionTable.getVersion(version);
             if (version.equals(org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION))
{
                 range = new VersionRange(Version.emptyVersion);
             } else {
@@ -1254,18 +1258,36 @@ public class Builder {
             }
         } else {
             name = feature;
+            osgiVersion = Version.emptyVersion;
             range = new VersionRange(Version.emptyVersion);
         }
-        Set<Feature> set = allFeatures.stream()
-                .filter(f -> f.getName().equals(name) && range.contains(VersionTable.getVersion(f.getVersion())))
-                .collect(Collectors.toSet());
+        Set<Feature> set = new HashSet<>();
+        boolean featurePresentInCache = false;
+        Optional<Map<Version, Feature>> optionalVersionFeatureMap = Optional.ofNullable(featuresCache.get(name));
+        if(optionalVersionFeatureMap.isPresent()) {
+            Optional<Feature> cachedFeature = Optional.ofNullable(optionalVersionFeatureMap.get().get(osgiVersion));
+            if(cachedFeature.isPresent()){
+                set.add(cachedFeature.get());
+                featurePresentInCache = true;
+            }
+        }
+        if(!featurePresentInCache) {
+            for (Feature f : allFeatures) {
+                if (f.getName().equals(name) && range.contains(VersionTable.getVersion(f.getVersion())))
{
+                    set.add(f);
+                    Map<Version, Feature> versionFeatureMap = Optional.ofNullable(featuresCache.get(name)).orElse(new
HashMap<>());
+                    versionFeatureMap.put(osgiVersion, f);
+                    featuresCache.put(name, versionFeatureMap);
+                }
+            }
+        }
         if (mandatory && set.isEmpty()) {
             throw new IllegalStateException("Could not find matching feature for " + feature);
         }
         for (Feature f : set) {
             features.add(f);
             for (Dependency dep : f.getFeature()) {
-                addFeatures(allFeatures, dep.toString(), features, !dep.isDependency() &&
!dep.isPrerequisite());
+                addFeatures(allFeatures, dep.toString(), features, !dep.isDependency() &&
!dep.isPrerequisite(), featuresCache);
             }
         }
     }


Mime
View raw message