aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers
diff options
context:
space:
mode:
authorLibravatar Oszkar Semerath <Oszkar Semerath@DESKTOP-DNR7JQ7>2021-07-02 16:09:07 +0200
committerLibravatar Oszkar Semerath <Oszkar Semerath@DESKTOP-DNR7JQ7>2021-07-02 16:09:07 +0200
commitbd702e7964420c897799cd01ff658a2cc098c780 (patch)
treed8450dad2a497167273a5e88a37a4218507d6f63 /Solvers
parentfixed bigdecimal <-> double casting error (diff)
downloadVIATRA-Generator-bd702e7964420c897799cd01ff658a2cc098c780.tar.gz
VIATRA-Generator-bd702e7964420c897799cd01ff658a2cc098c780.tar.zst
VIATRA-Generator-bd702e7964420c897799cd01ff658a2cc098c780.zip
First version of the versioned hashmap
Diffstat (limited to 'Solvers')
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/.classpath12
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/.project23
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/.settings/org.eclipse.jdt.core.prefs14
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/bin/.gitignore1
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/BooleanValue.java17
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/DataSymbol.java5
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/DefinedSymbol.java11
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/Logic2Valued.java9
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/Logic4Valued.java22
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/Model.java10
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/ModelObject.java5
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/NamedTruthValue.java13
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/PrimitiveSymbol.java5
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/Symbol.java5
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/TruthValue.java5
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/ContinousHashProvider.java34
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/Versioned.java6
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/VersionedMap.java63
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/ImmutableNode.java215
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/ImmutableNodeIterator.java5
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/MutableNode.java241
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/MutableNodeIterator.java29
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/Node.java69
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/NodeIterator.java13
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/tests/org/eclipse/viatra/solver/data/map/MapSmokeTest.java82
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/tests/org/eclipse/viatra/solver/data/map/MapTestEnvironment.java41
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/tests/org/eclipse/viatra/solver/data/map/MapTests.java5
27 files changed, 960 insertions, 0 deletions
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/.classpath b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/.classpath
new file mode 100644
index 00000000..0fa31827
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/.classpath
@@ -0,0 +1,12 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<classpath>
3 <classpathentry kind="src" path="src"/>
4 <classpathentry kind="src" path="tests"/>
5 <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/>
6 <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
7 <attributes>
8 <attribute name="module" value="true"/>
9 </attributes>
10 </classpathentry>
11 <classpathentry kind="output" path="bin"/>
12</classpath>
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/.project b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/.project
new file mode 100644
index 00000000..464aef51
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/.project
@@ -0,0 +1,23 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<projectDescription>
3 <name>org.eclipse.viatra.solver.data</name>
4 <comment></comment>
5 <projects>
6 </projects>
7 <buildSpec>
8 <buildCommand>
9 <name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
10 <arguments>
11 </arguments>
12 </buildCommand>
13 <buildCommand>
14 <name>org.eclipse.jdt.core.javabuilder</name>
15 <arguments>
16 </arguments>
17 </buildCommand>
18 </buildSpec>
19 <natures>
20 <nature>org.eclipse.jdt.core.javanature</nature>
21 <nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
22 </natures>
23</projectDescription>
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/.settings/org.eclipse.jdt.core.prefs b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..f2525a8b
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,14 @@
1eclipse.preferences.version=1
2org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
4org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
5org.eclipse.jdt.core.compiler.compliance=11
6org.eclipse.jdt.core.compiler.debug.lineNumber=generate
7org.eclipse.jdt.core.compiler.debug.localVariable=generate
8org.eclipse.jdt.core.compiler.debug.sourceFile=generate
9org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
10org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
11org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
12org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
13org.eclipse.jdt.core.compiler.release=enabled
14org.eclipse.jdt.core.compiler.source=11
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/bin/.gitignore b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/bin/.gitignore
new file mode 100644
index 00000000..cf1db2ee
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/bin/.gitignore
@@ -0,0 +1 @@
/org/
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/BooleanValue.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/BooleanValue.java
new file mode 100644
index 00000000..7b0e565b
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/BooleanValue.java
@@ -0,0 +1,17 @@
1package org.eclipse.viatra.solver.data;
2
3public class BooleanValue implements TruthValue {
4 private final boolean value;
5 protected BooleanValue(final boolean value) {
6 this.value = value;
7 }
8 public static final BooleanValue trueValue = new BooleanValue(true);
9 public static final BooleanValue falseValue = new BooleanValue(false);
10
11 @Override
12 public String getName() {
13 // TODO Auto-generated method stub
14 return Boolean.toString(value);
15 }
16
17}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/DataSymbol.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/DataSymbol.java
new file mode 100644
index 00000000..74624db6
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/DataSymbol.java
@@ -0,0 +1,5 @@
1package org.eclipse.viatra.solver.data;
2
3public class DataSymbol {
4
5}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/DefinedSymbol.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/DefinedSymbol.java
new file mode 100644
index 00000000..40d01721
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/DefinedSymbol.java
@@ -0,0 +1,11 @@
1package org.eclipse.viatra.solver.data;
2
3public class DefinedSymbol extends Symbol {
4 private final String name;
5 public DefinedSymbol(String name) {
6 this.name = name;
7 }
8 public String getName() {
9 return name;
10 }
11}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/Logic2Valued.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/Logic2Valued.java
new file mode 100644
index 00000000..7a807155
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/Logic2Valued.java
@@ -0,0 +1,9 @@
1package org.eclipse.viatra.solver.data;
2
3public class Logic2Valued {
4 protected static final String trueName = "true";
5 protected static final String falseName = "false";
6
7 public static final TruthValue trueValue = new NamedTruthValue(trueName);
8 public static final TruthValue falseValue = new NamedTruthValue(falseName);
9}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/Logic4Valued.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/Logic4Valued.java
new file mode 100644
index 00000000..5f1e2bd8
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/Logic4Valued.java
@@ -0,0 +1,22 @@
1package org.eclipse.viatra.solver.data;
2
3public class Logic4Valued extends Logic2Valued {
4 protected static final String unknownName = "unknown";
5 protected static final String errorName = "error";
6
7 public static final TruthValue unknownValue = new NamedTruthValue(unknownName);
8 public static final TruthValue errorValue = new NamedTruthValue(errorName);
9
10// public TruthValue getImplMin(TruthValue a, TruthValue b) {
11//
12// }
13// public TruthValue getImplMax(TruthValue a, TruthValue b) {
14//
15// }
16// public TruthValue getInfoMin(TruthValue a, TruthValue b) {
17//
18// }
19// public TruthValue getInfoMax(TruthValue a, TruthValue b) {
20//
21// }
22}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/Model.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/Model.java
new file mode 100644
index 00000000..6f5c58ce
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/Model.java
@@ -0,0 +1,10 @@
1package org.eclipse.viatra.solver.data;
2
3import java.util.List;
4import java.util.Map;
5import java.util.Set;
6
7public class Model {
8 Set<ModelObject> objects;
9 Map<String,Map<List<ModelObject>,TruthValue>> interpretation;
10}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/ModelObject.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/ModelObject.java
new file mode 100644
index 00000000..73607f82
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/ModelObject.java
@@ -0,0 +1,5 @@
1package org.eclipse.viatra.solver.data;
2
3public class ModelObject {
4
5}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/NamedTruthValue.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/NamedTruthValue.java
new file mode 100644
index 00000000..be3a2351
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/NamedTruthValue.java
@@ -0,0 +1,13 @@
1package org.eclipse.viatra.solver.data;
2
3public class NamedTruthValue implements TruthValue {
4 private final String name;
5 public NamedTruthValue(String name) {
6 this.name = name;
7 }
8 @Override
9 public String getName() {
10 return this.name;
11 }
12
13}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/PrimitiveSymbol.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/PrimitiveSymbol.java
new file mode 100644
index 00000000..6bf0b195
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/PrimitiveSymbol.java
@@ -0,0 +1,5 @@
1package org.eclipse.viatra.solver.data;
2
3public class PrimitiveSymbol {
4
5}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/Symbol.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/Symbol.java
new file mode 100644
index 00000000..d403e181
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/Symbol.java
@@ -0,0 +1,5 @@
1package org.eclipse.viatra.solver.data;
2
3public class Symbol {
4
5}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/TruthValue.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/TruthValue.java
new file mode 100644
index 00000000..5dbde11c
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/TruthValue.java
@@ -0,0 +1,5 @@
1package org.eclipse.viatra.solver.data;
2
3interface TruthValue {
4 public String getName();
5}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/ContinousHashProvider.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/ContinousHashProvider.java
new file mode 100644
index 00000000..c4567458
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/ContinousHashProvider.java
@@ -0,0 +1,34 @@
1package org.eclipse.viatra.solver.data.map;
2
3/**
4 * A class representing an equivalence relation for a type {@code KEY} with a continuous hash function.
5 * @author Oszkar Semerath
6 *
7 * @param <KEY> Target java type.
8 */
9public interface ContinousHashProvider<KEY> {
10 /**
11 * Provides a hash code for a object {@code key} with a given {@code index}. It has the following contracts:
12 * <ul>
13 * <li>If {@link #equals}{@code (key1,key2)}, then {@code getHash(key1, index) == getHash(key2, index)} for all values of {@code index}.</li>
14 * <li>If {@code getHash(key1,index) == getHash(key2, index)} for all values of {@code index}, then {@link #equals}{@code (key1, key2)}</li>
15 * </ul>
16 * Check {@link #equals} for further details.
17 * @param key The target data object.
18 * @param index The depth of the the hash code. Needs to be non-negative.
19 * @return A hash code.
20 */
21 public int getHash(KEY key, int index);
22 /**
23 * Compares the equivalnce of two objects {@code key1} and {@code key2}. It has the contracts of a equivalence relation:
24 * <ul>
25 * <li> Reflexive: {@code equals(key,key) == true}.</li>
26 * <li> Symmetric: {@code equals(key1,key2) == equals(key2,key1)}.</li>
27 * <li> Transitive: {@code equals(key1,key2) == true} and {@code equals(key2,key3) == true} then {@code equals(key1,key3) == true}.</li>
28 * </ul>
29 * @param key1 First data object.
30 * @param key2 Second data object.
31 * @return whether {@code key1} and {@code key2} are equivalent with respect to an equivalence relation represented by the given .
32 */
33 public boolean equals(KEY key1, KEY key2);
34}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/Versioned.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/Versioned.java
new file mode 100644
index 00000000..d58c458e
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/Versioned.java
@@ -0,0 +1,6 @@
1package org.eclipse.viatra.solver.data.map;
2
3public interface Versioned {
4 public long commit();
5 public void restore(long state);
6}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/VersionedMap.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/VersionedMap.java
new file mode 100644
index 00000000..41fd55b7
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/VersionedMap.java
@@ -0,0 +1,63 @@
1package org.eclipse.viatra.solver.data.map;
2
3import java.util.Iterator;
4import java.util.Map;
5
6import org.eclipse.viatra.solver.data.map.internal.MutableNode;
7import org.eclipse.viatra.solver.data.map.internal.Node;
8import org.eclipse.viatra.solver.data.map.internal.NodeIterator;
9
10public class VersionedMap<KEY,VALUE> implements Versioned{
11
12 protected final ContinousHashProvider<? super KEY> hashProvider;
13 protected final VALUE defaultValue;
14 protected Node<KEY,VALUE> root = null;
15
16 protected VersionedMap(ContinousHashProvider<? super KEY> hashProvider, VALUE defaultValue) {
17 this.hashProvider = hashProvider;
18 this.defaultValue = defaultValue;
19 }
20
21 public VALUE getDefaultValue() {
22 return defaultValue;
23 }
24 public ContinousHashProvider<? super KEY> getHashProvider() {
25 return hashProvider;
26 }
27
28 public void put(KEY key, VALUE value) {
29 if(root!=null) {
30 root = root.putValue(key, value, hashProvider, defaultValue, hashProvider.getHash(key, 0), 0);
31 } else {
32 root = MutableNode.initialize(key, value, hashProvider, defaultValue);
33 }
34 }
35 public VALUE get(KEY key) {
36 if(root!=null) {
37 return root.getValue(key, hashProvider, defaultValue, hashProvider.getHash(key, 0), 0);
38 } else {
39 return defaultValue;
40 }
41 }
42 public int getSize() {
43 if(root == null) {
44 return 0;
45 } else {
46 return root.getSize();
47 }
48 }
49 Iterator<Map.Entry<KEY,VALUE>> getIterator() {
50 return new NodeIterator<KEY, VALUE>(this.root);
51 }
52
53 @Override
54 public long commit() {
55 // TODO Auto-generated method stub
56 return 0;
57 }
58
59 @Override
60 public void restore(long state) {
61 // TODO Auto-generated method stub
62 }
63}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/ImmutableNode.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/ImmutableNode.java
new file mode 100644
index 00000000..e2bc06a9
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/ImmutableNode.java
@@ -0,0 +1,215 @@
1package org.eclipse.viatra.solver.data.map.internal;
2
3import org.eclipse.viatra.solver.data.map.ContinousHashProvider;
4
5public class ImmutableNode<KEY, VALUE> extends Node<KEY, VALUE> {
6 /**
7 * Bitmap defining the stored key and values.
8 */
9 int dataMap;
10 /**
11 * Bitmap defining the positions of further nodes.
12 */
13 int nodeMap;
14 /**
15 * Stores Keys, Values, and subnodes. Structure: (KEY,VALUE)*,NODE; NODES are stored backwards.
16 */
17 Object[] content;
18
19 /**
20 * Constructor with given content
21 */
22 protected ImmutableNode(int dataMap, int nodeMap, Object[] content) {
23 this.dataMap = dataMap;
24 this.nodeMap = nodeMap;
25 this.content = content;
26 }
27
28 /**
29 * Constructor that copies a mutable node to an immutable.
30 * @param node
31 */
32 @SuppressWarnings("unchecked")
33 protected ImmutableNode(MutableNode<KEY,VALUE> node) {
34 int size = 0;
35 for(int i = 0; i<factor; i++) {
36 if(node.content[i]!=null) {
37 size++;
38 }
39 }
40
41 int datas = 0;
42 int nodes = 0;
43 this.dataMap = 0;
44 this.nodeMap = 0;
45 this.content = new Object[size];
46 int bitposition = 1;
47 for(int i = 0; i<factor; i++) {
48 Object key = node.content[i*2];
49 if(key != null) {
50 dataMap |= bitposition;
51 content[datas*2] = key;
52 content[datas*2+1] = node.content[i*2+1];
53 datas++;
54 } else {
55 Node<KEY,VALUE> subnode = (Node<KEY, VALUE>) node.content[i*2+1];
56 if(subnode != null) {
57 ImmutableNode<KEY, VALUE> immutableSubnode = subnode.toImmutable();
58 nodeMap |=bitposition;
59 content[size-1-nodes] = immutableSubnode;
60 nodes++;
61 }
62 }
63 bitposition<<=1;
64 }
65 }
66
67 private int index(int bitmap, int bitpos) {
68 return Integer.bitCount(bitmap & (bitpos-1));
69 }
70
71 @SuppressWarnings("unchecked")
72 @Override
73 public VALUE getValue(KEY key, ContinousHashProvider<? super KEY> hashProvider, VALUE defaultValue, int hash, int depth) {
74 int selectedHashFragment = hashFragment(hash,shiftDepth(depth));
75 int bitposition = 1 << selectedHashFragment;
76 // If the key is stored as a data
77 if((dataMap & bitposition) != 0) {
78 int keyIndex = 2*index(dataMap, bitposition);
79 KEY keyCandidate = (KEY) content[keyIndex];
80 if(hashProvider.equals(keyCandidate, key)) {
81 return (VALUE) content[keyIndex+1];
82 } else {
83 return defaultValue;
84 }
85 }
86 // the key is stored as a node
87 else if((nodeMap & bitposition) != 0) {
88 int keyIndex = content.length-1-index(nodeMap, bitposition);
89 ImmutableNode<KEY,VALUE> subNode = (ImmutableNode<KEY,VALUE>) content[keyIndex];
90 int newHash = depth%numberOfFactors == 0?
91 hashProvider.getHash(key, hashDepth(depth)) :
92 hash;
93 int newDepth = depth+1;
94 return subNode.getValue(key, hashProvider, defaultValue, newHash, newDepth);
95 }
96 // the key is not stored at all
97 else {
98 return defaultValue;
99 }
100 }
101
102 @SuppressWarnings("unchecked")
103 @Override
104 public Node<KEY,VALUE> putValue(KEY key, VALUE value, ContinousHashProvider<? super KEY> hashProvider, VALUE defaultValue, int hash, int depth) {
105 int selectedHashFragment = hashFragment(hash,shiftDepth(depth));
106 int bitposition = 1 << selectedHashFragment;
107 if((dataMap & bitposition) != 0) {
108 int keyIndex = 2*index(dataMap, bitposition);
109 KEY keyCandidate = (KEY) content[keyIndex];
110 if(hashProvider.equals(keyCandidate, key)) {
111 if(value == defaultValue) {
112 // delete
113 MutableNode<KEY, VALUE> mutable = this.toMutable();
114 mutable.removeEntry(selectedHashFragment);
115 return mutable;
116 } else if(value == content[keyIndex+1]) {
117 // dont change
118 return this;
119 } else {
120 // update existing value
121 MutableNode<KEY, VALUE> mutable = this.toMutable();
122 mutable.updateValue(value, selectedHashFragment);
123 return mutable;
124 }
125 } else {
126 if(value == defaultValue) {
127 // dont change
128 return this;
129 } else {
130 // add new key + value
131 MutableNode<KEY, VALUE> mutable = this.toMutable();
132 mutable.putValue(key, value, hashProvider, defaultValue, selectedHashFragment, depth);
133 return mutable;
134 }
135 }
136 } else if((nodeMap & bitposition)!=0) {
137
138 int keyIndex = content.length-1-index(dataMap, bitposition);
139 ImmutableNode<KEY,VALUE> subNode = (ImmutableNode<KEY,VALUE>) content[keyIndex];
140 int newHash = newHash(hashProvider, key, selectedHashFragment, depth);
141 int newDepth = depth+1;
142 Node<KEY,VALUE> newsubNode = subNode.putValue(key, value, hashProvider, defaultValue, newHash, newDepth);
143
144 if(subNode == newsubNode) {
145 // nothing changed
146 return this;
147 } else {
148 MutableNode<KEY, VALUE> result = toMutable();
149 result.updateSubNode(selectedHashFragment, newsubNode);
150 return result;
151 }
152 } else {
153 // add new key + value
154 MutableNode<KEY, VALUE> mutable = this.toMutable();
155 mutable.putValue(key, value, hashProvider, defaultValue, selectedHashFragment, depth);
156 return mutable;
157 }
158 }
159
160
161 @Override
162 public int getSize() {
163 throw new UnsupportedOperationException();
164 }
165
166 @Override
167 protected MutableNode<KEY,VALUE> toMutable() {
168 return new MutableNode<KEY,VALUE>(this);
169 }
170
171 @Override
172 protected ImmutableNode<KEY,VALUE> toImmutable() {
173 return this;
174 }
175
176 @Override
177 protected void prettyPrint(StringBuilder builder, int depth, int code) {
178 for(int i = 0; i<depth; i++) {
179 builder.append("\t");
180 }
181 if(code>=0) {
182 builder.append(code);
183 builder.append(":");
184 }
185 builder.append("Immutable(");
186 boolean hadContent = false;
187 int dataMask = 1;
188 for(int i = 0; i<factor; i++) {
189 if((dataMask & dataMap) != 0) {
190 if(hadContent) {
191 builder.append(",");
192 }
193 builder.append(i);
194 builder.append(":[");
195 builder.append(content[2*index(dataMap, dataMask)].toString());
196 builder.append("]->[");
197 builder.append(content[2*index(dataMap, dataMask)+1].toString());
198 builder.append("]");
199 hadContent = true;
200 }
201 dataMask<<=1;
202 }
203 builder.append(")");
204 int nodeMask = 1;
205 for(int i = 0; i<factor; i++) {
206 if((nodeMask & nodeMap)!=0) {
207 @SuppressWarnings("unchecked")
208 Node<KEY,VALUE> subNode = (Node<KEY, VALUE>) content[content.length-1-index(nodeMap, nodeMask)];
209 builder.append("\n");
210 subNode.prettyPrint(builder, depth+1, i);
211 }
212 nodeMask<<=1;
213 }
214 }
215}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/ImmutableNodeIterator.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/ImmutableNodeIterator.java
new file mode 100644
index 00000000..7715bc72
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/ImmutableNodeIterator.java
@@ -0,0 +1,5 @@
1package org.eclipse.viatra.solver.data.map.internal;
2
3public class ImmutableNodeIterator {
4
5}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/MutableNode.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/MutableNode.java
new file mode 100644
index 00000000..f6d0323e
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/MutableNode.java
@@ -0,0 +1,241 @@
1package org.eclipse.viatra.solver.data.map.internal;
2
3import org.eclipse.viatra.solver.data.map.ContinousHashProvider;
4
5public class MutableNode<KEY,VALUE> extends Node<KEY,VALUE> {
6 Object[] content;
7 protected MutableNode() {
8 this.content = new Object[2*factor];
9 }
10 public static <KEY,VALUE> MutableNode<KEY,VALUE> initialize(
11 KEY key, VALUE value,
12 ContinousHashProvider<? super KEY> hashProvider,
13 VALUE defaultValue)
14 {
15 if(value == defaultValue) {
16 return null;
17 } else {
18 int hash = hashProvider.getHash(key, 0);
19 int fragment = hashFragment(hash, 0);
20 MutableNode<KEY, VALUE> res = new MutableNode<KEY, VALUE>();
21 res.content[2*fragment] = key;
22 res.content[2*fragment+1] = value;
23 return res;
24 }
25 }
26
27 protected MutableNode(ImmutableNode<KEY,VALUE> node) {
28 this.content = new Object[2*factor];
29 int dataUsed=0;
30 int nodeUsed=0;
31 for(int i=0; i<factor; i++) {
32 int bitposition = 1 << i;
33 if((node.dataMap & bitposition) != 0) {
34 content[2*i] = this.content[dataUsed*2];
35 content[2*i+1] = this.content[dataUsed*2+1];
36 dataUsed++;
37 } else if((node.nodeMap & bitposition) != 0) {
38 content[2*i+1] = this.content[this.content.length-1-nodeUsed];
39 nodeUsed++;
40 }
41 }
42 }
43
44 @SuppressWarnings("unchecked")
45 @Override
46 public VALUE getValue(KEY key, ContinousHashProvider<? super KEY> hashProvider, VALUE defaultValue, int hash, int depth) {
47 int selectedHashFragment = hashFragment(hash,shiftDepth(depth));
48 KEY keyCandidate = (KEY) content[2*selectedHashFragment];
49 if(keyCandidate != null) {
50 if(hashProvider.equals(keyCandidate, key)) {
51 return (VALUE) content[2*selectedHashFragment+1];
52 } else {
53 return defaultValue;
54 }
55 } else {
56 Node<KEY,VALUE> nodeCandidate = (Node<KEY,VALUE>) content[2*selectedHashFragment+1];
57 if(nodeCandidate != null) {
58 int newHash = newHash(hashProvider, key, hash, depth);
59 int newDepth = depth+1;
60 return (VALUE) nodeCandidate.getValue(key, hashProvider, defaultValue, newHash, newDepth);
61 } else {
62 return defaultValue;
63 }
64 }
65 }
66
67 private boolean hasContent() {
68 for(Object element : this.content) {
69 if(element != null) return true;
70 }
71 return false;
72 }
73
74 private MutableNode<KEY,VALUE> createNewNode(
75 ContinousHashProvider<? super KEY> hashProvider,
76 KEY key1, VALUE value1, int oldHash1,
77 KEY key2, VALUE value2, int oldHash2,
78 int newdepth)
79 {
80 int newHash1 = newHash(hashProvider, key1, oldHash1, newdepth);
81 int newHash2 = newHash(hashProvider, key2, oldHash2, newdepth);
82 int newFragment1 = hashFragment(newHash1, newdepth);
83 int newFragment2 = hashFragment(newHash2, newdepth);
84
85 MutableNode<KEY,VALUE> subNode = new MutableNode<KEY,VALUE>();
86 if(newFragment1 != newFragment2) {
87 subNode.content[newFragment1*2]=key1;
88 subNode.content[newFragment1*2+1]=value1;
89
90 subNode.content[newFragment2*2]=key2;
91 subNode.content[newFragment2*2+1]=value2;
92 return subNode;
93 } else {
94 MutableNode<KEY,VALUE> subSubNode = createNewNode(
95 hashProvider,
96 key1, value1, newHash1,
97 key2, value2, newHash2,
98 newdepth+1);
99 subNode.content[newFragment1*2+1] = subSubNode;
100 return subNode;
101 }
102 }
103
104 @SuppressWarnings("unchecked")
105 @Override
106 public Node<KEY,VALUE> putValue(KEY key, VALUE value, ContinousHashProvider<? super KEY> hashProvider, VALUE defaultValue, int hash, int depth) {
107 int selectedHashFragment = hashFragment(hash,shiftDepth(depth));
108 KEY keyCandidate = (KEY) content[2*selectedHashFragment];
109 if(keyCandidate != null) {
110 if(hashProvider.equals(keyCandidate,key)) {
111 // Update entry
112 if(value == defaultValue) {
113 return removeEntry(selectedHashFragment);
114 } else {
115 return updateValue(value, selectedHashFragment);
116 }
117 } else {
118 if(value == defaultValue) {
119 // dont need to add new node
120 return this;
121 } else {
122 // Split entry: data -> node
123 return moveDown(key, value, hashProvider, hash, depth, selectedHashFragment, keyCandidate);
124 }
125 }
126 } else {
127 Node<KEY,VALUE> nodeCandidate = (Node<KEY,VALUE>) content[2*selectedHashFragment+1];
128 if(nodeCandidate != null) {
129 Node<KEY, VALUE> newNode = nodeCandidate.putValue(key, value, hashProvider, defaultValue, newHash(hashProvider, key, hash, depth+1), depth+1);
130 return updateSubNode(selectedHashFragment,newNode);
131 } else {
132 content[2*selectedHashFragment] = key;
133 return updateValue(value, selectedHashFragment);
134 }
135 }
136 }
137
138 Node<KEY, VALUE> updateSubNode(int selectedHashFragment, Node<KEY, VALUE> newNode) {
139 content[2*selectedHashFragment+1] = newNode;
140 for(int i = 0; i<this.content.length; i++) {
141 if(content[i]!=null) return this;
142 }
143 return null;
144 }
145
146 @SuppressWarnings("unchecked")
147 Node<KEY, VALUE> moveDown(
148 KEY key, VALUE value,
149 ContinousHashProvider<? super KEY> hashProvider, int hash,
150 int depth, int selectedHashFragment, KEY keyCandidate) {
151 KEY previousKey = keyCandidate;
152 VALUE previousValue = (VALUE) content[2*selectedHashFragment+1];
153
154 MutableNode<KEY,VALUE> subNode = createNewNode(
155 hashProvider,
156 previousKey, previousValue, hashProvider.getHash(previousKey, hashDepth(depth)),
157 key, value, hash,
158 depth+1);
159
160 content[2*selectedHashFragment] = null;
161 content[2*selectedHashFragment+1] = subNode;
162 return this;
163 }
164
165 Node<KEY, VALUE> updateValue(VALUE value, int selectedHashFragment) {
166 content[2*selectedHashFragment+1] = value;
167 return this;
168 }
169 Node<KEY, VALUE> removeEntry(int selectedHashFragment) {
170 content[2*selectedHashFragment] = null;
171 content[2*selectedHashFragment+1] = null;
172 if(hasContent()) {
173 return this;
174 } else {
175 return null;
176 }
177 }
178
179 @SuppressWarnings("unchecked")
180 @Override
181 public int getSize() {
182 int size = 0;
183 for(int i=0; i<factor; i++) {
184 if(content[i*2]!=null) {
185 size++;
186 } else{
187 Node<KEY,VALUE> nodeCandidate = (Node<KEY, VALUE>) content[i*2+1];
188 if(nodeCandidate!=null) {
189 size+=nodeCandidate.getSize();
190 }
191 }
192 }
193 return size;
194 }
195
196 @Override
197 protected MutableNode<KEY,VALUE> toMutable() {
198 return this;
199 }
200
201 @Override
202 protected ImmutableNode<KEY,VALUE> toImmutable() {
203 return new ImmutableNode<KEY,VALUE>(this);
204 }
205
206 @Override
207 protected void prettyPrint(StringBuilder builder, int depth, int code) {
208 for(int i = 0; i<depth; i++) {
209 builder.append("\t");
210 }
211 if(code>=0) {
212 builder.append(code);
213 builder.append(":");
214 }
215 builder.append("Mutable(");
216 boolean hadContent = false;
217 for(int i = 0; i<factor; i++) {
218 if(content[2*i] != null) {
219 if(hadContent) {
220 builder.append(",");
221 }
222 builder.append(i);
223 builder.append(":[");
224 builder.append(content[2*i].toString());
225 builder.append("]->[");
226 builder.append(content[2*i+1].toString());
227 builder.append("]");
228 hadContent = true;
229 }
230 }
231 builder.append(")");
232 for(int i = 0; i<factor; i++) {
233 if(content[2*i] == null || content[2*i+1]!=null) {
234 @SuppressWarnings("unchecked")
235 Node<KEY,VALUE> subNode = (Node<KEY, VALUE>) content[2*i+1];
236 builder.append("\n");
237 subNode.prettyPrint(builder, depth+1, i);
238 }
239 }
240 }
241}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/MutableNodeIterator.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/MutableNodeIterator.java
new file mode 100644
index 00000000..619eb3b2
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/MutableNodeIterator.java
@@ -0,0 +1,29 @@
1package org.eclipse.viatra.solver.data.map.internal;
2
3import java.util.Map.Entry;
4
5public class MutableNodeIterator<KEY,VALUE> extends NodeIterator<MutableNode<KEY,VALUE>,KEY, VALUE>{
6
7 public MutableNodeIterator(MutableNode<KEY, VALUE> node) {
8 super(node);
9 }
10
11 /**
12 * Index of the last result value;
13 */
14 int index = -1;
15 NodeIterator<KEY,VALUE> actualSubNode = null;
16
17 @Override
18 public boolean hasNext() {
19 for(int i = index; i<node.factor; i++) {
20
21 }
22 return false;
23 }
24 @Override
25 public Entry<KEY, VALUE> next() {
26 // TODO Auto-generated method stub
27 return null;
28 }
29}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/Node.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/Node.java
new file mode 100644
index 00000000..89c52f7f
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/Node.java
@@ -0,0 +1,69 @@
1package org.eclipse.viatra.solver.data.map.internal;
2
3import org.eclipse.viatra.solver.data.map.ContinousHashProvider;
4
5public abstract class Node<KEY,VALUE>{
6 protected static final int branchingFactorBit = 5;
7 protected static final int factor = 1<<branchingFactorBit;
8 protected static final int numberOfFactors = Integer.SIZE / branchingFactorBit;
9 protected static final int factorMask = factor-1;
10
11 /**
12 * Calculates the index for the continuous hash.
13 * @param depth The depth of the node in the tree.
14 * @return The index of the continuous hash.
15 */
16 protected static int hashDepth(int depth) {
17 return depth/numberOfFactors;
18 }
19
20 /**
21 * Calculates the which segment of a single hash should be used.
22 * @param depth The depth of the node in the tree.
23 * @return The segment of a hash code.
24 */
25 protected static int shiftDepth(int depth) {
26 return depth%numberOfFactors;
27 }
28 /**
29 * Selects a segments from a complete hash for a given depth.
30 * @param hash A complete hash.
31 * @param shiftDepth The index of the segment.
32 * @return The segment as an integer.
33 */
34 protected static int hashFragment(int hash, int shiftDepth) {
35 return (hash >>> shiftDepth*branchingFactorBit) & factorMask;
36 }
37 /**
38 * Returns the hash code for a given depth. It may calculate new hash code, or reuse a hash code calculated for depth-1.
39 * @param key The key.
40 * @param hash Hash code for depth-1
41 * @param depth The depth.
42 * @return The new hash code.
43 */
44 protected int newHash(final ContinousHashProvider<? super KEY> hashProvider, KEY key, int hash, int depth) {
45 return depth%numberOfFactors == 0?
46 hashProvider.getHash(key, hashDepth(depth)) :
47 hash;
48 }
49
50
51 abstract public VALUE getValue(KEY key, ContinousHashProvider<? super KEY> hashProvider, VALUE defaultValue, int hash, int depth);
52 abstract public Node<KEY,VALUE> putValue(KEY key, VALUE value, ContinousHashProvider<? super KEY> hashProvider, VALUE defaultValue, int hash, int depth);
53 abstract public int getSize();
54
55 abstract protected MutableNode<KEY, VALUE> toMutable();
56 abstract protected ImmutableNode<KEY, VALUE> toImmutable();
57
58 ///////// For iterators
59 //abstract boolean moveIteratorToNextData(NodeIterator<KEY,VALUE> iterator, int currentIndex);
60 //abstract boolean moveIteratorToNextNode(NodeIterator<KEY,VALUE> iterator, int currentIndex);
61 ///////// FOR printing
62 abstract protected void prettyPrint(StringBuilder builder, int depth, int code);
63 @Override
64 public String toString() {
65 StringBuilder stringBuilder = new StringBuilder();
66 prettyPrint(stringBuilder, 0, -1);
67 return stringBuilder.toString();
68 }
69}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/NodeIterator.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/NodeIterator.java
new file mode 100644
index 00000000..4c426b1e
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/src/org/eclipse/viatra/solver/data/map/internal/NodeIterator.java
@@ -0,0 +1,13 @@
1package org.eclipse.viatra.solver.data.map.internal;
2
3import java.util.Iterator;
4import java.util.Map;
5
6public abstract class NodeIterator<NODETYPE extends Node<KEY,VALUE>,KEY,VALUE>
7 implements Iterator<Map.Entry<KEY,VALUE>>
8{
9 protected NODETYPE node;
10 public NodeIterator(NODETYPE node) {
11 this.node = node;
12 }
13}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/tests/org/eclipse/viatra/solver/data/map/MapSmokeTest.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/tests/org/eclipse/viatra/solver/data/map/MapSmokeTest.java
new file mode 100644
index 00000000..e1a7a39b
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/tests/org/eclipse/viatra/solver/data/map/MapSmokeTest.java
@@ -0,0 +1,82 @@
1package org.eclipse.viatra.solver.data.map;
2
3import java.util.Random;
4
5import org.junit.jupiter.api.Test;
6
7public class MapSmokeTest {
8
9 private void runTest(int seed, int steps, int maxKey, int maxValue) {
10 String[] values = new String[maxValue];
11 for(int i = 0; i<values.length; i++) {
12 values[i] = "VALUE-"+i;
13 }
14 ContinousHashProvider<Integer> chp = new ContinousHashProvider<Integer>() {
15
16 @Override
17 public int getHash(Integer key, int index) {
18 int result = 1;
19 final int prime = 31;
20 result = prime*result + key;
21 result = prime*result + index;
22 return result;
23 }
24
25 @Override
26 public boolean equals(Integer key1, Integer key2) {
27 return key1.equals(key2);
28 }
29 };
30
31 VersionedMap<Integer, String> sut = new VersionedMap<Integer, String>(chp, values[0]);
32 MapTestEnvironment<Integer, String> e = new MapTestEnvironment<Integer, String>(sut);
33
34 Random r = new Random(seed);
35
36 iterativeCall(steps, maxKey, maxValue, values, e, r);
37 }
38
39 void recursiveCall(
40 int steps,
41 int maxKey,
42 int maxValue,
43 String[] values,
44 MapTestEnvironment<Integer, String> e,
45 Random r)
46 {
47 if(steps<=0) {
48 return;
49 } else {
50 e.put(r.nextInt(maxKey), values[r.nextInt(maxValue)]);
51 e.checkEquivalence();
52
53 recursiveCall(steps-1, maxKey, maxValue, values, e, r);
54 }
55 }
56
57 void iterativeCall(int steps,
58 int maxKey,
59 int maxValue,
60 String[] values,
61 MapTestEnvironment<Integer, String> e,
62 Random r)
63 {
64 for(int i=0; i<steps; i++) {
65 e.put(r.nextInt(maxKey), values[r.nextInt(maxValue)]);
66 e.checkEquivalence();
67 }
68 }
69
70 @Test
71 void runTest1() {
72 runTest(0, 100000, 3, 2);
73 }
74 @Test
75 void runTest2() {
76 runTest(1, 100000, 3, 2);
77 }
78 @Test
79 void runTest3() {
80 runTest(1, 32*32*32*32, 32*32-1, 2);
81 }
82}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/tests/org/eclipse/viatra/solver/data/map/MapTestEnvironment.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/tests/org/eclipse/viatra/solver/data/map/MapTestEnvironment.java
new file mode 100644
index 00000000..5e9b2e5f
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/tests/org/eclipse/viatra/solver/data/map/MapTestEnvironment.java
@@ -0,0 +1,41 @@
1package org.eclipse.viatra.solver.data.map;
2
3import static org.junit.Assert.fail;
4import static org.junit.jupiter.api.Assertions.assertEquals;
5
6import java.util.HashMap;
7import java.util.Map;
8import java.util.Map.Entry;
9
10import junit.framework.AssertionFailedError;
11
12public class MapTestEnvironment<KEY,VALUE> {
13 VersionedMap<KEY, VALUE> sut;
14 Map<KEY,VALUE> oracle = new HashMap<KEY, VALUE>();
15
16 public MapTestEnvironment(VersionedMap<KEY, VALUE> sut) {
17 this.sut = sut;
18 }
19
20 public void put(KEY key, VALUE value) {
21 sut.put(key, value);
22 oracle.put(key, value);
23 }
24
25 public void checkEquivalence() {
26 int nonDefault = 0;
27 for(Entry<KEY, VALUE> entry : oracle.entrySet()) {
28 VALUE sutAnswer = sut.get(entry.getKey());
29 VALUE oracleAnswer1 = entry.getValue();
30 VALUE oracleAnswer2 = (oracleAnswer1 == null)?sut.getDefaultValue():oracleAnswer1;
31 if(sutAnswer!=oracleAnswer2) {
32 fail("Non-equivalent gets: " + sutAnswer + " != " + oracleAnswer2 + "<-[oracle]") ;
33 }
34 if(entry.getValue() != sut.getDefaultValue()) {
35 nonDefault++;
36 }
37 }
38 int sutNonDefault = sut.getSize();
39 assertEquals(sutNonDefault, nonDefault);
40 }
41}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/tests/org/eclipse/viatra/solver/data/map/MapTests.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/tests/org/eclipse/viatra/solver/data/map/MapTests.java
new file mode 100644
index 00000000..28a49380
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.solver.data/tests/org/eclipse/viatra/solver/data/map/MapTests.java
@@ -0,0 +1,5 @@
1package org.eclipse.viatra.solver.data.map;
2
3public class MapTests {
4
5}