aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-12-13 03:21:58 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-12-13 12:25:02 +0100
commit6ccc179ea305fc27ae121253b1d1f172bad676fd (patch)
tree8c5bb8dd7bf45157cabb57b19d17ce9af11aca5f
parentchore(deps): upgrade to yarn canary (diff)
downloadrefinery-6ccc179ea305fc27ae121253b1d1f172bad676fd.tar.gz
refinery-6ccc179ea305fc27ae121253b1d1f172bad676fd.tar.zst
refinery-6ccc179ea305fc27ae121253b1d1f172bad676fd.zip
refactor(store): simplify return types
Prefers sealed non-generic interfaces over wildcard types to avoid confusion about method return types, especially in collections (see SonarQube rule java:S1452).
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeCursor.java14
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraQueryableModelStore.java28
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/RelationalScope.java7
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraQueryableModel.java8
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java28
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java15
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RelationViewWrapper.java6
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ModelUpdateListener.java21
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateTranslator.java5
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/AnyVersionedMap.java5
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/Cursor.java29
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/VersionedMap.java20
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreConfiguration.java20
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreImpl.java22
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/internal/MapCursor.java88
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/internal/MapDiffCursor.java23
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/internal/VersionedMapImpl.java103
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/Model.java28
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/ModelDiffCursor.java21
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java15
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java41
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java41
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/internal/SimilarRelationEquivalenceClass.java12
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyAuxiliaryData.java4
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyDataRepresentation.java9
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyRelation.java9
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/representation/AuxiliaryData.java2
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/representation/DataRepresentation.java5
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java3
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java10
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/Modality.java8
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/RelationViewAtom.java8
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/AnyRelationView.java13
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java15
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java16
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java29
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/ContentEqualsFuzzTest.java52
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/utils/MapTestEnvironment.java38
38 files changed, 437 insertions, 384 deletions
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeCursor.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeCursor.java
index 727a9528..a1fdc73d 100644
--- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeCursor.java
+++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeCursor.java
@@ -1,13 +1,11 @@
1package tools.refinery.language.semantics.model.internal; 1package tools.refinery.language.semantics.model.internal;
2 2
3import tools.refinery.store.map.Cursor; 3import tools.refinery.store.map.Cursor;
4import tools.refinery.store.map.VersionedMap;
5import tools.refinery.store.tuple.Tuple;
6import tools.refinery.store.model.representation.TruthValue; 4import tools.refinery.store.model.representation.TruthValue;
5import tools.refinery.store.tuple.Tuple;
7 6
8import java.util.ArrayDeque; 7import java.util.ArrayDeque;
9import java.util.Deque; 8import java.util.Deque;
10import java.util.List;
11 9
12class DecisionTreeCursor implements Cursor<Tuple, TruthValue> { 10class DecisionTreeCursor implements Cursor<Tuple, TruthValue> {
13 static final int STATE_FINISH = Integer.MAX_VALUE; 11 static final int STATE_FINISH = Integer.MAX_VALUE;
@@ -81,14 +79,4 @@ class DecisionTreeCursor implements Cursor<Tuple, TruthValue> {
81 key = Tuple.of(rawTuple); 79 key = Tuple.of(rawTuple);
82 return true; 80 return true;
83 } 81 }
84
85 @Override
86 public boolean isDirty() {
87 return false;
88 }
89
90 @Override
91 public List<VersionedMap<?, ?>> getDependingMaps() {
92 return List.of();
93 }
94} 82}
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraQueryableModelStore.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraQueryableModelStore.java
index 37cd91a6..94d2db4f 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraQueryableModelStore.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraQueryableModelStore.java
@@ -5,13 +5,17 @@ import tools.refinery.store.model.ModelDiffCursor;
5import tools.refinery.store.model.ModelStore; 5import tools.refinery.store.model.ModelStore;
6import tools.refinery.store.model.ModelStoreImpl; 6import tools.refinery.store.model.ModelStoreImpl;
7import tools.refinery.store.model.RelationLike; 7import tools.refinery.store.model.RelationLike;
8import tools.refinery.store.model.representation.AnyDataRepresentation;
8import tools.refinery.store.model.representation.DataRepresentation; 9import tools.refinery.store.model.representation.DataRepresentation;
9import tools.refinery.store.query.*; 10import tools.refinery.store.query.DNF;
11import tools.refinery.store.query.DNFAnd;
12import tools.refinery.store.query.QueryableModel;
13import tools.refinery.store.query.QueryableModelStore;
10import tools.refinery.store.query.atom.*; 14import tools.refinery.store.query.atom.*;
11import tools.refinery.store.query.viatra.internal.RawPatternMatcher; 15import tools.refinery.store.query.viatra.internal.RawPatternMatcher;
12import tools.refinery.store.query.viatra.internal.ViatraQueryableModel; 16import tools.refinery.store.query.viatra.internal.ViatraQueryableModel;
13import tools.refinery.store.query.viatra.internal.pquery.DNF2PQuery; 17import tools.refinery.store.query.viatra.internal.pquery.DNF2PQuery;
14import tools.refinery.store.query.view.RelationView; 18import tools.refinery.store.query.view.AnyRelationView;
15 19
16import java.util.Collections; 20import java.util.Collections;
17import java.util.HashMap; 21import java.util.HashMap;
@@ -21,11 +25,11 @@ import java.util.Set;
21public class ViatraQueryableModelStore implements QueryableModelStore { 25public class ViatraQueryableModelStore implements QueryableModelStore {
22 protected final ModelStore store; 26 protected final ModelStore store;
23 27
24 protected final Set<RelationView<?>> relationViews; 28 protected final Set<AnyRelationView> relationViews;
25 29
26 protected final Map<DNF, GenericQuerySpecification<RawPatternMatcher>> predicates; 30 protected final Map<DNF, GenericQuerySpecification<RawPatternMatcher>> predicates;
27 31
28 public ViatraQueryableModelStore(ModelStore store, Set<RelationView<?>> relationViews, 32 public ViatraQueryableModelStore(ModelStore store, Set<AnyRelationView> relationViews,
29 Set<DNF> predicates) { 33 Set<DNF> predicates) {
30 this.store = store; 34 this.store = store;
31 validateViews(store.getDataRepresentations(), relationViews); 35 validateViews(store.getDataRepresentations(), relationViews);
@@ -34,13 +38,13 @@ public class ViatraQueryableModelStore implements QueryableModelStore {
34 this.predicates = initPredicates(predicates); 38 this.predicates = initPredicates(predicates);
35 } 39 }
36 40
37 public ViatraQueryableModelStore(Set<DataRepresentation<?, ?>> dataRepresentations, 41 public ViatraQueryableModelStore(Set<AnyDataRepresentation> dataRepresentations,
38 Set<RelationView<?>> relationViews, Set<DNF> predicates) { 42 Set<AnyRelationView> relationViews, Set<DNF> predicates) {
39 this(new ModelStoreImpl(dataRepresentations), relationViews, predicates); 43 this(new ModelStoreImpl(dataRepresentations), relationViews, predicates);
40 } 44 }
41 45
42 private void validateViews(Set<DataRepresentation<?, ?>> dataRepresentations, Set<RelationView<?>> relationViews) { 46 private void validateViews(Set<AnyDataRepresentation> dataRepresentations, Set<AnyRelationView> relationViews) {
43 for (RelationView<?> relationView : relationViews) { 47 for (var relationView : relationViews) {
44 if (!dataRepresentations.contains(relationView.getRepresentation())) { 48 if (!dataRepresentations.contains(relationView.getRepresentation())) {
45 throw new IllegalArgumentException("%s %s added to %s without a referred representation.".formatted( 49 throw new IllegalArgumentException("%s %s added to %s without a referred representation.".formatted(
46 DataRepresentation.class.getSimpleName(), relationView.getName(), 50 DataRepresentation.class.getSimpleName(), relationView.getName(),
@@ -49,7 +53,7 @@ public class ViatraQueryableModelStore implements QueryableModelStore {
49 } 53 }
50 } 54 }
51 55
52 private void validatePredicates(Set<RelationView<?>> relationViews, Set<DNF> predicates) { 56 private void validatePredicates(Set<AnyRelationView> relationViews, Set<DNF> predicates) {
53 for (DNF dnfPredicate : predicates) { 57 for (DNF dnfPredicate : predicates) {
54 for (DNFAnd clause : dnfPredicate.getClauses()) { 58 for (DNFAnd clause : dnfPredicate.getClauses()) {
55 for (DNFAtom atom : clause.constraints()) { 59 for (DNFAtom atom : clause.constraints()) {
@@ -65,7 +69,7 @@ public class ViatraQueryableModelStore implements QueryableModelStore {
65 } 69 }
66 } 70 }
67 71
68 private void validateRelationAtom(Set<RelationView<?>> relationViews, DNF dnfPredicate, 72 private void validateRelationAtom(Set<AnyRelationView> relationViews, DNF dnfPredicate,
69 RelationViewAtom relationViewAtom) { 73 RelationViewAtom relationViewAtom) {
70 if (!relationViews.contains(relationViewAtom.getTarget())) { 74 if (!relationViews.contains(relationViewAtom.getTarget())) {
71 throw new IllegalArgumentException( 75 throw new IllegalArgumentException(
@@ -100,12 +104,12 @@ public class ViatraQueryableModelStore implements QueryableModelStore {
100 } 104 }
101 105
102 @Override 106 @Override
103 public Set<DataRepresentation<?, ?>> getDataRepresentations() { 107 public Set<AnyDataRepresentation> getDataRepresentations() {
104 return store.getDataRepresentations(); 108 return store.getDataRepresentations();
105 } 109 }
106 110
107 @Override 111 @Override
108 public Set<RelationView<?>> getViews() { 112 public Set<AnyRelationView> getViews() {
109 return this.relationViews; 113 return this.relationViews;
110 } 114 }
111 115
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/RelationalScope.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/RelationalScope.java
index 5ddad67d..133c4c72 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/RelationalScope.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/RelationalScope.java
@@ -6,19 +6,20 @@ import org.eclipse.viatra.query.runtime.api.scope.IEngineContext;
6import org.eclipse.viatra.query.runtime.api.scope.IIndexingErrorListener; 6import org.eclipse.viatra.query.runtime.api.scope.IIndexingErrorListener;
7import org.eclipse.viatra.query.runtime.api.scope.QueryScope; 7import org.eclipse.viatra.query.runtime.api.scope.QueryScope;
8import tools.refinery.store.model.Model; 8import tools.refinery.store.model.Model;
9import tools.refinery.store.tuple.Tuple;
10import tools.refinery.store.model.representation.Relation; 9import tools.refinery.store.model.representation.Relation;
11import tools.refinery.store.query.viatra.internal.context.RelationalEngineContext; 10import tools.refinery.store.query.viatra.internal.context.RelationalEngineContext;
12import tools.refinery.store.query.viatra.internal.viewupdate.ModelUpdateListener; 11import tools.refinery.store.query.viatra.internal.viewupdate.ModelUpdateListener;
13import tools.refinery.store.query.view.RelationView; 12import tools.refinery.store.query.view.AnyRelationView;
13import tools.refinery.store.tuple.Tuple;
14 14
15import java.util.Set; 15import java.util.Set;
16 16
17public class RelationalScope extends QueryScope { 17public class RelationalScope extends QueryScope {
18 private final Model model; 18 private final Model model;
19
19 private final ModelUpdateListener updateListener; 20 private final ModelUpdateListener updateListener;
20 21
21 public RelationalScope(Model model, Set<RelationView<?>> relationViews) { 22 public RelationalScope(Model model, Set<AnyRelationView> relationViews) {
22 this.model = model; 23 this.model = model;
23 this.updateListener = new ModelUpdateListener(relationViews); 24 this.updateListener = new ModelUpdateListener(relationViews);
24 } 25 }
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraQueryableModel.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraQueryableModel.java
index cd9fb180..5b06e266 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraQueryableModel.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraQueryableModel.java
@@ -8,6 +8,7 @@ import tools.refinery.store.map.Cursor;
8import tools.refinery.store.map.DiffCursor; 8import tools.refinery.store.map.DiffCursor;
9import tools.refinery.store.model.Model; 9import tools.refinery.store.model.Model;
10import tools.refinery.store.model.ModelDiffCursor; 10import tools.refinery.store.model.ModelDiffCursor;
11import tools.refinery.store.model.representation.AnyDataRepresentation;
11import tools.refinery.store.model.representation.DataRepresentation; 12import tools.refinery.store.model.representation.DataRepresentation;
12import tools.refinery.store.model.representation.Relation; 13import tools.refinery.store.model.representation.Relation;
13import tools.refinery.store.query.QueryableModel; 14import tools.refinery.store.query.QueryableModel;
@@ -66,7 +67,7 @@ public class ViatraQueryableModel implements QueryableModel {
66 } 67 }
67 68
68 @Override 69 @Override
69 public Set<DataRepresentation<?, ?>> getDataRepresentations() { 70 public Set<AnyDataRepresentation> getDataRepresentations() {
70 return model.getDataRepresentations(); 71 return model.getDataRepresentations();
71 } 72 }
72 73
@@ -113,7 +114,7 @@ public class ViatraQueryableModel implements QueryableModel {
113 } 114 }
114 115
115 @Override 116 @Override
116 public <K, V> long getSize(DataRepresentation<K, V> representation) { 117 public long getSize(AnyDataRepresentation representation) {
117 return model.getSize(representation); 118 return model.getSize(representation);
118 } 119 }
119 120
@@ -207,7 +208,8 @@ public class ViatraQueryableModel implements QueryableModel {
207 208
208 private void restoreWithDiffReplay(long state) { 209 private void restoreWithDiffReplay(long state) {
209 var modelDiffCursor = getDiffCursor(state); 210 var modelDiffCursor = getDiffCursor(state);
210 for (DataRepresentation<?, ?> dataRepresentation : this.getDataRepresentations()) { 211 for (AnyDataRepresentation anyDataRepresentation : this.getDataRepresentations()) {
212 var dataRepresentation = (DataRepresentation<?, ?>) anyDataRepresentation;
211 restoreRepresentationWithDiffReplay(modelDiffCursor, dataRepresentation); 213 restoreRepresentationWithDiffReplay(modelDiffCursor, dataRepresentation);
212 } 214 }
213 } 215 }
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java
index c007d630..e01525e0 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java
@@ -9,6 +9,7 @@ import org.eclipse.viatra.query.runtime.matchers.util.Accuracy;
9import tools.refinery.store.model.Model; 9import tools.refinery.store.model.Model;
10import tools.refinery.store.query.viatra.internal.pquery.RelationViewWrapper; 10import tools.refinery.store.query.viatra.internal.pquery.RelationViewWrapper;
11import tools.refinery.store.query.viatra.internal.viewupdate.ModelUpdateListener; 11import tools.refinery.store.query.viatra.internal.viewupdate.ModelUpdateListener;
12import tools.refinery.store.query.view.AnyRelationView;
12import tools.refinery.store.query.view.RelationView; 13import tools.refinery.store.query.view.RelationView;
13 14
14import java.lang.reflect.InvocationTargetException; 15import java.lang.reflect.InvocationTargetException;
@@ -53,7 +54,7 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext {
53 @Override 54 @Override
54 public boolean isIndexed(IInputKey key, IndexingService service) { 55 public boolean isIndexed(IInputKey key, IndexingService service) {
55 if (key instanceof RelationView<?> relationalKey) { 56 if (key instanceof RelationView<?> relationalKey) {
56 return this.modelUpdateListener.containsRelationalView(relationalKey); 57 return this.modelUpdateListener.containsRelationView(relationalKey);
57 } else { 58 } else {
58 return false; 59 return false;
59 } 60 }
@@ -66,11 +67,10 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext {
66 } 67 }
67 } 68 }
68 69
69 @SuppressWarnings("squid:S1452") 70 AnyRelationView checkKey(IInputKey key) {
70 RelationView<?> checkKey(IInputKey key) {
71 if (key instanceof RelationViewWrapper wrappedKey) { 71 if (key instanceof RelationViewWrapper wrappedKey) {
72 var relationViewKey = wrappedKey.getWrappedKey(); 72 var relationViewKey = wrappedKey.getWrappedKey();
73 if (modelUpdateListener.containsRelationalView(relationViewKey)) { 73 if (modelUpdateListener.containsRelationView(relationViewKey)) {
74 return relationViewKey; 74 return relationViewKey;
75 } else { 75 } else {
76 throw new IllegalStateException("Query is asking for non-indexed key"); 76 throw new IllegalStateException("Query is asking for non-indexed key");
@@ -82,8 +82,8 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext {
82 82
83 @Override 83 @Override
84 public int countTuples(IInputKey key, TupleMask seedMask, ITuple seed) { 84 public int countTuples(IInputKey key, TupleMask seedMask, ITuple seed) {
85 RelationView<?> relationalViewKey = checkKey(key); 85 var relationViewKey = checkKey(key);
86 Iterable<Object[]> allObjects = relationalViewKey.getAll(model); 86 Iterable<Object[]> allObjects = relationViewKey.getAll(model);
87 Iterable<Object[]> filteredBySeed = filter(allObjects, objectArray -> isMatching(objectArray, seedMask, seed)); 87 Iterable<Object[]> filteredBySeed = filter(allObjects, objectArray -> isMatching(objectArray, seedMask, seed));
88 Iterator<Object[]> iterator = filteredBySeed.iterator(); 88 Iterator<Object[]> iterator = filteredBySeed.iterator();
89 int result = 0; 89 int result = 0;
@@ -101,8 +101,8 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext {
101 101
102 @Override 102 @Override
103 public Iterable<Tuple> enumerateTuples(IInputKey key, TupleMask seedMask, ITuple seed) { 103 public Iterable<Tuple> enumerateTuples(IInputKey key, TupleMask seedMask, ITuple seed) {
104 RelationView<?> relationalViewKey = checkKey(key); 104 var relationViewKey = checkKey(key);
105 Iterable<Object[]> allObjects = relationalViewKey.getAll(model); 105 Iterable<Object[]> allObjects = relationViewKey.getAll(model);
106 Iterable<Object[]> filteredBySeed = filter(allObjects, objectArray -> isMatching(objectArray, seedMask, seed)); 106 Iterable<Object[]> filteredBySeed = filter(allObjects, objectArray -> isMatching(objectArray, seedMask, seed));
107 return map(filteredBySeed, Tuples::flatTupleOf); 107 return map(filteredBySeed, Tuples::flatTupleOf);
108 } 108 }
@@ -125,21 +125,21 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext {
125 125
126 @Override 126 @Override
127 public boolean containsTuple(IInputKey key, ITuple seed) { 127 public boolean containsTuple(IInputKey key, ITuple seed) {
128 RelationView<?> relationalViewKey = checkKey(key); 128 var relationViewKey = checkKey(key);
129 return relationalViewKey.get(model, seed.getElements()); 129 return relationViewKey.get(model, seed.getElements());
130 } 130 }
131 131
132 @Override 132 @Override
133 public void addUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) { 133 public void addUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) {
134 RelationView<?> relationalKey = checkKey(key); 134 var relationViewKey = (RelationView<?>) checkKey(key);
135 this.modelUpdateListener.addListener(key, relationalKey, seed, listener); 135 this.modelUpdateListener.addListener(key, relationViewKey, seed, listener);
136 136
137 } 137 }
138 138
139 @Override 139 @Override
140 public void removeUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) { 140 public void removeUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) {
141 RelationView<?> relationalKey = checkKey(key); 141 var relationViewKey = checkKey(key);
142 this.modelUpdateListener.removeListener(key, relationalKey, seed, listener); 142 this.modelUpdateListener.removeListener(key, relationViewKey, seed, listener);
143 } 143 }
144 144
145 @Override 145 @Override
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java
index 98054161..aa3fba6e 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java
@@ -2,7 +2,10 @@ package tools.refinery.store.query.viatra.internal.pquery;
2 2
3import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; 3import org.eclipse.viatra.query.runtime.matchers.psystem.PBody;
4import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; 4import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable;
5import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.*; 5import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality;
6import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter;
7import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality;
8import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall;
6import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.BinaryTransitiveClosure; 9import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.BinaryTransitiveClosure;
7import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.ConstantValue; 10import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.ConstantValue;
8import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; 11import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall;
@@ -10,9 +13,11 @@ import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeCo
10import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; 13import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter;
11import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; 14import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple;
12import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; 15import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples;
13import tools.refinery.store.query.*; 16import tools.refinery.store.query.DNF;
17import tools.refinery.store.query.DNFAnd;
18import tools.refinery.store.query.Variable;
14import tools.refinery.store.query.atom.*; 19import tools.refinery.store.query.atom.*;
15import tools.refinery.store.query.view.RelationView; 20import tools.refinery.store.query.view.AnyRelationView;
16 21
17import java.util.*; 22import java.util.*;
18import java.util.stream.Collectors; 23import java.util.stream.Collectors;
@@ -22,7 +27,7 @@ public class DNF2PQuery {
22 27
23 private final Map<DNF, SimplePQuery> dnf2PQueryMap = new HashMap<>(); 28 private final Map<DNF, SimplePQuery> dnf2PQueryMap = new HashMap<>();
24 29
25 private final Map<RelationView<?>, RelationViewWrapper> view2WrapperMap = new HashMap<>(); 30 private final Map<AnyRelationView, RelationViewWrapper> view2WrapperMap = new HashMap<>();
26 31
27 public SimplePQuery translate(DNF dnfQuery) { 32 public SimplePQuery translate(DNF dnfQuery) {
28 if (translating.contains(dnfQuery)) { 33 if (translating.contains(dnfQuery)) {
@@ -115,7 +120,7 @@ public class DNF2PQuery {
115 return Tuples.flatTupleOf(variables); 120 return Tuples.flatTupleOf(variables);
116 } 121 }
117 122
118 private RelationViewWrapper wrapView(RelationView<?> relationView) { 123 private RelationViewWrapper wrapView(AnyRelationView relationView) {
119 return view2WrapperMap.computeIfAbsent(relationView, RelationViewWrapper::new); 124 return view2WrapperMap.computeIfAbsent(relationView, RelationViewWrapper::new);
120 } 125 }
121 126
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RelationViewWrapper.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RelationViewWrapper.java
index 2a4148dc..e48648bf 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RelationViewWrapper.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RelationViewWrapper.java
@@ -1,10 +1,10 @@
1package tools.refinery.store.query.viatra.internal.pquery; 1package tools.refinery.store.query.viatra.internal.pquery;
2 2
3import org.eclipse.viatra.query.runtime.matchers.context.common.BaseInputKeyWrapper; 3import org.eclipse.viatra.query.runtime.matchers.context.common.BaseInputKeyWrapper;
4import tools.refinery.store.query.view.RelationView; 4import tools.refinery.store.query.view.AnyRelationView;
5 5
6public class RelationViewWrapper extends BaseInputKeyWrapper<RelationView<?>> { 6public class RelationViewWrapper extends BaseInputKeyWrapper<AnyRelationView> {
7 public RelationViewWrapper(RelationView<?> wrappedKey) { 7 public RelationViewWrapper(AnyRelationView wrappedKey) {
8 super(wrappedKey); 8 super(wrappedKey);
9 } 9 }
10 10
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ModelUpdateListener.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ModelUpdateListener.java
index 1a2fcee7..6a1d06a9 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ModelUpdateListener.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ModelUpdateListener.java
@@ -3,6 +3,8 @@ package tools.refinery.store.query.viatra.internal.viewupdate;
3import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; 3import org.eclipse.viatra.query.runtime.matchers.context.IInputKey;
4import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; 4import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener;
5import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; 5import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple;
6import tools.refinery.store.model.representation.AnyRelation;
7import tools.refinery.store.query.view.AnyRelationView;
6import tools.refinery.store.tuple.Tuple; 8import tools.refinery.store.tuple.Tuple;
7import tools.refinery.store.model.representation.Relation; 9import tools.refinery.store.model.representation.Relation;
8import tools.refinery.store.query.view.RelationView; 10import tools.refinery.store.query.view.RelationView;
@@ -16,24 +18,24 @@ public class ModelUpdateListener {
16 /** 18 /**
17 * Collections of Relations and their Views. 19 * Collections of Relations and their Views.
18 */ 20 */
19 private final Map<Relation<?>, Set<RelationView<?>>> relation2View; 21 private final Map<AnyRelation, Set<AnyRelationView>> relation2View;
20 22
21 /** 23 /**
22 * Collection of Views and their buffers. 24 * Collection of Views and their buffers.
23 */ 25 */
24 private final Map<RelationView<?>, Set<ViewUpdateBuffer<?>>> view2Buffers; 26 private final Map<AnyRelationView, Set<ViewUpdateBuffer<?>>> view2Buffers;
25 27
26 public ModelUpdateListener(Set<RelationView<?>> relationViews) { 28 public ModelUpdateListener(Set<AnyRelationView> relationViews) {
27 this.relation2View = new HashMap<>(); 29 this.relation2View = new HashMap<>();
28 this.view2Buffers = new HashMap<>(); 30 this.view2Buffers = new HashMap<>();
29 31
30 for (RelationView<?> relationView : relationViews) { 32 for (var relationView : relationViews) {
31 registerView(relationView); 33 registerView(relationView);
32 } 34 }
33 } 35 }
34 36
35 private void registerView(RelationView<?> view) { 37 private void registerView(AnyRelationView view) {
36 Relation<?> relation = view.getRepresentation(); 38 AnyRelation relation = view.getRepresentation();
37 39
38 // 1. register views to relations, if necessary 40 // 1. register views to relations, if necessary
39 var views = relation2View.computeIfAbsent(relation, x -> new HashSet<>()); 41 var views = relation2View.computeIfAbsent(relation, x -> new HashSet<>());
@@ -43,7 +45,7 @@ public class ModelUpdateListener {
43 view2Buffers.computeIfAbsent(view, x -> new HashSet<>()); 45 view2Buffers.computeIfAbsent(view, x -> new HashSet<>());
44 } 46 }
45 47
46 public boolean containsRelationalView(RelationView<?> relationalKey) { 48 public boolean containsRelationView(AnyRelationView relationalKey) {
47 return view2Buffers.containsKey(relationalKey); 49 return view2Buffers.containsKey(relationalKey);
48 } 50 }
49 51
@@ -58,7 +60,7 @@ public class ModelUpdateListener {
58 } 60 }
59 } 61 }
60 62
61 public void removeListener(IInputKey key, RelationView<?> relationView, ITuple seed, 63 public void removeListener(IInputKey key, AnyRelationView relationView, ITuple seed,
62 IQueryRuntimeContextListener listener) { 64 IQueryRuntimeContextListener listener) {
63 if (view2Buffers.containsKey(relationView)) { 65 if (view2Buffers.containsKey(relationView)) {
64 Set<ViewUpdateBuffer<?>> buffers = this.view2Buffers.get(relationView); 66 Set<ViewUpdateBuffer<?>> buffers = this.view2Buffers.get(relationView);
@@ -92,8 +94,9 @@ public class ModelUpdateListener {
92 public boolean hasChanges() { 94 public boolean hasChanges() {
93 for (var bufferCollection : this.view2Buffers.values()) { 95 for (var bufferCollection : this.view2Buffers.values()) {
94 for (ViewUpdateBuffer<?> buffer : bufferCollection) { 96 for (ViewUpdateBuffer<?> buffer : bufferCollection) {
95 if (buffer.hasChanges()) 97 if (buffer.hasChanges()) {
96 return true; 98 return true;
99 }
97 } 100 }
98 } 101 }
99 return false; 102 return false;
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateTranslator.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateTranslator.java
index 74d0b366..c324c84a 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateTranslator.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateTranslator.java
@@ -4,8 +4,9 @@ import org.eclipse.viatra.query.runtime.matchers.context.IInputKey;
4import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; 4import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener;
5import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; 5import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple;
6import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; 6import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples;
7import tools.refinery.store.tuple.Tuple; 7import tools.refinery.store.query.view.AnyRelationView;
8import tools.refinery.store.query.view.RelationView; 8import tools.refinery.store.query.view.RelationView;
9import tools.refinery.store.tuple.Tuple;
9 10
10import java.util.Objects; 11import java.util.Objects;
11 12
@@ -27,7 +28,7 @@ public class ViewUpdateTranslator<D> {
27 this.listener = listener; 28 this.listener = listener;
28 } 29 }
29 30
30 public boolean equals(IInputKey wrappedKey, RelationView<?> relationView, ITuple seed, 31 public boolean equals(IInputKey wrappedKey, AnyRelationView relationView, ITuple seed,
31 IQueryRuntimeContextListener listener) { 32 IQueryRuntimeContextListener listener) {
32 return this.wrappedKey == wrappedKey && key == relationView && filter.equals(seed) && this.listener == listener; 33 return this.wrappedKey == wrappedKey && key == relationView && filter.equals(seed) && this.listener == listener;
33 } 34 }
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/AnyVersionedMap.java b/subprojects/store/src/main/java/tools/refinery/store/map/AnyVersionedMap.java
new file mode 100644
index 00000000..b94b9f38
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/map/AnyVersionedMap.java
@@ -0,0 +1,5 @@
1package tools.refinery.store.map;
2
3public sealed interface AnyVersionedMap extends Versioned permits VersionedMap {
4 long getSize();
5}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/Cursor.java b/subprojects/store/src/main/java/tools/refinery/store/map/Cursor.java
index 9c465ddc..b420585c 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/map/Cursor.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/map/Cursor.java
@@ -1,14 +1,21 @@
1package tools.refinery.store.map; 1package tools.refinery.store.map;
2 2
3import java.util.List; 3import java.util.Set;
4 4
5public interface Cursor<K,V> { 5public interface Cursor<K, V> {
6 public K getKey(); 6 K getKey();
7 public V getValue(); 7
8 public boolean isTerminated(); 8 V getValue();
9 public boolean move(); 9
10 public boolean isDirty(); 10 boolean isTerminated();
11 11
12 @SuppressWarnings("squid:S1452") 12 boolean move();
13 public List<VersionedMap<?,?>> getDependingMaps(); 13
14 default boolean isDirty() {
15 return false;
16 }
17
18 default Set<AnyVersionedMap> getDependingMaps() {
19 return Set.of();
20 }
14} 21}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMap.java b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMap.java
index a8a64d08..31985e94 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMap.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMap.java
@@ -1,13 +1,13 @@
1package tools.refinery.store.map; 1package tools.refinery.store.map;
2 2
3public interface VersionedMap<K,V> extends Versioned{ 3public non-sealed interface VersionedMap<K, V> extends AnyVersionedMap {
4 public V get(K key); 4 V get(K key);
5 public Cursor<K,V> getAll(); 5
6 6 Cursor<K, V> getAll();
7 public V put(K key, V value); 7
8 public void putAll(Cursor<K,V> cursor); 8 V put(K key, V value);
9 9
10 public long getSize(); 10 void putAll(Cursor<K, V> cursor);
11 11
12 public DiffCursor<K,V> getDiffCursor(long state); 12 DiffCursor<K, V> getDiffCursor(long state);
13} 13}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreConfiguration.java b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreConfiguration.java
index 723e5ec4..3856460d 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreConfiguration.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreConfiguration.java
@@ -1,14 +1,14 @@
1package tools.refinery.store.map; 1package tools.refinery.store.map;
2 2
3public class VersionedMapStoreConfiguration { 3public class VersionedMapStoreConfiguration {
4 4
5 public VersionedMapStoreConfiguration() { 5 public VersionedMapStoreConfiguration() {
6 6
7 } 7 }
8 public VersionedMapStoreConfiguration(boolean immutableWhenCommiting, boolean sharedNodeCacheInStore, 8 public VersionedMapStoreConfiguration(boolean immutableWhenCommitting, boolean sharedNodeCacheInStore,
9 boolean sharedNodeCacheInStoreGroups) { 9 boolean sharedNodeCacheInStoreGroups) {
10 super(); 10 super();
11 this.immutableWhenCommiting = immutableWhenCommiting; 11 this.immutableWhenCommitting = immutableWhenCommitting;
12 this.sharedNodeCacheInStore = sharedNodeCacheInStore; 12 this.sharedNodeCacheInStore = sharedNodeCacheInStore;
13 this.sharedNodeCacheInStoreGroups = sharedNodeCacheInStoreGroups; 13 this.sharedNodeCacheInStoreGroups = sharedNodeCacheInStoreGroups;
14 } 14 }
@@ -18,13 +18,13 @@ public class VersionedMapStoreConfiguration {
18 * by releasing immutable nodes, but it may decrease performance by recreating 18 * by releasing immutable nodes, but it may decrease performance by recreating
19 * immutable nodes upon changes (some evidence). 19 * immutable nodes upon changes (some evidence).
20 */ 20 */
21 private boolean immutableWhenCommiting = true; 21 private boolean immutableWhenCommitting = true;
22 public boolean isImmutableWhenCommiting() { 22 public boolean isImmutableWhenCommitting() {
23 return immutableWhenCommiting; 23 return immutableWhenCommitting;
24 } 24 }
25 25
26 /** 26 /**
27 * If true, all subnodes are cached within a {@link VersionedMapStore}. It 27 * If true, all sub-nodes are cached within a {@link VersionedMapStore}. It
28 * decreases the memory requirements. It may increase performance by discovering 28 * decreases the memory requirements. It may increase performance by discovering
29 * existing immutable copy of a node (some evidence). Additional overhead may 29 * existing immutable copy of a node (some evidence). Additional overhead may
30 * decrease performance (no example found). The option permits the efficient 30 * decrease performance (no example found). The option permits the efficient
@@ -34,9 +34,9 @@ public class VersionedMapStoreConfiguration {
34 public boolean isSharedNodeCacheInStore() { 34 public boolean isSharedNodeCacheInStore() {
35 return sharedNodeCacheInStore; 35 return sharedNodeCacheInStore;
36 } 36 }
37 37
38 /** 38 /**
39 * If true, all subnodes are cached within a group of 39 * If true, all sub-nodes are cached within a group of
40 * {@link VersionedMapStoreImpl#createSharedVersionedMapStores(int, ContinousHashProvider, Object, VersionedMapStoreConfiguration)}. 40 * {@link VersionedMapStoreImpl#createSharedVersionedMapStores(int, ContinousHashProvider, Object, VersionedMapStoreConfiguration)}.
41 * If {@link VersionedMapStoreConfiguration#sharedNodeCacheInStore} is 41 * If {@link VersionedMapStoreConfiguration#sharedNodeCacheInStore} is
42 * <code>false</code>, then it has currently no impact. 42 * <code>false</code>, then it has currently no impact.
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreImpl.java b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreImpl.java
index a626a5e8..113874e7 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreImpl.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreImpl.java
@@ -1,22 +1,15 @@
1package tools.refinery.store.map; 1package tools.refinery.store.map;
2 2
3import java.util.ArrayList;
4import java.util.Arrays;
5import java.util.Collections;
6import java.util.HashMap;
7import java.util.HashSet;
8import java.util.List;
9import java.util.Map;
10import java.util.Set;
11
12import tools.refinery.store.map.internal.ImmutableNode; 3import tools.refinery.store.map.internal.ImmutableNode;
13import tools.refinery.store.map.internal.MapDiffCursor; 4import tools.refinery.store.map.internal.MapDiffCursor;
14import tools.refinery.store.map.internal.Node; 5import tools.refinery.store.map.internal.Node;
15import tools.refinery.store.map.internal.VersionedMapImpl; 6import tools.refinery.store.map.internal.VersionedMapImpl;
16 7
8import java.util.*;
9
17public class VersionedMapStoreImpl<K, V> implements VersionedMapStore<K, V> { 10public class VersionedMapStoreImpl<K, V> implements VersionedMapStore<K, V> {
18 // Configuration 11 // Configuration
19 private final boolean immutableWhenCommiting; 12 private final boolean immutableWhenCommitting;
20 13
21 // Static data 14 // Static data
22 protected final ContinousHashProvider<K> hashProvider; 15 protected final ContinousHashProvider<K> hashProvider;
@@ -29,7 +22,7 @@ public class VersionedMapStoreImpl<K, V> implements VersionedMapStore<K, V> {
29 22
30 public VersionedMapStoreImpl(ContinousHashProvider<K> hashProvider, V defaultValue, 23 public VersionedMapStoreImpl(ContinousHashProvider<K> hashProvider, V defaultValue,
31 VersionedMapStoreConfiguration config) { 24 VersionedMapStoreConfiguration config) {
32 this.immutableWhenCommiting = config.isImmutableWhenCommiting(); 25 this.immutableWhenCommitting = config.isImmutableWhenCommitting();
33 this.hashProvider = hashProvider; 26 this.hashProvider = hashProvider;
34 this.defaultValue = defaultValue; 27 this.defaultValue = defaultValue;
35 if (config.isSharedNodeCacheInStore()) { 28 if (config.isSharedNodeCacheInStore()) {
@@ -41,7 +34,7 @@ public class VersionedMapStoreImpl<K, V> implements VersionedMapStore<K, V> {
41 34
42 private VersionedMapStoreImpl(ContinousHashProvider<K> hashProvider, V defaultValue, 35 private VersionedMapStoreImpl(ContinousHashProvider<K> hashProvider, V defaultValue,
43 Map<Node<K, V>, ImmutableNode<K, V>> nodeCache, VersionedMapStoreConfiguration config) { 36 Map<Node<K, V>, ImmutableNode<K, V>> nodeCache, VersionedMapStoreConfiguration config) {
44 this.immutableWhenCommiting = config.isImmutableWhenCommiting(); 37 this.immutableWhenCommitting = config.isImmutableWhenCommitting();
45 this.hashProvider = hashProvider; 38 this.hashProvider = hashProvider;
46 this.defaultValue = defaultValue; 39 this.defaultValue = defaultValue;
47 this.nodeCache = nodeCache; 40 this.nodeCache = nodeCache;
@@ -77,7 +70,7 @@ public class VersionedMapStoreImpl<K, V> implements VersionedMapStore<K, V> {
77 ContinousHashProvider<K> hashProvider, V defaultValue) { 70 ContinousHashProvider<K> hashProvider, V defaultValue) {
78 return createSharedVersionedMapStores(amount, hashProvider, defaultValue, new VersionedMapStoreConfiguration()); 71 return createSharedVersionedMapStores(amount, hashProvider, defaultValue, new VersionedMapStoreConfiguration());
79 } 72 }
80 73
81 @Override 74 @Override
82 public synchronized Set<Long> getStates() { 75 public synchronized Set<Long> getStates() {
83 return new HashSet<>(states.keySet()); 76 return new HashSet<>(states.keySet());
@@ -93,7 +86,6 @@ public class VersionedMapStoreImpl<K, V> implements VersionedMapStore<K, V> {
93 ImmutableNode<K, V> data = revert(state); 86 ImmutableNode<K, V> data = revert(state);
94 return new VersionedMapImpl<>(this, hashProvider, defaultValue, data); 87 return new VersionedMapImpl<>(this, hashProvider, defaultValue, data);
95 } 88 }
96
97 89
98 public synchronized ImmutableNode<K, V> revert(long state) { 90 public synchronized ImmutableNode<K, V> revert(long state) {
99 if (states.containsKey(state)) { 91 if (states.containsKey(state)) {
@@ -118,7 +110,7 @@ public class VersionedMapStoreImpl<K, V> implements VersionedMapStore<K, V> {
118 throw new IllegalStateException("Map store run out of Id-s"); 110 throw new IllegalStateException("Map store run out of Id-s");
119 long id = nextID++; 111 long id = nextID++;
120 this.states.put(id, immutable); 112 this.states.put(id, immutable);
121 if (this.immutableWhenCommiting) { 113 if (this.immutableWhenCommitting) {
122 mapToUpdateRoot.setRoot(immutable); 114 mapToUpdateRoot.setRoot(immutable);
123 } 115 }
124 return id; 116 return id;
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapCursor.java b/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapCursor.java
index b90f5b71..1698830f 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapCursor.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapCursor.java
@@ -1,128 +1,136 @@
1package tools.refinery.store.map.internal; 1package tools.refinery.store.map.internal;
2 2
3import tools.refinery.store.map.AnyVersionedMap;
4import tools.refinery.store.map.Cursor;
5import tools.refinery.store.map.VersionedMap;
6
3import java.util.ArrayDeque; 7import java.util.ArrayDeque;
4import java.util.ConcurrentModificationException; 8import java.util.ConcurrentModificationException;
5import java.util.Iterator; 9import java.util.Iterator;
6import java.util.List; 10import java.util.Set;
7
8import tools.refinery.store.map.Cursor;
9import tools.refinery.store.map.VersionedMap;
10 11
11public class MapCursor<K,V> implements Cursor<K,V> { 12public class MapCursor<K, V> implements Cursor<K, V> {
12 // Constants 13 // Constants
13 static final int INDEX_START = -1; 14 static final int INDEX_START = -1;
14 static final int INDEX_FINISH = -2; 15 static final int INDEX_FINISH = -2;
15 16
16 // Tree stack 17 // Tree stack
17 ArrayDeque<Node<K,V>> nodeStack; 18 ArrayDeque<Node<K, V>> nodeStack;
18 ArrayDeque<Integer> nodeIndexStack; 19 ArrayDeque<Integer> nodeIndexStack;
19 int dataIndex; 20 int dataIndex;
20 21
21 // Values 22 // Values
22 K key; 23 K key;
23 V value; 24 V value;
24 25
25 // Hash code for checking concurrent modifications 26 // Hash code for checking concurrent modifications
26 final VersionedMap<K,V> map; 27 final VersionedMap<K, V> map;
27 final int creationHash; 28 final int creationHash;
28 29
29 public MapCursor(Node<K, V> root, VersionedMap<K,V> map) { 30 public MapCursor(Node<K, V> root, VersionedMap<K, V> map) {
30 // Initializing tree stack 31 // Initializing tree stack
31 super(); 32 super();
32 this.nodeStack = new ArrayDeque<>(); 33 this.nodeStack = new ArrayDeque<>();
33 this.nodeIndexStack = new ArrayDeque<>(); 34 this.nodeIndexStack = new ArrayDeque<>();
34 if(root != null) { 35 if (root != null) {
35 this.nodeStack.add(root); 36 this.nodeStack.add(root);
36 this.nodeIndexStack.push(INDEX_START); 37 this.nodeIndexStack.push(INDEX_START);
37 } 38 }
38 39
39 this.dataIndex = INDEX_START; 40 this.dataIndex = INDEX_START;
40 41
41 // Initializing cache 42 // Initializing cache
42 this.key = null; 43 this.key = null;
43 this.value = null; 44 this.value = null;
44 45
45 // Initializing state 46 // Initializing state
46 this.map=map; 47 this.map = map;
47 this.creationHash = map.hashCode(); 48 this.creationHash = map.hashCode();
48 } 49 }
49 50
50 public K getKey() { 51 public K getKey() {
51 return key; 52 return key;
52 } 53 }
53 54
54 public V getValue() { 55 public V getValue() {
55 return value; 56 return value;
56 } 57 }
57 58
58 public boolean isTerminated() { 59 public boolean isTerminated() {
59 return this.nodeStack.isEmpty(); 60 return this.nodeStack.isEmpty();
60 } 61 }
61 62
62 public boolean move() { 63 public boolean move() {
63 if(isDirty()) { 64 if (isDirty()) {
64 throw new ConcurrentModificationException(); 65 throw new ConcurrentModificationException();
65 } 66 }
66 if(!isTerminated()) { 67 if (!isTerminated()) {
67 boolean result = this.nodeStack.peek().moveToNext(this); 68 var node = this.nodeStack.peek();
68 if(this.nodeIndexStack.size() != this.nodeStack.size()) { 69 if (node == null) {
70 throw new IllegalStateException("Cursor is not terminated but the current node is missing");
71 }
72 boolean result = node.moveToNext(this);
73 if (this.nodeIndexStack.size() != this.nodeStack.size()) {
69 throw new IllegalArgumentException("Node stack is corrupted by illegal moves!"); 74 throw new IllegalArgumentException("Node stack is corrupted by illegal moves!");
70 } 75 }
71 return result; 76 return result;
72 } 77 }
73 return false; 78 return false;
74 } 79 }
80
75 public boolean skipCurrentNode() { 81 public boolean skipCurrentNode() {
76 nodeStack.pop(); 82 nodeStack.pop();
77 nodeIndexStack.pop(); 83 nodeIndexStack.pop();
78 dataIndex = INDEX_FINISH; 84 dataIndex = INDEX_FINISH;
79 return move(); 85 return move();
80 } 86 }
87
81 @Override 88 @Override
82 public boolean isDirty() { 89 public boolean isDirty() {
83 return this.map.hashCode() != this.creationHash; 90 return this.map.hashCode() != this.creationHash;
84 } 91 }
92
85 @Override 93 @Override
86 public List<VersionedMap<?, ?>> getDependingMaps() { 94 public Set<AnyVersionedMap> getDependingMaps() {
87 return List.of(this.map); 95 return Set.of(this.map);
88 } 96 }
89 97
90 public static <K,V> boolean sameSubnode(MapCursor<K,V> cursor1, MapCursor<K,V> cursor2) { 98 public static <K, V> boolean sameSubnode(MapCursor<K, V> cursor1, MapCursor<K, V> cursor2) {
91 Node<K, V> nodeOfCursor1 = cursor1.nodeStack.peek(); 99 Node<K, V> nodeOfCursor1 = cursor1.nodeStack.peek();
92 Node<K, V> nodeOfCursor2 = cursor2.nodeStack.peek(); 100 Node<K, V> nodeOfCursor2 = cursor2.nodeStack.peek();
93 if(nodeOfCursor1 != null && nodeOfCursor2 != null) { 101 if (nodeOfCursor1 != null && nodeOfCursor2 != null) {
94 return nodeOfCursor1.equals(nodeOfCursor2); 102 return nodeOfCursor1.equals(nodeOfCursor2);
95 } else { 103 } else {
96 return false; 104 return false;
97 } 105 }
98 } 106 }
99 107
100 /** 108 /**
101 *
102 * @param <K> 109 * @param <K>
103 * @param <V> 110 * @param <V>
104 * @param cursor1 111 * @param cursor1
105 * @param cursor2 112 * @param cursor2
106 * @return Positive number if cursor 1 is behind, negative number if cursor 2 is behind, and 0 if they are at the same position. 113 * @return Positive number if cursor 1 is behind, negative number if cursor 2 is behind, and 0 if they are at the
114 * same position.
107 */ 115 */
108 public static <K,V> int compare(MapCursor<K,V> cursor1, MapCursor<K,V> cursor2) { 116 public static <K, V> int compare(MapCursor<K, V> cursor1, MapCursor<K, V> cursor2) {
109 // two cursors are equally deep 117 // two cursors are equally deep
110 Iterator<Integer> stack1 = cursor1.nodeIndexStack.descendingIterator(); 118 Iterator<Integer> stack1 = cursor1.nodeIndexStack.descendingIterator();
111 Iterator<Integer> stack2 = cursor2.nodeIndexStack.descendingIterator(); 119 Iterator<Integer> stack2 = cursor2.nodeIndexStack.descendingIterator();
112 if(stack1.hasNext()) { 120 if (stack1.hasNext()) {
113 if(!stack2.hasNext()) { 121 if (!stack2.hasNext()) {
114 // stack 2 has no more element, thus stack 1 is deeper 122 // stack 2 has no more element, thus stack 1 is deeper
115 return 1; 123 return 1;
116 } 124 }
117 int val1 = stack1.next(); 125 int val1 = stack1.next();
118 int val2 = stack2.next(); 126 int val2 = stack2.next();
119 if(val1 < val2) { 127 if (val1 < val2) {
120 return -1; 128 return -1;
121 } else if(val2 < val1) { 129 } else if (val2 < val1) {
122 return 1; 130 return 1;
123 } 131 }
124 } 132 }
125 if(stack2.hasNext()) { 133 if (stack2.hasNext()) {
126 // stack 2 has more element, thus stack 2 is deeper 134 // stack 2 has more element, thus stack 2 is deeper
127 return 1; 135 return 1;
128 } 136 }
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapDiffCursor.java b/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapDiffCursor.java
index a4ca813c..9cd78113 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapDiffCursor.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapDiffCursor.java
@@ -1,12 +1,13 @@
1package tools.refinery.store.map.internal; 1package tools.refinery.store.map.internal;
2 2
3import java.util.List; 3import tools.refinery.store.map.AnyVersionedMap;
4import java.util.stream.Stream;
5
6import tools.refinery.store.map.ContinousHashProvider; 4import tools.refinery.store.map.ContinousHashProvider;
7import tools.refinery.store.map.Cursor; 5import tools.refinery.store.map.Cursor;
8import tools.refinery.store.map.DiffCursor; 6import tools.refinery.store.map.DiffCursor;
9import tools.refinery.store.map.VersionedMap; 7
8import java.util.Set;
9import java.util.stream.Collectors;
10import java.util.stream.Stream;
10 11
11/** 12/**
12 * A cursor representing the difference between two states of a map. 13 * A cursor representing the difference between two states of a map.
@@ -18,10 +19,10 @@ public class MapDiffCursor<K, V> implements DiffCursor<K, V>, Cursor<K, V> {
18 /** 19 /**
19 * Default nodeId representing missing elements. 20 * Default nodeId representing missing elements.
20 */ 21 */
21 private V defaultValue; 22 private final V defaultValue;
22 private MapCursor<K, V> cursor1; 23 private final MapCursor<K, V> cursor1;
23 private MapCursor<K, V> cursor2; 24 private final MapCursor<K, V> cursor2;
24 private ContinousHashProvider<? super K> hashProvider; 25 private final ContinousHashProvider<? super K> hashProvider;
25 26
26 // Values 27 // Values
27 private K key; 28 private K key;
@@ -75,8 +76,10 @@ public class MapDiffCursor<K, V> implements DiffCursor<K, V>, Cursor<K, V> {
75 } 76 }
76 77
77 @Override 78 @Override
78 public List<VersionedMap<?, ?>> getDependingMaps() { 79 public Set<AnyVersionedMap> getDependingMaps() {
79 return Stream.concat(cursor1.getDependingMaps().stream(), cursor2.getDependingMaps().stream()).toList(); 80 return Stream.concat(cursor1.getDependingMaps().stream(), cursor2.getDependingMaps().stream())
81 .map(AnyVersionedMap.class::cast)
82 .collect(Collectors.toUnmodifiableSet());
80 } 83 }
81 84
82 protected void updateState() { 85 protected void updateState() {
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/internal/VersionedMapImpl.java b/subprojects/store/src/main/java/tools/refinery/store/map/internal/VersionedMapImpl.java
index 346fe596..866e7b33 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/map/internal/VersionedMapImpl.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/map/internal/VersionedMapImpl.java
@@ -1,61 +1,59 @@
1package tools.refinery.store.map.internal; 1package tools.refinery.store.map.internal;
2 2
3import tools.refinery.store.map.*;
4
3import java.util.Iterator; 5import java.util.Iterator;
4import java.util.LinkedList; 6import java.util.LinkedList;
5import java.util.List; 7import java.util.List;
6 8
7import tools.refinery.store.map.ContinousHashProvider;
8import tools.refinery.store.map.Cursor;
9import tools.refinery.store.map.DiffCursor;
10import tools.refinery.store.map.VersionedMap;
11import tools.refinery.store.map.VersionedMapStoreImpl;
12
13/** 9/**
14 * Not threadSafe in itself 10 * Not threadSafe in itself
15 * @author Oszkar Semerath
16 * 11 *
17 * @param <K> 12 * @param <K>
18 * @param <V> 13 * @param <V>
14 * @author Oszkar Semerath
19 */ 15 */
20public class VersionedMapImpl<K,V> implements VersionedMap<K,V>{ 16public class VersionedMapImpl<K, V> implements VersionedMap<K, V> {
21 protected final VersionedMapStoreImpl<K,V> store; 17 protected final VersionedMapStoreImpl<K, V> store;
22 18
23 protected final ContinousHashProvider<K> hashProvider; 19 protected final ContinousHashProvider<K> hashProvider;
20
24 protected final V defaultValue; 21 protected final V defaultValue;
25 protected Node<K,V> root; 22 protected Node<K, V> root;
26 23
27 private OldValueBox<V> oldValueBox = new OldValueBox<>(); 24 private final OldValueBox<V> oldValueBox = new OldValueBox<>();
28 25
29 public VersionedMapImpl( 26 public VersionedMapImpl(
30 VersionedMapStoreImpl<K,V> store, 27 VersionedMapStoreImpl<K, V> store,
31 ContinousHashProvider<K> hashProvider, 28 ContinousHashProvider<K> hashProvider,
32 V defaultValue) 29 V defaultValue) {
33 {
34 this.store = store; 30 this.store = store;
35 this.hashProvider = hashProvider; 31 this.hashProvider = hashProvider;
36 this.defaultValue = defaultValue; 32 this.defaultValue = defaultValue;
37 this.root = null; 33 this.root = null;
38 } 34 }
35
39 public VersionedMapImpl( 36 public VersionedMapImpl(
40 VersionedMapStoreImpl<K,V> store, 37 VersionedMapStoreImpl<K, V> store,
41 ContinousHashProvider<K> hashProvider, 38 ContinousHashProvider<K> hashProvider,
42 V defaultValue, Node<K,V> data) 39 V defaultValue, Node<K, V> data) {
43 {
44 this.store = store; 40 this.store = store;
45 this.hashProvider = hashProvider; 41 this.hashProvider = hashProvider;
46 this.defaultValue = defaultValue; 42 this.defaultValue = defaultValue;
47 this.root = data; 43 this.root = data;
48 } 44 }
49 45
50 public V getDefaultValue() { 46 public V getDefaultValue() {
51 return defaultValue; 47 return defaultValue;
52 } 48 }
49
53 public ContinousHashProvider<K> getHashProvider() { 50 public ContinousHashProvider<K> getHashProvider() {
54 return hashProvider; 51 return hashProvider;
55 } 52 }
53
56 @Override 54 @Override
57 public V put(K key, V value) { 55 public V put(K key, V value) {
58 if(root!=null) { 56 if (root != null) {
59 root = root.putValue(key, value, oldValueBox, hashProvider, defaultValue, hashProvider.getHash(key, 0), 0); 57 root = root.putValue(key, value, oldValueBox, hashProvider, defaultValue, hashProvider.getHash(key, 0), 0);
60 return oldValueBox.getOldValue(); 58 return oldValueBox.getOldValue();
61 } else { 59 } else {
@@ -63,39 +61,40 @@ public class VersionedMapImpl<K,V> implements VersionedMap<K,V>{
63 return defaultValue; 61 return defaultValue;
64 } 62 }
65 } 63 }
66 64
67 @Override 65 @Override
68 public void putAll(Cursor<K, V> cursor) { 66 public void putAll(Cursor<K, V> cursor) {
69 if(cursor.getDependingMaps().contains(this)) { 67 if (cursor.getDependingMaps().contains(this)) {
70 List<K> keys = new LinkedList<>(); 68 List<K> keys = new LinkedList<>();
71 List<V> values = new LinkedList<>(); 69 List<V> values = new LinkedList<>();
72 while(cursor.move()) { 70 while (cursor.move()) {
73 keys.add(cursor.getKey()); 71 keys.add(cursor.getKey());
74 values.add(cursor.getValue()); 72 values.add(cursor.getValue());
75 } 73 }
76 Iterator<K> keyIterator = keys.iterator(); 74 Iterator<K> keyIterator = keys.iterator();
77 Iterator<V> valueIterator = values.iterator(); 75 Iterator<V> valueIterator = values.iterator();
78 while(keyIterator.hasNext()) { 76 while (keyIterator.hasNext()) {
79 this.put(keyIterator.next(), valueIterator.next()); 77 this.put(keyIterator.next(), valueIterator.next());
80 } 78 }
81 } else { 79 } else {
82 while(cursor.move()) { 80 while (cursor.move()) {
83 this.put(cursor.getKey(), cursor.getValue()); 81 this.put(cursor.getKey(), cursor.getValue());
84 } 82 }
85 } 83 }
86 } 84 }
87 85
88 @Override 86 @Override
89 public V get(K key) { 87 public V get(K key) {
90 if(root!=null) { 88 if (root != null) {
91 return root.getValue(key, hashProvider, defaultValue, hashProvider.getHash(key, 0), 0); 89 return root.getValue(key, hashProvider, defaultValue, hashProvider.getHash(key, 0), 0);
92 } else { 90 } else {
93 return defaultValue; 91 return defaultValue;
94 } 92 }
95 } 93 }
94
96 @Override 95 @Override
97 public long getSize() { 96 public long getSize() {
98 if(root == null) { 97 if (root == null) {
99 return 0; 98 return 0;
100 } else { 99 } else {
101 return root.getSize(); 100 return root.getSize();
@@ -104,22 +103,24 @@ public class VersionedMapImpl<K,V> implements VersionedMap<K,V>{
104 103
105 @Override 104 @Override
106 public Cursor<K, V> getAll() { 105 public Cursor<K, V> getAll() {
107 return new MapCursor<>(this.root,this); 106 return new MapCursor<>(this.root, this);
108 } 107 }
108
109 @Override 109 @Override
110 public DiffCursor<K, V> getDiffCursor(long toVersion) { 110 public DiffCursor<K, V> getDiffCursor(long toVersion) {
111 Cursor<K, V> fromCursor = this.getAll(); 111 Cursor<K, V> fromCursor = this.getAll();
112 VersionedMap<K, V> toMap = this.store.createMap(toVersion); 112 VersionedMap<K, V> toMap = this.store.createMap(toVersion);
113 Cursor<K, V> toCursor = toMap.getAll(); 113 Cursor<K, V> toCursor = toMap.getAll();
114 return new MapDiffCursor<>(this.hashProvider,this.defaultValue, fromCursor, toCursor); 114 return new MapDiffCursor<>(this.hashProvider, this.defaultValue, fromCursor, toCursor);
115 115
116 } 116 }
117 117
118 118
119 @Override 119 @Override
120 public long commit() { 120 public long commit() {
121 return this.store.commit(root,this); 121 return this.store.commit(root, this);
122 } 122 }
123
123 public void setRoot(Node<K, V> root) { 124 public void setRoot(Node<K, V> root) {
124 this.root = root; 125 this.root = root;
125 } 126 }
@@ -128,44 +129,20 @@ public class VersionedMapImpl<K,V> implements VersionedMap<K,V>{
128 public void restore(long state) { 129 public void restore(long state) {
129 root = this.store.revert(state); 130 root = this.store.revert(state);
130 } 131 }
131 132
132 @Override
133 public int hashCode() {
134 final int prime = 31;
135 int result = 1;
136 result = prime * result + ((root == null) ? 0 : root.hashCode());
137 return result;
138 }
139
140 @Override
141 public boolean equals(Object obj) {
142 if (this == obj)
143 return true;
144 if (obj == null)
145 return false;
146 if (getClass() != obj.getClass())
147 return false;
148 VersionedMapImpl<?,?> other = (VersionedMapImpl<?,?>) obj;
149 if (root == null) {
150 if (other.root != null)
151 return false;
152 } else if (!root.equals(other.root))
153 return false;
154 return true;
155 }
156 public void prettyPrint() { 133 public void prettyPrint() {
157 StringBuilder s = new StringBuilder(); 134 StringBuilder s = new StringBuilder();
158 if(this.root != null) { 135 if (this.root != null) {
159 this.root.prettyPrint(s, 0, -1); 136 this.root.prettyPrint(s, 0, -1);
160 System.out.println(s.toString()); 137 System.out.println(s.toString());
161 } else { 138 } else {
162 System.out.println("empty tree"); 139 System.out.println("empty tree");
163 } 140 }
164 } 141 }
142
165 public void checkIntegrity() { 143 public void checkIntegrity() {
166 if(this.root != null) { 144 if (this.root != null) {
167 this.root.checkIntegrity(hashProvider, defaultValue, 0); 145 this.root.checkIntegrity(hashProvider, defaultValue, 0);
168 } 146 }
169 } 147 }
170
171} 148}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/Model.java b/subprojects/store/src/main/java/tools/refinery/store/model/Model.java
index a42d711a..69f57389 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/Model.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/Model.java
@@ -1,20 +1,24 @@
1package tools.refinery.store.model; 1package tools.refinery.store.model;
2 2
3import java.util.Set;
4
5import tools.refinery.store.map.Cursor; 3import tools.refinery.store.map.Cursor;
6import tools.refinery.store.map.Versioned; 4import tools.refinery.store.map.Versioned;
5import tools.refinery.store.model.representation.AnyDataRepresentation;
7import tools.refinery.store.model.representation.DataRepresentation; 6import tools.refinery.store.model.representation.DataRepresentation;
8 7
9public interface Model extends Versioned{ 8import java.util.Set;
10 @SuppressWarnings("squid:S1452") 9
11 Set<DataRepresentation<?, ?>> getDataRepresentations(); 10public interface Model extends Versioned {
12 11 Set<AnyDataRepresentation> getDataRepresentations();
13 <K,V> V get(DataRepresentation<K,V> representation, K key); 12
14 <K,V> Cursor<K,V> getAll(DataRepresentation<K,V> representation); 13 <K, V> V get(DataRepresentation<K, V> representation, K key);
15 <K,V> V put(DataRepresentation<K,V> representation, K key, V value); 14
16 <K,V> void putAll(DataRepresentation<K,V> representation, Cursor<K,V> cursor); 15 <K, V> Cursor<K, V> getAll(DataRepresentation<K, V> representation);
17 <K,V> long getSize(DataRepresentation<K,V> representation); 16
18 17 <K, V> V put(DataRepresentation<K, V> representation, K key, V value);
18
19 <K, V> void putAll(DataRepresentation<K, V> representation, Cursor<K, V> cursor);
20
21 long getSize(AnyDataRepresentation representation);
22
19 ModelDiffCursor getDiffCursor(long to); 23 ModelDiffCursor getDiffCursor(long to);
20} 24}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/ModelDiffCursor.java b/subprojects/store/src/main/java/tools/refinery/store/model/ModelDiffCursor.java
index 91990fa6..d5bb541b 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/ModelDiffCursor.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/ModelDiffCursor.java
@@ -1,26 +1,27 @@
1package tools.refinery.store.model; 1package tools.refinery.store.model;
2 2
3import java.util.Map;
4
5import tools.refinery.store.map.Cursor; 3import tools.refinery.store.map.Cursor;
6import tools.refinery.store.map.DiffCursor; 4import tools.refinery.store.map.DiffCursor;
5import tools.refinery.store.model.representation.AnyDataRepresentation;
7import tools.refinery.store.model.representation.DataRepresentation; 6import tools.refinery.store.model.representation.DataRepresentation;
8 7
8import java.util.Map;
9
9public class ModelDiffCursor { 10public class ModelDiffCursor {
10 final Map<DataRepresentation<?, ?>,DiffCursor<?,?>> diffcursors; 11 final Map<AnyDataRepresentation, DiffCursor<?, ?>> diffCursors;
11 12
12 public ModelDiffCursor(Map<DataRepresentation<?, ?>, DiffCursor<?, ?>> diffcursors) { 13 public ModelDiffCursor(Map<AnyDataRepresentation, DiffCursor<?, ?>> diffCursors) {
13 super(); 14 super();
14 this.diffcursors = diffcursors; 15 this.diffCursors = diffCursors;
15 } 16 }
16 17
17 @SuppressWarnings("unchecked") 18 @SuppressWarnings("unchecked")
18 public <K,V> DiffCursor<K,V> getCursor(DataRepresentation<K, V> representation) { 19 public <K, V> DiffCursor<K, V> getCursor(DataRepresentation<K, V> representation) {
19 Cursor<?, ?> cursor = diffcursors.get(representation); 20 Cursor<?, ?> cursor = diffCursors.get(representation);
20 if(cursor != null) { 21 if (cursor != null) {
21 return (DiffCursor<K, V>) cursor; 22 return (DiffCursor<K, V>) cursor;
22 } else { 23 } else {
23 throw new IllegalArgumentException("ModelCursor does not contain cursor for representation "+representation); 24 throw new IllegalArgumentException("ModelCursor does not contain cursor for representation " + representation);
24 } 25 }
25 } 26 }
26} 27}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java b/subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java
index 682a0e78..84b67765 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java
@@ -1,16 +1,17 @@
1package tools.refinery.store.model; 1package tools.refinery.store.model;
2 2
3import java.util.Set; 3import tools.refinery.store.model.representation.AnyDataRepresentation;
4 4
5import tools.refinery.store.model.representation.DataRepresentation; 5import java.util.Set;
6 6
7public interface ModelStore { 7public interface ModelStore {
8 @SuppressWarnings("squid:S1452") 8 Set<AnyDataRepresentation> getDataRepresentations();
9 Set<DataRepresentation<?, ?>> getDataRepresentations(); 9
10
11 Model createModel(); 10 Model createModel();
11
12 Model createModel(long state); 12 Model createModel(long state);
13 13
14 Set<Long> getStates(); 14 Set<Long> getStates();
15
15 ModelDiffCursor getDiffCursor(long from, long to); 16 ModelDiffCursor getDiffCursor(long from, long to);
16} \ No newline at end of file 17}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java b/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java
index d08cf0f8..2f73a0e5 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java
@@ -3,6 +3,7 @@ package tools.refinery.store.model;
3import tools.refinery.store.map.*; 3import tools.refinery.store.map.*;
4import tools.refinery.store.model.internal.ModelImpl; 4import tools.refinery.store.model.internal.ModelImpl;
5import tools.refinery.store.model.internal.SimilarRelationEquivalenceClass; 5import tools.refinery.store.model.internal.SimilarRelationEquivalenceClass;
6import tools.refinery.store.model.representation.AnyDataRepresentation;
6import tools.refinery.store.model.representation.AuxiliaryData; 7import tools.refinery.store.model.representation.AuxiliaryData;
7import tools.refinery.store.model.representation.DataRepresentation; 8import tools.refinery.store.model.representation.DataRepresentation;
8import tools.refinery.store.model.representation.Relation; 9import tools.refinery.store.model.representation.Relation;
@@ -13,26 +14,26 @@ import java.util.Map.Entry;
13 14
14public class ModelStoreImpl implements ModelStore { 15public class ModelStoreImpl implements ModelStore {
15 16
16 private final Map<DataRepresentation<?, ?>, VersionedMapStore<?, ?>> stores; 17 private final Map<AnyDataRepresentation, VersionedMapStore<?, ?>> stores;
17 18
18 public ModelStoreImpl(Set<DataRepresentation<?, ?>> dataRepresentations) { 19 public ModelStoreImpl(Set<AnyDataRepresentation> dataRepresentations) {
19 stores = initStores(dataRepresentations); 20 stores = initStores(dataRepresentations);
20 } 21 }
21 22
22 private Map<DataRepresentation<?, ?>, VersionedMapStore<?, ?>> initStores( 23 private Map<AnyDataRepresentation, VersionedMapStore<?, ?>> initStores(
23 Set<DataRepresentation<?, ?>> dataRepresentations) { 24 Set<AnyDataRepresentation> dataRepresentations) {
24 Map<DataRepresentation<?, ?>, VersionedMapStore<?, ?>> result = new HashMap<>(); 25 Map<AnyDataRepresentation, VersionedMapStore<?, ?>> result = new HashMap<>();
25 26
26 Map<SimilarRelationEquivalenceClass, List<Relation<?>>> symbolRepresentationsPerHashPerArity = new HashMap<>(); 27 Map<SimilarRelationEquivalenceClass, List<Relation<?>>> symbolRepresentationsPerHashPerArity = new HashMap<>();
27 28
28 for (DataRepresentation<?, ?> dataRepresentation : dataRepresentations) { 29 for (AnyDataRepresentation dataRepresentation : dataRepresentations) {
29 if (dataRepresentation instanceof Relation<?> symbolRepresentation) { 30 if (dataRepresentation instanceof Relation<?> symbolRepresentation) {
30 addOrCreate(symbolRepresentationsPerHashPerArity, 31 addOrCreate(symbolRepresentationsPerHashPerArity,
31 new SimilarRelationEquivalenceClass(symbolRepresentation), symbolRepresentation); 32 new SimilarRelationEquivalenceClass(symbolRepresentation), symbolRepresentation);
32 } else if (dataRepresentation instanceof AuxiliaryData<?, ?>) { 33 } else if (dataRepresentation instanceof AuxiliaryData<?, ?> auxiliaryData) {
33 VersionedMapStoreImpl<?, ?> store = new VersionedMapStoreImpl<>(dataRepresentation.getHashProvider(), 34 VersionedMapStoreImpl<?, ?> store = new VersionedMapStoreImpl<>(auxiliaryData.getHashProvider(),
34 dataRepresentation.getDefaultValue()); 35 auxiliaryData.getDefaultValue());
35 result.put(dataRepresentation, store); 36 result.put(auxiliaryData, store);
36 } else { 37 } else {
37 throw new UnsupportedOperationException( 38 throw new UnsupportedOperationException(
38 "Model store does not have strategy to use " + dataRepresentation.getClass() + "!"); 39 "Model store does not have strategy to use " + dataRepresentation.getClass() + "!");
@@ -45,7 +46,7 @@ public class ModelStoreImpl implements ModelStore {
45 return result; 46 return result;
46 } 47 }
47 48
48 private void initRepresentationGroup(Map<DataRepresentation<?, ?>, VersionedMapStore<?, ?>> result, 49 private void initRepresentationGroup(Map<AnyDataRepresentation, VersionedMapStore<?, ?>> result,
49 List<Relation<?>> symbolGroup) { 50 List<Relation<?>> symbolGroup) {
50 final ContinousHashProvider<Tuple> hashProvider = symbolGroup.get(0).getHashProvider(); 51 final ContinousHashProvider<Tuple> hashProvider = symbolGroup.get(0).getHashProvider();
51 final Object defaultValue = symbolGroup.get(0).getDefaultValue(); 52 final Object defaultValue = symbolGroup.get(0).getDefaultValue();
@@ -70,14 +71,14 @@ public class ModelStoreImpl implements ModelStore {
70 } 71 }
71 72
72 @Override 73 @Override
73 public Set<DataRepresentation<?, ?>> getDataRepresentations() { 74 public Set<AnyDataRepresentation> getDataRepresentations() {
74 return this.stores.keySet(); 75 return this.stores.keySet();
75 } 76 }
76 77
77 @Override 78 @Override
78 public ModelImpl createModel() { 79 public ModelImpl createModel() {
79 Map<DataRepresentation<?, ?>, VersionedMap<?, ?>> maps = new HashMap<>(); 80 Map<AnyDataRepresentation, VersionedMap<?, ?>> maps = new HashMap<>();
80 for (Entry<DataRepresentation<?, ?>, VersionedMapStore<?, ?>> entry : this.stores.entrySet()) { 81 for (var entry : this.stores.entrySet()) {
81 maps.put(entry.getKey(), entry.getValue().createMap()); 82 maps.put(entry.getKey(), entry.getValue().createMap());
82 } 83 }
83 return new ModelImpl(this, maps); 84 return new ModelImpl(this, maps);
@@ -85,8 +86,8 @@ public class ModelStoreImpl implements ModelStore {
85 86
86 @Override 87 @Override
87 public synchronized ModelImpl createModel(long state) { 88 public synchronized ModelImpl createModel(long state) {
88 Map<DataRepresentation<?, ?>, VersionedMap<?, ?>> maps = new HashMap<>(); 89 Map<AnyDataRepresentation, VersionedMap<?, ?>> maps = new HashMap<>();
89 for (Entry<DataRepresentation<?, ?>, VersionedMapStore<?, ?>> entry : this.stores.entrySet()) { 90 for (var entry : this.stores.entrySet()) {
90 maps.put(entry.getKey(), entry.getValue().createMap(state)); 91 maps.put(entry.getKey(), entry.getValue().createMap(state));
91 } 92 }
92 return new ModelImpl(this, maps); 93 return new ModelImpl(this, maps);
@@ -103,10 +104,10 @@ public class ModelStoreImpl implements ModelStore {
103 104
104 @Override 105 @Override
105 public synchronized ModelDiffCursor getDiffCursor(long from, long to) { 106 public synchronized ModelDiffCursor getDiffCursor(long from, long to) {
106 Map<DataRepresentation<?, ?>, DiffCursor<?, ?>> diffcursors = new HashMap<>(); 107 Map<AnyDataRepresentation, DiffCursor<?, ?>> diffcursors = new HashMap<>();
107 for (Entry<DataRepresentation<?, ?>, VersionedMapStore<?, ?>> entry : stores.entrySet()) { 108 for (var entry : stores.entrySet()) {
108 DataRepresentation<?, ?> representation = entry.getKey(); 109 var representation = entry.getKey();
109 DiffCursor<?, ?> diffCursor = entry.getValue().getDiffCursor(from, to); 110 var diffCursor = entry.getValue().getDiffCursor(from, to);
110 diffcursors.put(representation, diffCursor); 111 diffcursors.put(representation, diffCursor);
111 } 112 }
112 return new ModelDiffCursor(diffcursors); 113 return new ModelDiffCursor(diffcursors);
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java b/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java
index 2a5f2925..795a891b 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java
@@ -1,9 +1,5 @@
1package tools.refinery.store.model.internal; 1package tools.refinery.store.model.internal;
2 2
3import java.util.HashMap;
4import java.util.Map;
5import java.util.Set;
6
7import tools.refinery.store.map.ContinousHashProvider; 3import tools.refinery.store.map.ContinousHashProvider;
8import tools.refinery.store.map.Cursor; 4import tools.refinery.store.map.Cursor;
9import tools.refinery.store.map.DiffCursor; 5import tools.refinery.store.map.DiffCursor;
@@ -12,31 +8,41 @@ import tools.refinery.store.map.internal.MapDiffCursor;
12import tools.refinery.store.model.Model; 8import tools.refinery.store.model.Model;
13import tools.refinery.store.model.ModelDiffCursor; 9import tools.refinery.store.model.ModelDiffCursor;
14import tools.refinery.store.model.ModelStore; 10import tools.refinery.store.model.ModelStore;
11import tools.refinery.store.model.representation.AnyDataRepresentation;
15import tools.refinery.store.model.representation.DataRepresentation; 12import tools.refinery.store.model.representation.DataRepresentation;
16 13
14import java.util.HashMap;
15import java.util.Map;
16import java.util.Set;
17
17public class ModelImpl implements Model { 18public class ModelImpl implements Model {
18 private final ModelStore store; 19 private final ModelStore store;
19 private final Map<DataRepresentation<?, ?>, VersionedMap<?, ?>> maps;
20 20
21 public ModelImpl(ModelStore store, Map<DataRepresentation<?, ?>, VersionedMap<?, ?>> maps) { 21 private final Map<AnyDataRepresentation, VersionedMap<?, ?>> maps;
22
23 public ModelImpl(ModelStore store, Map<AnyDataRepresentation, VersionedMap<?, ?>> maps) {
22 this.store = store; 24 this.store = store;
23 this.maps = maps; 25 this.maps = maps;
24 } 26 }
25 27
26 @Override 28 @Override
27 public Set<DataRepresentation<?, ?>> getDataRepresentations() { 29 public Set<AnyDataRepresentation> getDataRepresentations() {
28 return maps.keySet(); 30 return maps.keySet();
29 } 31 }
30 32
31 @SuppressWarnings("unchecked") 33 private VersionedMap<?, ?> getMap(AnyDataRepresentation representation) {
32 private <K, V> VersionedMap<K, V> getMap(DataRepresentation<K, V> representation) {
33 if (maps.containsKey(representation)) { 34 if (maps.containsKey(representation)) {
34 return (VersionedMap<K, V>) maps.get(representation); 35 return maps.get(representation);
35 } else { 36 } else {
36 throw new IllegalArgumentException("Model does have representation " + representation); 37 throw new IllegalArgumentException("Model does have representation " + representation);
37 } 38 }
38 } 39 }
39 40
41 @SuppressWarnings("unchecked")
42 private <K, V> VersionedMap<K, V> getMap(DataRepresentation<K, V> representation) {
43 return (VersionedMap<K, V>) maps.get(representation);
44 }
45
40 private <K, V> VersionedMap<K, V> getMapValidateKey(DataRepresentation<K, V> representation, K key) { 46 private <K, V> VersionedMap<K, V> getMapValidateKey(DataRepresentation<K, V> representation, K key) {
41 if (representation.isValidKey(key)) { 47 if (representation.isValidKey(key)) {
42 return getMap(representation); 48 return getMap(representation);
@@ -67,17 +73,18 @@ public class ModelImpl implements Model {
67 } 73 }
68 74
69 @Override 75 @Override
70 public <K, V> long getSize(DataRepresentation<K, V> representation) { 76 public long getSize(AnyDataRepresentation representation) {
71 return getMap(representation).getSize(); 77 return getMap(representation).getSize();
72 } 78 }
73 79
74 @Override 80 @Override
75 public ModelDiffCursor getDiffCursor(long to) { 81 public ModelDiffCursor getDiffCursor(long to) {
76 Model toModel = store.createModel(to); 82 Model toModel = store.createModel(to);
77 Map<DataRepresentation<?, ?>, DiffCursor<?, ?>> diffCursors = new HashMap<>(); 83 Map<AnyDataRepresentation, DiffCursor<?, ?>> diffCursors = new HashMap<>();
78 for (DataRepresentation<?, ?> representation : this.maps.keySet()) { 84 for (AnyDataRepresentation anyDataRepresentation : this.maps.keySet()) {
79 MapDiffCursor<?, ?> diffCursor = constructDiffCursor(toModel, representation); 85 var dataRepresentation = (DataRepresentation<?, ?>) anyDataRepresentation;
80 diffCursors.put(representation, diffCursor); 86 MapDiffCursor<?, ?> diffCursor = constructDiffCursor(toModel, dataRepresentation);
87 diffCursors.put(dataRepresentation, diffCursor);
81 } 88 }
82 return new ModelDiffCursor(diffCursors); 89 return new ModelDiffCursor(diffCursors);
83 } 90 }
@@ -113,12 +120,12 @@ public class ModelImpl implements Model {
113 120
114 @Override 121 @Override
115 public void restore(long state) { 122 public void restore(long state) {
116 if(store.getStates().contains(state)) { 123 if (store.getStates().contains(state)) {
117 for (VersionedMap<?, ?> map : maps.values()) { 124 for (VersionedMap<?, ?> map : maps.values()) {
118 map.restore(state); 125 map.restore(state);
119 } 126 }
120 } else { 127 } else {
121 throw new IllegalArgumentException("Map does not contain state "+state+"!"); 128 throw new IllegalArgumentException("Map does not contain state " + state + "!");
122 } 129 }
123 } 130 }
124} 131}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/internal/SimilarRelationEquivalenceClass.java b/subprojects/store/src/main/java/tools/refinery/store/model/internal/SimilarRelationEquivalenceClass.java
index 9939f17e..79e4c9f9 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/internal/SimilarRelationEquivalenceClass.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/internal/SimilarRelationEquivalenceClass.java
@@ -1,31 +1,33 @@
1package tools.refinery.store.model.internal; 1package tools.refinery.store.model.internal;
2 2
3import java.util.Objects;
4
5import tools.refinery.store.map.ContinousHashProvider; 3import tools.refinery.store.map.ContinousHashProvider;
6import tools.refinery.store.tuple.Tuple;
7import tools.refinery.store.model.representation.Relation; 4import tools.refinery.store.model.representation.Relation;
5import tools.refinery.store.tuple.Tuple;
6
7import java.util.Objects;
8 8
9public class SimilarRelationEquivalenceClass { 9public class SimilarRelationEquivalenceClass {
10 final ContinousHashProvider<Tuple> hashProvider; 10 final ContinousHashProvider<Tuple> hashProvider;
11 final Object defaultValue; 11 final Object defaultValue;
12 final int arity; 12 final int arity;
13
13 public SimilarRelationEquivalenceClass(Relation<?> representation) { 14 public SimilarRelationEquivalenceClass(Relation<?> representation) {
14 this.hashProvider = representation.getHashProvider(); 15 this.hashProvider = representation.getHashProvider();
15 this.defaultValue = representation.getDefaultValue(); 16 this.defaultValue = representation.getDefaultValue();
16 this.arity = representation.getArity(); 17 this.arity = representation.getArity();
17 } 18 }
19
18 @Override 20 @Override
19 public int hashCode() { 21 public int hashCode() {
20 return Objects.hash(arity, defaultValue, hashProvider); 22 return Objects.hash(arity, defaultValue, hashProvider);
21 } 23 }
24
22 @Override 25 @Override
23 public boolean equals(Object obj) { 26 public boolean equals(Object obj) {
24 if (this == obj) 27 if (this == obj)
25 return true; 28 return true;
26 if (!(obj instanceof SimilarRelationEquivalenceClass)) 29 if (!(obj instanceof SimilarRelationEquivalenceClass other))
27 return false; 30 return false;
28 SimilarRelationEquivalenceClass other = (SimilarRelationEquivalenceClass) obj;
29 return arity == other.arity && Objects.equals(defaultValue, other.defaultValue) 31 return arity == other.arity && Objects.equals(defaultValue, other.defaultValue)
30 && Objects.equals(hashProvider, other.hashProvider); 32 && Objects.equals(hashProvider, other.hashProvider);
31 } 33 }
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyAuxiliaryData.java b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyAuxiliaryData.java
new file mode 100644
index 00000000..951952e5
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyAuxiliaryData.java
@@ -0,0 +1,4 @@
1package tools.refinery.store.model.representation;
2
3public sealed interface AnyAuxiliaryData extends AnyDataRepresentation permits AuxiliaryData {
4}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyDataRepresentation.java b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyDataRepresentation.java
new file mode 100644
index 00000000..ea74a625
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyDataRepresentation.java
@@ -0,0 +1,9 @@
1package tools.refinery.store.model.representation;
2
3public sealed interface AnyDataRepresentation permits DataRepresentation, AnyRelation, AnyAuxiliaryData {
4 String getName();
5
6 Class<?> getKeyType();
7
8 Class<?> getValueType();
9}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyRelation.java b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyRelation.java
new file mode 100644
index 00000000..1d698c28
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyRelation.java
@@ -0,0 +1,9 @@
1package tools.refinery.store.model.representation;
2
3import tools.refinery.store.model.RelationLike;
4import tools.refinery.store.tuple.Tuple;
5
6public sealed interface AnyRelation extends AnyDataRepresentation, RelationLike permits Relation {
7 @Override
8 Class<Tuple> getKeyType();
9}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/representation/AuxiliaryData.java b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AuxiliaryData.java
index 18c38151..dad1ccf4 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/representation/AuxiliaryData.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AuxiliaryData.java
@@ -2,7 +2,7 @@ package tools.refinery.store.model.representation;
2 2
3import tools.refinery.store.map.ContinousHashProvider; 3import tools.refinery.store.map.ContinousHashProvider;
4 4
5public final class AuxiliaryData<K, V> extends DataRepresentation<K, V> { 5public final class AuxiliaryData<K, V> extends DataRepresentation<K, V> implements AnyAuxiliaryData {
6 private final ContinousHashProvider<K> hashProvider; 6 private final ContinousHashProvider<K> hashProvider;
7 7
8 public AuxiliaryData(String name, Class<K> keyType, ContinousHashProvider<K> hashProvider, Class<V> valueType, 8 public AuxiliaryData(String name, Class<K> keyType, ContinousHashProvider<K> hashProvider, Class<V> valueType,
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/representation/DataRepresentation.java b/subprojects/store/src/main/java/tools/refinery/store/model/representation/DataRepresentation.java
index 61c6291b..2bf498b9 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/representation/DataRepresentation.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/representation/DataRepresentation.java
@@ -2,7 +2,7 @@ package tools.refinery.store.model.representation;
2 2
3import tools.refinery.store.map.ContinousHashProvider; 3import tools.refinery.store.map.ContinousHashProvider;
4 4
5public abstract sealed class DataRepresentation<K, V> permits Relation, AuxiliaryData { 5public abstract sealed class DataRepresentation<K, V> implements AnyDataRepresentation permits Relation, AuxiliaryData {
6 private final String name; 6 private final String name;
7 7
8 private final V defaultValue; 8 private final V defaultValue;
@@ -18,6 +18,7 @@ public abstract sealed class DataRepresentation<K, V> permits Relation, Auxiliar
18 this.valueType = valueType; 18 this.valueType = valueType;
19 } 19 }
20 20
21 @Override
21 public String getName() { 22 public String getName() {
22 return name; 23 return name;
23 } 24 }
@@ -30,10 +31,12 @@ public abstract sealed class DataRepresentation<K, V> permits Relation, Auxiliar
30 return defaultValue; 31 return defaultValue;
31 } 32 }
32 33
34 @Override
33 public Class<K> getKeyType() { 35 public Class<K> getKeyType() {
34 return keyType; 36 return keyType;
35 } 37 }
36 38
39 @Override
37 public Class<V> getValueType() { 40 public Class<V> getValueType() {
38 return valueType; 41 return valueType;
39 } 42 }
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java b/subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java
index cc32257c..47a07536 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java
@@ -1,11 +1,10 @@
1package tools.refinery.store.model.representation; 1package tools.refinery.store.model.representation;
2 2
3import tools.refinery.store.map.ContinousHashProvider; 3import tools.refinery.store.map.ContinousHashProvider;
4import tools.refinery.store.model.RelationLike;
5import tools.refinery.store.model.TupleHashProvider; 4import tools.refinery.store.model.TupleHashProvider;
6import tools.refinery.store.tuple.Tuple; 5import tools.refinery.store.tuple.Tuple;
7 6
8public final class Relation<D> extends DataRepresentation<Tuple, D> implements RelationLike { 7public final class Relation<D> extends DataRepresentation<Tuple, D> implements AnyRelation {
9 private final int arity; 8 private final int arity;
10 9
11 public Relation(String name, int arity, Class<D> valueType, D defaultValue) { 10 public Relation(String name, int arity, Class<D> valueType, D defaultValue) {
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java
index 41f47e64..3a69f3a4 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java
@@ -1,17 +1,15 @@
1package tools.refinery.store.query; 1package tools.refinery.store.query;
2 2
3import tools.refinery.store.model.ModelStore; 3import tools.refinery.store.model.ModelStore;
4import tools.refinery.store.model.representation.DataRepresentation; 4import tools.refinery.store.model.representation.AnyDataRepresentation;
5import tools.refinery.store.query.view.RelationView; 5import tools.refinery.store.query.view.AnyRelationView;
6 6
7import java.util.Set; 7import java.util.Set;
8 8
9public interface QueryableModelStore extends ModelStore { 9public interface QueryableModelStore extends ModelStore {
10 @SuppressWarnings("squid:S1452") 10 Set<AnyDataRepresentation> getDataRepresentations();
11 Set<DataRepresentation<?, ?>> getDataRepresentations();
12 11
13 @SuppressWarnings("squid:S1452") 12 Set<AnyRelationView> getViews();
14 Set<RelationView<?>> getViews();
15 13
16 Set<DNF> getPredicates(); 14 Set<DNF> getPredicates();
17 15
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/atom/Modality.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/Modality.java
index bc107b76..e389f563 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/atom/Modality.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/Modality.java
@@ -7,6 +7,14 @@ public enum Modality {
7 MAY, 7 MAY,
8 CURRENT; 8 CURRENT;
9 9
10 public Modality negate() {
11 return switch(this) {
12 case MUST -> MAY;
13 case MAY -> MUST;
14 case CURRENT -> CURRENT;
15 };
16 }
17
10 @Override 18 @Override
11 public String toString() { 19 public String toString() {
12 return name().toLowerCase(Locale.ROOT); 20 return name().toLowerCase(Locale.ROOT);
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/atom/RelationViewAtom.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/RelationViewAtom.java
index 762a41f1..cf836541 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/atom/RelationViewAtom.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/RelationViewAtom.java
@@ -1,17 +1,17 @@
1package tools.refinery.store.query.atom; 1package tools.refinery.store.query.atom;
2 2
3import tools.refinery.store.query.Variable; 3import tools.refinery.store.query.Variable;
4import tools.refinery.store.query.view.RelationView; 4import tools.refinery.store.query.view.AnyRelationView;
5 5
6import java.util.List; 6import java.util.List;
7import java.util.Objects; 7import java.util.Objects;
8 8
9public final class RelationViewAtom extends AbstractSubstitutionAtom<RelationView<?>> { 9public final class RelationViewAtom extends AbstractSubstitutionAtom<AnyRelationView> {
10 public RelationViewAtom(RelationView<?> target, List<Variable> substitution) { 10 public RelationViewAtom(AnyRelationView target, List<Variable> substitution) {
11 super(target, substitution); 11 super(target, substitution);
12 } 12 }
13 13
14 public RelationViewAtom(RelationView<?> target, Variable... substitution) { 14 public RelationViewAtom(AnyRelationView target, Variable... substitution) {
15 this(target, List.of(substitution)); 15 this(target, List.of(substitution));
16 } 16 }
17 17
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/AnyRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/AnyRelationView.java
new file mode 100644
index 00000000..df5e0d72
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/AnyRelationView.java
@@ -0,0 +1,13 @@
1package tools.refinery.store.query.view;
2
3import tools.refinery.store.model.Model;
4import tools.refinery.store.model.RelationLike;
5import tools.refinery.store.model.representation.AnyRelation;
6
7public sealed interface AnyRelationView extends RelationLike permits RelationView {
8 AnyRelation getRepresentation();
9
10 boolean get(Model model, Object[] tuple);
11
12 Iterable<Object[]> getAll(Model model);
13}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java
index 3b639979..5b892cc6 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java
@@ -3,6 +3,7 @@ package tools.refinery.store.query.view;
3import tools.refinery.store.tuple.Tuple; 3import tools.refinery.store.tuple.Tuple;
4import tools.refinery.store.model.representation.Relation; 4import tools.refinery.store.model.representation.Relation;
5 5
6import java.util.Objects;
6import java.util.function.BiPredicate; 7import java.util.function.BiPredicate;
7import java.util.function.Predicate; 8import java.util.function.Predicate;
8 9
@@ -31,4 +32,18 @@ public class FilteredRelationView<D> extends AbstractFilteredRelationView<D> {
31 public boolean filter(Tuple key, D value) { 32 public boolean filter(Tuple key, D value) {
32 return this.predicate.test(key, value); 33 return this.predicate.test(key, value);
33 } 34 }
35
36 @Override
37 public boolean equals(Object o) {
38 if (this == o) return true;
39 if (o == null || getClass() != o.getClass()) return false;
40 if (!super.equals(o)) return false;
41 FilteredRelationView<?> that = (FilteredRelationView<?>) o;
42 return Objects.equals(predicate, that.predicate);
43 }
44
45 @Override
46 public int hashCode() {
47 return Objects.hash(super.hashCode(), predicate);
48 }
34} 49}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java
index c88af5a4..f7e7d28a 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java
@@ -3,6 +3,8 @@ package tools.refinery.store.query.view;
3import tools.refinery.store.tuple.Tuple; 3import tools.refinery.store.tuple.Tuple;
4import tools.refinery.store.model.representation.Relation; 4import tools.refinery.store.model.representation.Relation;
5 5
6import java.util.Objects;
7
6public class KeyOnlyRelationView extends AbstractFilteredRelationView<Boolean> { 8public class KeyOnlyRelationView extends AbstractFilteredRelationView<Boolean> {
7 public static final String VIEW_NAME = "key"; 9 public static final String VIEW_NAME = "key";
8 10
@@ -17,4 +19,18 @@ public class KeyOnlyRelationView extends AbstractFilteredRelationView<Boolean> {
17 public boolean filter(Tuple key, Boolean value) { 19 public boolean filter(Tuple key, Boolean value) {
18 return !value.equals(defaultValue); 20 return !value.equals(defaultValue);
19 } 21 }
22
23 @Override
24 public boolean equals(Object o) {
25 if (this == o) return true;
26 if (o == null || getClass() != o.getClass()) return false;
27 if (!super.equals(o)) return false;
28 KeyOnlyRelationView that = (KeyOnlyRelationView) o;
29 return Objects.equals(defaultValue, that.defaultValue);
30 }
31
32 @Override
33 public int hashCode() {
34 return Objects.hash(super.hashCode(), defaultValue);
35 }
20} 36}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java
index 96f8584a..1224076c 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java
@@ -2,9 +2,8 @@ package tools.refinery.store.query.view;
2 2
3import tools.refinery.store.map.CursorAsIterator; 3import tools.refinery.store.map.CursorAsIterator;
4import tools.refinery.store.model.Model; 4import tools.refinery.store.model.Model;
5import tools.refinery.store.model.RelationLike;
6import tools.refinery.store.tuple.Tuple;
7import tools.refinery.store.model.representation.Relation; 5import tools.refinery.store.model.representation.Relation;
6import tools.refinery.store.tuple.Tuple;
8 7
9import java.util.Objects; 8import java.util.Objects;
10import java.util.UUID; 9import java.util.UUID;
@@ -15,7 +14,7 @@ import java.util.UUID;
15 * @param <D> 14 * @param <D>
16 * @author Oszkar Semerath 15 * @author Oszkar Semerath
17 */ 16 */
18public abstract class RelationView<D> implements RelationLike { 17public abstract non-sealed class RelationView<D> implements AnyRelationView {
19 private final Relation<D> representation; 18 private final Relation<D> representation;
20 19
21 private final String name; 20 private final String name;
@@ -29,6 +28,7 @@ public abstract class RelationView<D> implements RelationLike {
29 this(representation, UUID.randomUUID().toString()); 28 this(representation, UUID.randomUUID().toString());
30 } 29 }
31 30
31 @Override
32 public Relation<D> getRepresentation() { 32 public Relation<D> getRepresentation() {
33 return representation; 33 return representation;
34 } 34 }
@@ -42,28 +42,21 @@ public abstract class RelationView<D> implements RelationLike {
42 42
43 public abstract Object[] forwardMap(Tuple key, D value); 43 public abstract Object[] forwardMap(Tuple key, D value);
44 44
45 public abstract boolean get(Model model, Object[] tuple); 45 @Override
46
47 public Iterable<Object[]> getAll(Model model) { 46 public Iterable<Object[]> getAll(Model model) {
48 return (() -> new CursorAsIterator<>(model.getAll(representation), this::forwardMap, this::filter)); 47 return (() -> new CursorAsIterator<>(model.getAll(representation), this::forwardMap, this::filter));
49 } 48 }
50 49
51 @Override 50 @Override
52 public int hashCode() { 51 public boolean equals(Object o) {
53 final int prime = 31; 52 if (this == o) return true;
54 int result = 1; 53 if (o == null || getClass() != o.getClass()) return false;
55 result = prime * result + Objects.hash(representation); 54 RelationView<?> that = (RelationView<?>) o;
56 return result; 55 return Objects.equals(representation, that.representation) && Objects.equals(name, that.name);
57 } 56 }
58 57
59 @Override 58 @Override
60 public boolean equals(Object obj) { 59 public int hashCode() {
61 if (this == obj) 60 return Objects.hash(representation, name);
62 return true;
63 if (!(obj instanceof RelationView))
64 return false;
65 @SuppressWarnings("unchecked")
66 RelationView<D> other = ((RelationView<D>) obj);
67 return Objects.equals(representation, other.representation);
68 } 61 }
69} 62}
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/ContentEqualsFuzzTest.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/ContentEqualsFuzzTest.java
index 263cb2cd..d7f77d1a 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/ContentEqualsFuzzTest.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/ContentEqualsFuzzTest.java
@@ -1,30 +1,25 @@
1package tools.refinery.store.map.tests.fuzz; 1package tools.refinery.store.map.tests.fuzz;
2 2
3import static org.junit.jupiter.api.Assertions.assertEquals;
4import static org.junit.jupiter.api.Assertions.fail;
5
6import java.util.AbstractMap.SimpleEntry;
7import java.util.Collections;
8import java.util.LinkedList;
9import java.util.List;
10import java.util.Random;
11import java.util.stream.Stream;
12
13import org.junit.jupiter.api.Tag; 3import org.junit.jupiter.api.Tag;
14import org.junit.jupiter.api.Timeout; 4import org.junit.jupiter.api.Timeout;
15import org.junit.jupiter.params.ParameterizedTest; 5import org.junit.jupiter.params.ParameterizedTest;
16import org.junit.jupiter.params.provider.Arguments; 6import org.junit.jupiter.params.provider.Arguments;
17import org.junit.jupiter.params.provider.MethodSource; 7import org.junit.jupiter.params.provider.MethodSource;
18 8import tools.refinery.store.map.*;
19import tools.refinery.store.map.ContinousHashProvider;
20import tools.refinery.store.map.Cursor;
21import tools.refinery.store.map.VersionedMap;
22import tools.refinery.store.map.VersionedMapStore;
23import tools.refinery.store.map.VersionedMapStoreImpl;
24import tools.refinery.store.map.internal.VersionedMapImpl; 9import tools.refinery.store.map.internal.VersionedMapImpl;
25import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; 10import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils;
26import tools.refinery.store.map.tests.utils.MapTestEnvironment; 11import tools.refinery.store.map.tests.utils.MapTestEnvironment;
27 12
13import java.util.AbstractMap.SimpleEntry;
14import java.util.Collections;
15import java.util.LinkedList;
16import java.util.List;
17import java.util.Random;
18import java.util.stream.Stream;
19
20import static org.junit.jupiter.api.Assertions.assertEquals;
21import static org.junit.jupiter.api.Assertions.fail;
22
28class ContentEqualsFuzzTest { 23class ContentEqualsFuzzTest {
29 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue, int commitFrequency, 24 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue, int commitFrequency,
30 boolean evilHash) { 25 boolean evilHash) {
@@ -37,10 +32,9 @@ class ContentEqualsFuzzTest {
37 } 32 }
38 33
39 private void iterativeRandomPutsAndCommitsThenCompare(String scenario, ContinousHashProvider<Integer> chp, int steps, int maxKey, String[] values, Random r, int commitFrequency) { 34 private void iterativeRandomPutsAndCommitsThenCompare(String scenario, ContinousHashProvider<Integer> chp, int steps, int maxKey, String[] values, Random r, int commitFrequency) {
40
41 VersionedMapStore<Integer, String> store1 = new VersionedMapStoreImpl<Integer, String>(chp, values[0]); 35 VersionedMapStore<Integer, String> store1 = new VersionedMapStoreImpl<Integer, String>(chp, values[0]);
42 VersionedMap<Integer, String> sut1 = store1.createMap(); 36 VersionedMap<Integer, String> sut1 = store1.createMap();
43 37
44 // Fill one map 38 // Fill one map
45 for (int i = 0; i < steps; i++) { 39 for (int i = 0; i < steps; i++) {
46 int index1 = i + 1; 40 int index1 = i + 1;
@@ -57,17 +51,17 @@ class ContentEqualsFuzzTest {
57 sut1.commit(); 51 sut1.commit();
58 } 52 }
59 } 53 }
60 54
61 // Get the content of the first map 55 // Get the content of the first map
62 List<SimpleEntry<Integer, String>> content = new LinkedList<>(); 56 List<SimpleEntry<Integer, String>> content = new LinkedList<>();
63 Cursor<Integer, String> cursor = sut1.getAll(); 57 Cursor<Integer, String> cursor = sut1.getAll();
64 while (cursor.move()) { 58 while (cursor.move()) {
65 content.add(new SimpleEntry<>(cursor.getKey(), cursor.getValue())); 59 content.add(new SimpleEntry<>(cursor.getKey(), cursor.getValue()));
66 } 60 }
67 61
68 // Randomize the order of the content 62 // Randomize the order of the content
69 Collections.shuffle(content, r); 63 Collections.shuffle(content, r);
70 64
71 VersionedMapStore<Integer, String> store2 = new VersionedMapStoreImpl<Integer, String>(chp, values[0]); 65 VersionedMapStore<Integer, String> store2 = new VersionedMapStoreImpl<Integer, String>(chp, values[0]);
72 VersionedMap<Integer, String> sut2 = store2.createMap(); 66 VersionedMap<Integer, String> sut2 = store2.createMap();
73 int index2 = 1; 67 int index2 = 1;
@@ -76,18 +70,16 @@ class ContentEqualsFuzzTest {
76 if(index2++%commitFrequency == 0) 70 if(index2++%commitFrequency == 0)
77 sut2.commit(); 71 sut2.commit();
78 } 72 }
79 73
80 // Check the integrity of the maps 74 // Check the integrity of the maps
81 ((VersionedMapImpl<Integer,String>) sut1).checkIntegrity(); 75 ((VersionedMapImpl<Integer,String>) sut1).checkIntegrity();
82 ((VersionedMapImpl<Integer,String>) sut2).checkIntegrity(); 76 ((VersionedMapImpl<Integer,String>) sut2).checkIntegrity();
83 77
84// // Compare the two maps 78// // Compare the two maps
85 // By size 79 // By size
86 assertEquals(sut1.getSize(), content.size()); 80 assertEquals(sut1.getSize(), content.size());
87 assertEquals(sut2.getSize(), content.size()); 81 assertEquals(sut2.getSize(), content.size());
88 82
89
90
91 // By cursors 83 // By cursors
92 Cursor<Integer, String> cursor1 = sut1.getAll(); 84 Cursor<Integer, String> cursor1 = sut1.getAll();
93 Cursor<Integer, String> cursor2 = sut2.getAll(); 85 Cursor<Integer, String> cursor2 = sut2.getAll();
@@ -99,16 +91,10 @@ class ContentEqualsFuzzTest {
99 assertEquals(canMove1, canMove2, scenario + ":" + index3 +" Cursors stopped at different times!"); 91 assertEquals(canMove1, canMove2, scenario + ":" + index3 +" Cursors stopped at different times!");
100 assertEquals(cursor1.getKey(), cursor2.getKey(), scenario + ":" + index3 +" Cursors have different keys!"); 92 assertEquals(cursor1.getKey(), cursor2.getKey(), scenario + ":" + index3 +" Cursors have different keys!");
101 assertEquals(cursor1.getValue(), cursor2.getValue(), scenario + ":" + index3 +" Cursors have different values!"); 93 assertEquals(cursor1.getValue(), cursor2.getValue(), scenario + ":" + index3 +" Cursors have different values!");
102 94
103 canMove = canMove1; 95 canMove = canMove1;
104 MapTestEnvironment.printStatus(scenario, index3++, content.size(), "Compare"); 96 MapTestEnvironment.printStatus(scenario, index3++, content.size(), "Compare");
105 } while (canMove); 97 } while (canMove);
106
107 // By hashcode
108 assertEquals(sut1.hashCode(), sut2.hashCode(), "Hash codes are not equal!");
109
110 // By equals
111 assertEquals(sut1, sut2, "Maps are not equals");
112 } 98 }
113 99
114 @ParameterizedTest(name = "Compare {index}/{0} Steps={1} Keys={2} Values={3} commit frequency={4} seed={5} evil-hash={6}") 100 @ParameterizedTest(name = "Compare {index}/{0} Steps={1} Keys={2} Values={3} commit frequency={4} seed={5} evil-hash={6}")
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/utils/MapTestEnvironment.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/utils/MapTestEnvironment.java
index a4ba7441..b73f8b32 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/map/tests/utils/MapTestEnvironment.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/utils/MapTestEnvironment.java
@@ -1,21 +1,14 @@
1package tools.refinery.store.map.tests.utils; 1package tools.refinery.store.map.tests.utils;
2 2
3import static org.junit.jupiter.api.Assertions.assertEquals;
4import static org.junit.jupiter.api.Assertions.assertTrue;
5import static org.junit.jupiter.api.Assertions.fail;
6
7import java.util.HashMap;
8import java.util.Iterator;
9import java.util.List;
10import java.util.Map;
11import java.util.Map.Entry;
12
13import tools.refinery.store.map.ContinousHashProvider; 3import tools.refinery.store.map.ContinousHashProvider;
14import tools.refinery.store.map.Cursor; 4import tools.refinery.store.map.Cursor;
15import tools.refinery.store.map.VersionedMap; 5import tools.refinery.store.map.VersionedMap;
16import tools.refinery.store.map.internal.VersionedMapImpl; 6import tools.refinery.store.map.internal.VersionedMapImpl;
17 7
18import java.util.TreeMap; 8import java.util.*;
9import java.util.Map.Entry;
10
11import static org.junit.jupiter.api.Assertions.*;
19 12
20public class MapTestEnvironment<K, V> { 13public class MapTestEnvironment<K, V> {
21 public static String[] prepareValues(int maxValue) { 14 public static String[] prepareValues(int maxValue) {
@@ -63,7 +56,6 @@ public class MapTestEnvironment<K, V> {
63 } 56 }
64 public static <K, V> void compareTwoMaps(String title, VersionedMapImpl<K, V> map1, 57 public static <K, V> void compareTwoMaps(String title, VersionedMapImpl<K, V> map1,
65 VersionedMapImpl<K, V> map2, List<Throwable> errors) { 58 VersionedMapImpl<K, V> map2, List<Throwable> errors) {
66 // 1. Comparing cursors.
67 Cursor<K, V> cursor1 = map1.getAll(); 59 Cursor<K, V> cursor1 = map1.getAll();
68 Cursor<K, V> cursor2 = map2.getAll(); 60 Cursor<K, V> cursor2 = map2.getAll();
69 while (!cursor1.isTerminated()) { 61 while (!cursor1.isTerminated()) {
@@ -77,12 +69,8 @@ public class MapTestEnvironment<K, V> {
77 } 69 }
78 if (!cursor2.isTerminated()) 70 if (!cursor2.isTerminated())
79 fail("cursor 1 terminated before cursor 2"); 71 fail("cursor 1 terminated before cursor 2");
80
81 // 2.1. comparing hash codes
82 assertEqualsList(map1.hashCode(), map2.hashCode(), title + ": hash code check",errors);
83 assertEqualsList(map1, map2, title + ": 1.equals(2)",errors);
84 assertEqualsList(map2, map1, title + ": 2.equals(1)",errors);
85 } 72 }
73
86 private static void assertEqualsList(Object o1, Object o2, String message, List<Throwable> errors) { 74 private static void assertEqualsList(Object o1, Object o2, String message, List<Throwable> errors) {
87 if(errors == null) { 75 if(errors == null) {
88 assertEquals(o1, o2, message); 76 assertEquals(o1, o2, message);
@@ -112,7 +100,7 @@ public class MapTestEnvironment<K, V> {
112 oldOracleValue = oracle.remove(key); 100 oldOracleValue = oracle.remove(key);
113 } 101 }
114 if(oldSutValue == sut.getDefaultValue() && oldOracleValue != null) { 102 if(oldSutValue == sut.getDefaultValue() && oldOracleValue != null) {
115 fail("After put, SUT old nodeId was default, but oracle old walue was " + oldOracleValue); 103 fail("After put, SUT old nodeId was default, but oracle old value was " + oldOracleValue);
116 } 104 }
117 if(oldSutValue != sut.getDefaultValue()) { 105 if(oldSutValue != sut.getDefaultValue()) {
118 assertEquals(oldOracleValue, oldSutValue); 106 assertEquals(oldOracleValue, oldSutValue);
@@ -165,7 +153,7 @@ public class MapTestEnvironment<K, V> {
165 long sutSize = sut.getSize(); 153 long sutSize = sut.getSize();
166 if (oracleSize != sutSize || oracleSize != elementsInSutEntrySet) { 154 if (oracleSize != sutSize || oracleSize != elementsInSutEntrySet) {
167 printComparison(); 155 printComparison();
168 fail(title + ": Non-eqivalent size() result: SUT.getSize()=" + sutSize + ", SUT.entryset.size=" 156 fail(title + ": Non-equivalent size() result: SUT.getSize()=" + sutSize + ", SUT.entryset.size="
169 + elementsInSutEntrySet + ", Oracle=" + oracleSize + "!"); 157 + elementsInSutEntrySet + ", Oracle=" + oracleSize + "!");
170 } 158 }
171 } 159 }
@@ -192,22 +180,22 @@ public class MapTestEnvironment<K, V> {
192 } 180 }
193 181
194 private void printEntrySet(Iterator<Entry<K, V>> iterator) { 182 private void printEntrySet(Iterator<Entry<K, V>> iterator) {
195 TreeMap<K, V> treemap = new TreeMap<>(); 183 Map<K, V> map = new LinkedHashMap<>();
196 while (iterator.hasNext()) { 184 while (iterator.hasNext()) {
197 Entry<K, V> entry = iterator.next(); 185 Entry<K, V> entry = iterator.next();
198 treemap.put(entry.getKey(), entry.getValue()); 186 map.put(entry.getKey(), entry.getValue());
199 } 187 }
200 for (Entry<K, V> e : treemap.entrySet()) { 188 for (Entry<K, V> e : map.entrySet()) {
201 System.out.println("\t" + e.getKey() + " -> " + e.getValue()); 189 System.out.println("\t" + e.getKey() + " -> " + e.getValue());
202 } 190 }
203 } 191 }
204 192
205 private void printEntrySet(Cursor<K, V> cursor) { 193 private void printEntrySet(Cursor<K, V> cursor) {
206 TreeMap<K, V> treemap = new TreeMap<>(); 194 Map<K, V> map = new LinkedHashMap<>();
207 while (cursor.move()) { 195 while (cursor.move()) {
208 treemap.put(cursor.getKey(), cursor.getValue()); 196 map.put(cursor.getKey(), cursor.getValue());
209 } 197 }
210 for (Entry<K, V> e : treemap.entrySet()) { 198 for (Entry<K, V> e : map.entrySet()) {
211 System.out.println("\t" + e.getKey() + " -> " + e.getValue()); 199 System.out.println("\t" + e.getKey() + " -> " + e.getValue());
212 } 200 }
213 } 201 }