From 963f01211bacb308a4998f8eb292d7d36f9323f5 Mon Sep 17 00:00:00 2001 From: Andreas Bayha <bayha@fortiss.org> Date: Thu, 20 Apr 2023 13:13:06 +0200 Subject: [PATCH] Fixed parallel translation of multiple Objects Objects which are referenced several times were also translated several times. This has been fixed. Issue-ref: 4240 Issue-URL: af3#4240 Signed-off-by: Andreas Bayha <bayha@fortiss.org> --- .../org/fortiss/variability/analysis/.ratings | 2 +- .../variability/analysis/BucketSetMap.java | 54 +++++++++++++++++++ .../analysis/ProductLineBaseTranslation.java | 26 ++++----- 3 files changed, 69 insertions(+), 13 deletions(-) create mode 100644 org.fortiss.variability/src/org/fortiss/variability/analysis/BucketSetMap.java diff --git a/org.fortiss.variability/src/org/fortiss/variability/analysis/.ratings b/org.fortiss.variability/src/org/fortiss/variability/analysis/.ratings index 3ddc45914..a69031f1f 100644 --- a/org.fortiss.variability/src/org/fortiss/variability/analysis/.ratings +++ b/org.fortiss.variability/src/org/fortiss/variability/analysis/.ratings @@ -1,3 +1,3 @@ BucketMap.java c9572ca6503b41462240c1931cb1390af7b46c73 YELLOW +BucketSetMap.java 2c87b2f7f9ac68ed0aa669d665a1f6cb91d27207 YELLOW DualKeyMap.java 75fbe85a54e5a655aaf67108ae004f98ed2879d8 YELLOW -ProductLineTranslation.java 4ecd6805d3cd0b015ea013dcaf8a7bcc26f5b925 RED diff --git a/org.fortiss.variability/src/org/fortiss/variability/analysis/BucketSetMap.java b/org.fortiss.variability/src/org/fortiss/variability/analysis/BucketSetMap.java new file mode 100644 index 000000000..2c87b2f7f --- /dev/null +++ b/org.fortiss.variability/src/org/fortiss/variability/analysis/BucketSetMap.java @@ -0,0 +1,54 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2022 fortiss GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.variability.analysis; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * {@link Map} implementation which maps a key to a {@link Set} of values. + * + * @author bayha + */ +public class BucketSetMap<K, V> extends HashMap<K, Set<V>> { + /** ISerializable */ + private static final long serialVersionUID = 312480465506162554L; + + /** + * Adds a given value to the set for the given key. + * + * @param key + * The key for which an additional value shall be added. + * @param value + * The additional value that shall be added. + * + * @return The new set of values for the given key. + */ + public Set<V> append(K key, V value) { + Set<V> lst = this.get(key); + + if(lst == null) { + lst = new HashSet<V>(); + this.put(key, lst); + } + + lst.add(value); + + return lst; + } +} diff --git a/org.fortiss.variability/src/org/fortiss/variability/analysis/ProductLineBaseTranslation.java b/org.fortiss.variability/src/org/fortiss/variability/analysis/ProductLineBaseTranslation.java index 437927a20..744e5c9a2 100644 --- a/org.fortiss.variability/src/org/fortiss/variability/analysis/ProductLineBaseTranslation.java +++ b/org.fortiss.variability/src/org/fortiss/variability/analysis/ProductLineBaseTranslation.java @@ -66,20 +66,20 @@ public class ProductLineBaseTranslation { protected static BoolSort BOOL_SORT; /** Mapping from classes to all their objects */ - protected BucketMap<EClass, EObject> allObjects = new BucketMap<EClass, EObject>(); + protected BucketSetMap<EClass, EObject> allObjects = new BucketSetMap<EClass, EObject>(); /** Mapping from classes to all their subclasses */ - protected BucketMap<EClass, EClass> allSubclasses = new BucketMap<EClass, EClass>(); + protected BucketSetMap<EClass, EClass> allSubclasses = new BucketSetMap<EClass, EClass>(); /** Classes which are not supposed to be translated (usually for optimization). */ protected Set<EClass> excludedClasses = new HashSet<EClass>(); /** References which are not supposed to be translated (usually for optimization). */ protected Set<EReference> excludedReferences = new HashSet<EReference>(); /** Mapping from classes to all attributes of the respective type. */ - protected BucketMap<EClass, EAttribute> translatedAttributes = - new BucketMap<EClass, EAttribute>(); + protected BucketSetMap<EClass, EAttribute> translatedAttributes = + new BucketSetMap<EClass, EAttribute>(); /** Mapping from classes to all references of the respective type. */ - protected BucketMap<EClass, EReference> translatedReferences = - new BucketMap<EClass, EReference>(); + protected BucketSetMap<EClass, EReference> translatedReferences = + new BucketSetMap<EClass, EReference>(); /** Mapping of attributes to their translated Z3 function. */ protected DualKeyMap<EAttribute, EClass, FuncDecl> eAttribute2FunDecl = new DualKeyMap<EAttribute, EClass, FuncDecl>(); @@ -380,9 +380,9 @@ public class ProductLineBaseTranslation { private void translateObjects() { // Translate objects by class. for(EClass ec : allObjects.keySet()) { - List<EObject> Objs = allObjects.get(ec); + Set<EObject> Objs = allObjects.get(ec); - List<EAttribute> attributes = translatedAttributes.get(ec); + Set<EAttribute> attributes = translatedAttributes.get(ec); if(attributes != null) { for(EAttribute ea : attributes) { FuncDecl attFunc = eAttribute2FunDecl.get(ea, ec); @@ -396,7 +396,7 @@ public class ProductLineBaseTranslation { } } - List<EReference> references = translatedReferences.get(ec); + Set<EReference> references = translatedReferences.get(ec); if(references != null) { for(EReference er : references) { FuncDecl refFunc = eReference2FunDecl.get(er, ec); @@ -645,7 +645,7 @@ public class ProductLineBaseTranslation { * subtypes. */ private EnumSort translateSuperType(EClass refType) { - List<EClass> subClasses = allSubclasses.get(refType); + Set<EClass> subClasses = allSubclasses.get(refType); if(subClasses == null) { // There are no objects of this class in this case, hence it is not relevant. return null; @@ -702,9 +702,9 @@ public class ProductLineBaseTranslation { /** Creates the types for all classes and objects in Z3. */ private void translateClassesMetamodel() { for(EClass cls : allObjects.keySet()) { - List<EObject> objs = allObjects.get(cls); + List<EObject> objs = new ArrayList<EObject>(allObjects.get(cls)); - // The last index is added for null. + // The last index is added for the null element. Symbol[] objSymbols = new Symbol[objs.size() + 1]; String clsName = cls.getName(); for(int i = 0; i < objs.size(); i++) { @@ -715,9 +715,11 @@ public class ProductLineBaseTranslation { } objSymbols[objs.size()] = ctx.mkSymbol(clsName + "NONE"); + // Create EnumSort for class EnumSort enumSort = ctx.mkEnumSort(ctx.mkSymbol(clsName), objSymbols); eClass2Datatype.put(cls, enumSort); + // Map objects to z3 enum literals Expr[] consts = enumSort.getConsts(); for(int i = 0; i < objs.size(); i++) { eObject2Expr.put(objs.get(i), cls, consts[i]); -- GitLab