diff options
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 @@ | |||
1 | package tools.refinery.language.semantics.model.internal; | 1 | package tools.refinery.language.semantics.model.internal; |
2 | 2 | ||
3 | import tools.refinery.store.map.Cursor; | 3 | import tools.refinery.store.map.Cursor; |
4 | import tools.refinery.store.map.VersionedMap; | ||
5 | import tools.refinery.store.tuple.Tuple; | ||
6 | import tools.refinery.store.model.representation.TruthValue; | 4 | import tools.refinery.store.model.representation.TruthValue; |
5 | import tools.refinery.store.tuple.Tuple; | ||
7 | 6 | ||
8 | import java.util.ArrayDeque; | 7 | import java.util.ArrayDeque; |
9 | import java.util.Deque; | 8 | import java.util.Deque; |
10 | import java.util.List; | ||
11 | 9 | ||
12 | class DecisionTreeCursor implements Cursor<Tuple, TruthValue> { | 10 | class 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; | |||
5 | import tools.refinery.store.model.ModelStore; | 5 | import tools.refinery.store.model.ModelStore; |
6 | import tools.refinery.store.model.ModelStoreImpl; | 6 | import tools.refinery.store.model.ModelStoreImpl; |
7 | import tools.refinery.store.model.RelationLike; | 7 | import tools.refinery.store.model.RelationLike; |
8 | import tools.refinery.store.model.representation.AnyDataRepresentation; | ||
8 | import tools.refinery.store.model.representation.DataRepresentation; | 9 | import tools.refinery.store.model.representation.DataRepresentation; |
9 | import tools.refinery.store.query.*; | 10 | import tools.refinery.store.query.DNF; |
11 | import tools.refinery.store.query.DNFAnd; | ||
12 | import tools.refinery.store.query.QueryableModel; | ||
13 | import tools.refinery.store.query.QueryableModelStore; | ||
10 | import tools.refinery.store.query.atom.*; | 14 | import tools.refinery.store.query.atom.*; |
11 | import tools.refinery.store.query.viatra.internal.RawPatternMatcher; | 15 | import tools.refinery.store.query.viatra.internal.RawPatternMatcher; |
12 | import tools.refinery.store.query.viatra.internal.ViatraQueryableModel; | 16 | import tools.refinery.store.query.viatra.internal.ViatraQueryableModel; |
13 | import tools.refinery.store.query.viatra.internal.pquery.DNF2PQuery; | 17 | import tools.refinery.store.query.viatra.internal.pquery.DNF2PQuery; |
14 | import tools.refinery.store.query.view.RelationView; | 18 | import tools.refinery.store.query.view.AnyRelationView; |
15 | 19 | ||
16 | import java.util.Collections; | 20 | import java.util.Collections; |
17 | import java.util.HashMap; | 21 | import java.util.HashMap; |
@@ -21,11 +25,11 @@ import java.util.Set; | |||
21 | public class ViatraQueryableModelStore implements QueryableModelStore { | 25 | public 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; | |||
6 | import org.eclipse.viatra.query.runtime.api.scope.IIndexingErrorListener; | 6 | import org.eclipse.viatra.query.runtime.api.scope.IIndexingErrorListener; |
7 | import org.eclipse.viatra.query.runtime.api.scope.QueryScope; | 7 | import org.eclipse.viatra.query.runtime.api.scope.QueryScope; |
8 | import tools.refinery.store.model.Model; | 8 | import tools.refinery.store.model.Model; |
9 | import tools.refinery.store.tuple.Tuple; | ||
10 | import tools.refinery.store.model.representation.Relation; | 9 | import tools.refinery.store.model.representation.Relation; |
11 | import tools.refinery.store.query.viatra.internal.context.RelationalEngineContext; | 10 | import tools.refinery.store.query.viatra.internal.context.RelationalEngineContext; |
12 | import tools.refinery.store.query.viatra.internal.viewupdate.ModelUpdateListener; | 11 | import tools.refinery.store.query.viatra.internal.viewupdate.ModelUpdateListener; |
13 | import tools.refinery.store.query.view.RelationView; | 12 | import tools.refinery.store.query.view.AnyRelationView; |
13 | import tools.refinery.store.tuple.Tuple; | ||
14 | 14 | ||
15 | import java.util.Set; | 15 | import java.util.Set; |
16 | 16 | ||
17 | public class RelationalScope extends QueryScope { | 17 | public 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; | |||
8 | import tools.refinery.store.map.DiffCursor; | 8 | import tools.refinery.store.map.DiffCursor; |
9 | import tools.refinery.store.model.Model; | 9 | import tools.refinery.store.model.Model; |
10 | import tools.refinery.store.model.ModelDiffCursor; | 10 | import tools.refinery.store.model.ModelDiffCursor; |
11 | import tools.refinery.store.model.representation.AnyDataRepresentation; | ||
11 | import tools.refinery.store.model.representation.DataRepresentation; | 12 | import tools.refinery.store.model.representation.DataRepresentation; |
12 | import tools.refinery.store.model.representation.Relation; | 13 | import tools.refinery.store.model.representation.Relation; |
13 | import tools.refinery.store.query.QueryableModel; | 14 | import 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; | |||
9 | import tools.refinery.store.model.Model; | 9 | import tools.refinery.store.model.Model; |
10 | import tools.refinery.store.query.viatra.internal.pquery.RelationViewWrapper; | 10 | import tools.refinery.store.query.viatra.internal.pquery.RelationViewWrapper; |
11 | import tools.refinery.store.query.viatra.internal.viewupdate.ModelUpdateListener; | 11 | import tools.refinery.store.query.viatra.internal.viewupdate.ModelUpdateListener; |
12 | import tools.refinery.store.query.view.AnyRelationView; | ||
12 | import tools.refinery.store.query.view.RelationView; | 13 | import tools.refinery.store.query.view.RelationView; |
13 | 14 | ||
14 | import java.lang.reflect.InvocationTargetException; | 15 | import 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 | ||
3 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | 3 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; |
4 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | 4 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; |
5 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.*; | 5 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; |
6 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
7 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; | ||
8 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; | ||
6 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.BinaryTransitiveClosure; | 9 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.BinaryTransitiveClosure; |
7 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.ConstantValue; | 10 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.ConstantValue; |
8 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; | 11 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; |
@@ -10,9 +13,11 @@ import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeCo | |||
10 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | 13 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; |
11 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | 14 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; |
12 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | 15 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; |
13 | import tools.refinery.store.query.*; | 16 | import tools.refinery.store.query.DNF; |
17 | import tools.refinery.store.query.DNFAnd; | ||
18 | import tools.refinery.store.query.Variable; | ||
14 | import tools.refinery.store.query.atom.*; | 19 | import tools.refinery.store.query.atom.*; |
15 | import tools.refinery.store.query.view.RelationView; | 20 | import tools.refinery.store.query.view.AnyRelationView; |
16 | 21 | ||
17 | import java.util.*; | 22 | import java.util.*; |
18 | import java.util.stream.Collectors; | 23 | import 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 @@ | |||
1 | package tools.refinery.store.query.viatra.internal.pquery; | 1 | package tools.refinery.store.query.viatra.internal.pquery; |
2 | 2 | ||
3 | import org.eclipse.viatra.query.runtime.matchers.context.common.BaseInputKeyWrapper; | 3 | import org.eclipse.viatra.query.runtime.matchers.context.common.BaseInputKeyWrapper; |
4 | import tools.refinery.store.query.view.RelationView; | 4 | import tools.refinery.store.query.view.AnyRelationView; |
5 | 5 | ||
6 | public class RelationViewWrapper extends BaseInputKeyWrapper<RelationView<?>> { | 6 | public 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; | |||
3 | import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; | 3 | import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; |
4 | import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; | 4 | import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; |
5 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; | 5 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; |
6 | import tools.refinery.store.model.representation.AnyRelation; | ||
7 | import tools.refinery.store.query.view.AnyRelationView; | ||
6 | import tools.refinery.store.tuple.Tuple; | 8 | import tools.refinery.store.tuple.Tuple; |
7 | import tools.refinery.store.model.representation.Relation; | 9 | import tools.refinery.store.model.representation.Relation; |
8 | import tools.refinery.store.query.view.RelationView; | 10 | import 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; | |||
4 | import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; | 4 | import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; |
5 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; | 5 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; |
6 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | 6 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; |
7 | import tools.refinery.store.tuple.Tuple; | 7 | import tools.refinery.store.query.view.AnyRelationView; |
8 | import tools.refinery.store.query.view.RelationView; | 8 | import tools.refinery.store.query.view.RelationView; |
9 | import tools.refinery.store.tuple.Tuple; | ||
9 | 10 | ||
10 | import java.util.Objects; | 11 | import 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 @@ | |||
1 | package tools.refinery.store.map; | ||
2 | |||
3 | public 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 @@ | |||
1 | package tools.refinery.store.map; | 1 | package tools.refinery.store.map; |
2 | 2 | ||
3 | import java.util.List; | 3 | import java.util.Set; |
4 | 4 | ||
5 | public interface Cursor<K,V> { | 5 | public 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 @@ | |||
1 | package tools.refinery.store.map; | 1 | package tools.refinery.store.map; |
2 | 2 | ||
3 | public interface VersionedMap<K,V> extends Versioned{ | 3 | public 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 @@ | |||
1 | package tools.refinery.store.map; | 1 | package tools.refinery.store.map; |
2 | 2 | ||
3 | public class VersionedMapStoreConfiguration { | 3 | public 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 @@ | |||
1 | package tools.refinery.store.map; | 1 | package tools.refinery.store.map; |
2 | 2 | ||
3 | import java.util.ArrayList; | ||
4 | import java.util.Arrays; | ||
5 | import java.util.Collections; | ||
6 | import java.util.HashMap; | ||
7 | import java.util.HashSet; | ||
8 | import java.util.List; | ||
9 | import java.util.Map; | ||
10 | import java.util.Set; | ||
11 | |||
12 | import tools.refinery.store.map.internal.ImmutableNode; | 3 | import tools.refinery.store.map.internal.ImmutableNode; |
13 | import tools.refinery.store.map.internal.MapDiffCursor; | 4 | import tools.refinery.store.map.internal.MapDiffCursor; |
14 | import tools.refinery.store.map.internal.Node; | 5 | import tools.refinery.store.map.internal.Node; |
15 | import tools.refinery.store.map.internal.VersionedMapImpl; | 6 | import tools.refinery.store.map.internal.VersionedMapImpl; |
16 | 7 | ||
8 | import java.util.*; | ||
9 | |||
17 | public class VersionedMapStoreImpl<K, V> implements VersionedMapStore<K, V> { | 10 | public 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 @@ | |||
1 | package tools.refinery.store.map.internal; | 1 | package tools.refinery.store.map.internal; |
2 | 2 | ||
3 | import tools.refinery.store.map.AnyVersionedMap; | ||
4 | import tools.refinery.store.map.Cursor; | ||
5 | import tools.refinery.store.map.VersionedMap; | ||
6 | |||
3 | import java.util.ArrayDeque; | 7 | import java.util.ArrayDeque; |
4 | import java.util.ConcurrentModificationException; | 8 | import java.util.ConcurrentModificationException; |
5 | import java.util.Iterator; | 9 | import java.util.Iterator; |
6 | import java.util.List; | 10 | import java.util.Set; |
7 | |||
8 | import tools.refinery.store.map.Cursor; | ||
9 | import tools.refinery.store.map.VersionedMap; | ||
10 | 11 | ||
11 | public class MapCursor<K,V> implements Cursor<K,V> { | 12 | public 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 @@ | |||
1 | package tools.refinery.store.map.internal; | 1 | package tools.refinery.store.map.internal; |
2 | 2 | ||
3 | import java.util.List; | 3 | import tools.refinery.store.map.AnyVersionedMap; |
4 | import java.util.stream.Stream; | ||
5 | |||
6 | import tools.refinery.store.map.ContinousHashProvider; | 4 | import tools.refinery.store.map.ContinousHashProvider; |
7 | import tools.refinery.store.map.Cursor; | 5 | import tools.refinery.store.map.Cursor; |
8 | import tools.refinery.store.map.DiffCursor; | 6 | import tools.refinery.store.map.DiffCursor; |
9 | import tools.refinery.store.map.VersionedMap; | 7 | |
8 | import java.util.Set; | ||
9 | import java.util.stream.Collectors; | ||
10 | import 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 @@ | |||
1 | package tools.refinery.store.map.internal; | 1 | package tools.refinery.store.map.internal; |
2 | 2 | ||
3 | import tools.refinery.store.map.*; | ||
4 | |||
3 | import java.util.Iterator; | 5 | import java.util.Iterator; |
4 | import java.util.LinkedList; | 6 | import java.util.LinkedList; |
5 | import java.util.List; | 7 | import java.util.List; |
6 | 8 | ||
7 | import tools.refinery.store.map.ContinousHashProvider; | ||
8 | import tools.refinery.store.map.Cursor; | ||
9 | import tools.refinery.store.map.DiffCursor; | ||
10 | import tools.refinery.store.map.VersionedMap; | ||
11 | import 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 | */ |
20 | public class VersionedMapImpl<K,V> implements VersionedMap<K,V>{ | 16 | public 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 @@ | |||
1 | package tools.refinery.store.model; | 1 | package tools.refinery.store.model; |
2 | 2 | ||
3 | import java.util.Set; | ||
4 | |||
5 | import tools.refinery.store.map.Cursor; | 3 | import tools.refinery.store.map.Cursor; |
6 | import tools.refinery.store.map.Versioned; | 4 | import tools.refinery.store.map.Versioned; |
5 | import tools.refinery.store.model.representation.AnyDataRepresentation; | ||
7 | import tools.refinery.store.model.representation.DataRepresentation; | 6 | import tools.refinery.store.model.representation.DataRepresentation; |
8 | 7 | ||
9 | public interface Model extends Versioned{ | 8 | import java.util.Set; |
10 | @SuppressWarnings("squid:S1452") | 9 | |
11 | Set<DataRepresentation<?, ?>> getDataRepresentations(); | 10 | public 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 @@ | |||
1 | package tools.refinery.store.model; | 1 | package tools.refinery.store.model; |
2 | 2 | ||
3 | import java.util.Map; | ||
4 | |||
5 | import tools.refinery.store.map.Cursor; | 3 | import tools.refinery.store.map.Cursor; |
6 | import tools.refinery.store.map.DiffCursor; | 4 | import tools.refinery.store.map.DiffCursor; |
5 | import tools.refinery.store.model.representation.AnyDataRepresentation; | ||
7 | import tools.refinery.store.model.representation.DataRepresentation; | 6 | import tools.refinery.store.model.representation.DataRepresentation; |
8 | 7 | ||
8 | import java.util.Map; | ||
9 | |||
9 | public class ModelDiffCursor { | 10 | public 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 @@ | |||
1 | package tools.refinery.store.model; | 1 | package tools.refinery.store.model; |
2 | 2 | ||
3 | import java.util.Set; | 3 | import tools.refinery.store.model.representation.AnyDataRepresentation; |
4 | 4 | ||
5 | import tools.refinery.store.model.representation.DataRepresentation; | 5 | import java.util.Set; |
6 | 6 | ||
7 | public interface ModelStore { | 7 | public 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; | |||
3 | import tools.refinery.store.map.*; | 3 | import tools.refinery.store.map.*; |
4 | import tools.refinery.store.model.internal.ModelImpl; | 4 | import tools.refinery.store.model.internal.ModelImpl; |
5 | import tools.refinery.store.model.internal.SimilarRelationEquivalenceClass; | 5 | import tools.refinery.store.model.internal.SimilarRelationEquivalenceClass; |
6 | import tools.refinery.store.model.representation.AnyDataRepresentation; | ||
6 | import tools.refinery.store.model.representation.AuxiliaryData; | 7 | import tools.refinery.store.model.representation.AuxiliaryData; |
7 | import tools.refinery.store.model.representation.DataRepresentation; | 8 | import tools.refinery.store.model.representation.DataRepresentation; |
8 | import tools.refinery.store.model.representation.Relation; | 9 | import tools.refinery.store.model.representation.Relation; |
@@ -13,26 +14,26 @@ import java.util.Map.Entry; | |||
13 | 14 | ||
14 | public class ModelStoreImpl implements ModelStore { | 15 | public 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 @@ | |||
1 | package tools.refinery.store.model.internal; | 1 | package tools.refinery.store.model.internal; |
2 | 2 | ||
3 | import java.util.HashMap; | ||
4 | import java.util.Map; | ||
5 | import java.util.Set; | ||
6 | |||
7 | import tools.refinery.store.map.ContinousHashProvider; | 3 | import tools.refinery.store.map.ContinousHashProvider; |
8 | import tools.refinery.store.map.Cursor; | 4 | import tools.refinery.store.map.Cursor; |
9 | import tools.refinery.store.map.DiffCursor; | 5 | import tools.refinery.store.map.DiffCursor; |
@@ -12,31 +8,41 @@ import tools.refinery.store.map.internal.MapDiffCursor; | |||
12 | import tools.refinery.store.model.Model; | 8 | import tools.refinery.store.model.Model; |
13 | import tools.refinery.store.model.ModelDiffCursor; | 9 | import tools.refinery.store.model.ModelDiffCursor; |
14 | import tools.refinery.store.model.ModelStore; | 10 | import tools.refinery.store.model.ModelStore; |
11 | import tools.refinery.store.model.representation.AnyDataRepresentation; | ||
15 | import tools.refinery.store.model.representation.DataRepresentation; | 12 | import tools.refinery.store.model.representation.DataRepresentation; |
16 | 13 | ||
14 | import java.util.HashMap; | ||
15 | import java.util.Map; | ||
16 | import java.util.Set; | ||
17 | |||
17 | public class ModelImpl implements Model { | 18 | public 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 @@ | |||
1 | package tools.refinery.store.model.internal; | 1 | package tools.refinery.store.model.internal; |
2 | 2 | ||
3 | import java.util.Objects; | ||
4 | |||
5 | import tools.refinery.store.map.ContinousHashProvider; | 3 | import tools.refinery.store.map.ContinousHashProvider; |
6 | import tools.refinery.store.tuple.Tuple; | ||
7 | import tools.refinery.store.model.representation.Relation; | 4 | import tools.refinery.store.model.representation.Relation; |
5 | import tools.refinery.store.tuple.Tuple; | ||
6 | |||
7 | import java.util.Objects; | ||
8 | 8 | ||
9 | public class SimilarRelationEquivalenceClass { | 9 | public 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 @@ | |||
1 | package tools.refinery.store.model.representation; | ||
2 | |||
3 | public 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 @@ | |||
1 | package tools.refinery.store.model.representation; | ||
2 | |||
3 | public 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 @@ | |||
1 | package tools.refinery.store.model.representation; | ||
2 | |||
3 | import tools.refinery.store.model.RelationLike; | ||
4 | import tools.refinery.store.tuple.Tuple; | ||
5 | |||
6 | public 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 | ||
3 | import tools.refinery.store.map.ContinousHashProvider; | 3 | import tools.refinery.store.map.ContinousHashProvider; |
4 | 4 | ||
5 | public final class AuxiliaryData<K, V> extends DataRepresentation<K, V> { | 5 | public 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 | ||
3 | import tools.refinery.store.map.ContinousHashProvider; | 3 | import tools.refinery.store.map.ContinousHashProvider; |
4 | 4 | ||
5 | public abstract sealed class DataRepresentation<K, V> permits Relation, AuxiliaryData { | 5 | public 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 @@ | |||
1 | package tools.refinery.store.model.representation; | 1 | package tools.refinery.store.model.representation; |
2 | 2 | ||
3 | import tools.refinery.store.map.ContinousHashProvider; | 3 | import tools.refinery.store.map.ContinousHashProvider; |
4 | import tools.refinery.store.model.RelationLike; | ||
5 | import tools.refinery.store.model.TupleHashProvider; | 4 | import tools.refinery.store.model.TupleHashProvider; |
6 | import tools.refinery.store.tuple.Tuple; | 5 | import tools.refinery.store.tuple.Tuple; |
7 | 6 | ||
8 | public final class Relation<D> extends DataRepresentation<Tuple, D> implements RelationLike { | 7 | public 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 @@ | |||
1 | package tools.refinery.store.query; | 1 | package tools.refinery.store.query; |
2 | 2 | ||
3 | import tools.refinery.store.model.ModelStore; | 3 | import tools.refinery.store.model.ModelStore; |
4 | import tools.refinery.store.model.representation.DataRepresentation; | 4 | import tools.refinery.store.model.representation.AnyDataRepresentation; |
5 | import tools.refinery.store.query.view.RelationView; | 5 | import tools.refinery.store.query.view.AnyRelationView; |
6 | 6 | ||
7 | import java.util.Set; | 7 | import java.util.Set; |
8 | 8 | ||
9 | public interface QueryableModelStore extends ModelStore { | 9 | public 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 @@ | |||
1 | package tools.refinery.store.query.atom; | 1 | package tools.refinery.store.query.atom; |
2 | 2 | ||
3 | import tools.refinery.store.query.Variable; | 3 | import tools.refinery.store.query.Variable; |
4 | import tools.refinery.store.query.view.RelationView; | 4 | import tools.refinery.store.query.view.AnyRelationView; |
5 | 5 | ||
6 | import java.util.List; | 6 | import java.util.List; |
7 | import java.util.Objects; | 7 | import java.util.Objects; |
8 | 8 | ||
9 | public final class RelationViewAtom extends AbstractSubstitutionAtom<RelationView<?>> { | 9 | public 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 @@ | |||
1 | package tools.refinery.store.query.view; | ||
2 | |||
3 | import tools.refinery.store.model.Model; | ||
4 | import tools.refinery.store.model.RelationLike; | ||
5 | import tools.refinery.store.model.representation.AnyRelation; | ||
6 | |||
7 | public 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; | |||
3 | import tools.refinery.store.tuple.Tuple; | 3 | import tools.refinery.store.tuple.Tuple; |
4 | import tools.refinery.store.model.representation.Relation; | 4 | import tools.refinery.store.model.representation.Relation; |
5 | 5 | ||
6 | import java.util.Objects; | ||
6 | import java.util.function.BiPredicate; | 7 | import java.util.function.BiPredicate; |
7 | import java.util.function.Predicate; | 8 | import 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; | |||
3 | import tools.refinery.store.tuple.Tuple; | 3 | import tools.refinery.store.tuple.Tuple; |
4 | import tools.refinery.store.model.representation.Relation; | 4 | import tools.refinery.store.model.representation.Relation; |
5 | 5 | ||
6 | import java.util.Objects; | ||
7 | |||
6 | public class KeyOnlyRelationView extends AbstractFilteredRelationView<Boolean> { | 8 | public 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 | ||
3 | import tools.refinery.store.map.CursorAsIterator; | 3 | import tools.refinery.store.map.CursorAsIterator; |
4 | import tools.refinery.store.model.Model; | 4 | import tools.refinery.store.model.Model; |
5 | import tools.refinery.store.model.RelationLike; | ||
6 | import tools.refinery.store.tuple.Tuple; | ||
7 | import tools.refinery.store.model.representation.Relation; | 5 | import tools.refinery.store.model.representation.Relation; |
6 | import tools.refinery.store.tuple.Tuple; | ||
8 | 7 | ||
9 | import java.util.Objects; | 8 | import java.util.Objects; |
10 | import java.util.UUID; | 9 | import 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 | */ |
18 | public abstract class RelationView<D> implements RelationLike { | 17 | public 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 @@ | |||
1 | package tools.refinery.store.map.tests.fuzz; | 1 | package tools.refinery.store.map.tests.fuzz; |
2 | 2 | ||
3 | import static org.junit.jupiter.api.Assertions.assertEquals; | ||
4 | import static org.junit.jupiter.api.Assertions.fail; | ||
5 | |||
6 | import java.util.AbstractMap.SimpleEntry; | ||
7 | import java.util.Collections; | ||
8 | import java.util.LinkedList; | ||
9 | import java.util.List; | ||
10 | import java.util.Random; | ||
11 | import java.util.stream.Stream; | ||
12 | |||
13 | import org.junit.jupiter.api.Tag; | 3 | import org.junit.jupiter.api.Tag; |
14 | import org.junit.jupiter.api.Timeout; | 4 | import org.junit.jupiter.api.Timeout; |
15 | import org.junit.jupiter.params.ParameterizedTest; | 5 | import org.junit.jupiter.params.ParameterizedTest; |
16 | import org.junit.jupiter.params.provider.Arguments; | 6 | import org.junit.jupiter.params.provider.Arguments; |
17 | import org.junit.jupiter.params.provider.MethodSource; | 7 | import org.junit.jupiter.params.provider.MethodSource; |
18 | 8 | import tools.refinery.store.map.*; | |
19 | import tools.refinery.store.map.ContinousHashProvider; | ||
20 | import tools.refinery.store.map.Cursor; | ||
21 | import tools.refinery.store.map.VersionedMap; | ||
22 | import tools.refinery.store.map.VersionedMapStore; | ||
23 | import tools.refinery.store.map.VersionedMapStoreImpl; | ||
24 | import tools.refinery.store.map.internal.VersionedMapImpl; | 9 | import tools.refinery.store.map.internal.VersionedMapImpl; |
25 | import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; | 10 | import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; |
26 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; | 11 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; |
27 | 12 | ||
13 | import java.util.AbstractMap.SimpleEntry; | ||
14 | import java.util.Collections; | ||
15 | import java.util.LinkedList; | ||
16 | import java.util.List; | ||
17 | import java.util.Random; | ||
18 | import java.util.stream.Stream; | ||
19 | |||
20 | import static org.junit.jupiter.api.Assertions.assertEquals; | ||
21 | import static org.junit.jupiter.api.Assertions.fail; | ||
22 | |||
28 | class ContentEqualsFuzzTest { | 23 | class 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 @@ | |||
1 | package tools.refinery.store.map.tests.utils; | 1 | package tools.refinery.store.map.tests.utils; |
2 | 2 | ||
3 | import static org.junit.jupiter.api.Assertions.assertEquals; | ||
4 | import static org.junit.jupiter.api.Assertions.assertTrue; | ||
5 | import static org.junit.jupiter.api.Assertions.fail; | ||
6 | |||
7 | import java.util.HashMap; | ||
8 | import java.util.Iterator; | ||
9 | import java.util.List; | ||
10 | import java.util.Map; | ||
11 | import java.util.Map.Entry; | ||
12 | |||
13 | import tools.refinery.store.map.ContinousHashProvider; | 3 | import tools.refinery.store.map.ContinousHashProvider; |
14 | import tools.refinery.store.map.Cursor; | 4 | import tools.refinery.store.map.Cursor; |
15 | import tools.refinery.store.map.VersionedMap; | 5 | import tools.refinery.store.map.VersionedMap; |
16 | import tools.refinery.store.map.internal.VersionedMapImpl; | 6 | import tools.refinery.store.map.internal.VersionedMapImpl; |
17 | 7 | ||
18 | import java.util.TreeMap; | 8 | import java.util.*; |
9 | import java.util.Map.Entry; | ||
10 | |||
11 | import static org.junit.jupiter.api.Assertions.*; | ||
19 | 12 | ||
20 | public class MapTestEnvironment<K, V> { | 13 | public 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 | } |