From aac386f0d8c4e4585026b11bfeca20f378f7f261 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Mon, 26 Sep 2022 00:39:23 +0200 Subject: refactor: move viatra into a separate subproject --- .../tools/refinery/store/query/QueriableModel.java | 30 -- .../refinery/store/query/QueriableModelStore.java | 23 -- .../store/query/QueriableModelStoreImpl.java | 127 ------ .../tools/refinery/store/query/QueryableModel.java | 32 ++ .../refinery/store/query/QueryableModelStore.java | 23 ++ .../store/query/building/RelationAtom.java | 30 +- .../refinery/store/query/internal/DNF2PQuery.java | 189 --------- .../store/query/internal/DummyBaseIndexer.java | 59 --- .../store/query/internal/ModelUpdateListener.java | 103 ----- .../store/query/internal/PredicateResult.java | 24 -- .../store/query/internal/QueriableModelImpl.java | 212 ---------- .../store/query/internal/RawPatternMatcher.java | 57 --- .../query/internal/RelationalEngineContext.java | 33 -- .../query/internal/RelationalQueryMetaContext.java | 58 --- .../query/internal/RelationalRuntimeContext.java | 178 --------- .../store/query/internal/RelationalScope.java | 43 -- .../refinery/store/query/internal/ViewUpdate.java | 34 -- .../store/query/internal/ViewUpdateBuffer.java | 46 --- .../store/query/internal/ViewUpdateTranslator.java | 57 --- .../tools/refinery/store/query/test/QueryTest.java | 445 --------------------- .../store/query/test/QueryTransactionTest.java | 58 --- 21 files changed, 61 insertions(+), 1800 deletions(-) delete mode 100644 subprojects/store/src/main/java/tools/refinery/store/query/QueriableModel.java delete mode 100644 subprojects/store/src/main/java/tools/refinery/store/query/QueriableModelStore.java delete mode 100644 subprojects/store/src/main/java/tools/refinery/store/query/QueriableModelStoreImpl.java create mode 100644 subprojects/store/src/main/java/tools/refinery/store/query/QueryableModel.java create mode 100644 subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java delete mode 100644 subprojects/store/src/main/java/tools/refinery/store/query/internal/DNF2PQuery.java delete mode 100644 subprojects/store/src/main/java/tools/refinery/store/query/internal/DummyBaseIndexer.java delete mode 100644 subprojects/store/src/main/java/tools/refinery/store/query/internal/ModelUpdateListener.java delete mode 100644 subprojects/store/src/main/java/tools/refinery/store/query/internal/PredicateResult.java delete mode 100644 subprojects/store/src/main/java/tools/refinery/store/query/internal/QueriableModelImpl.java delete mode 100644 subprojects/store/src/main/java/tools/refinery/store/query/internal/RawPatternMatcher.java delete mode 100644 subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalEngineContext.java delete mode 100644 subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalQueryMetaContext.java delete mode 100644 subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalRuntimeContext.java delete mode 100644 subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalScope.java delete mode 100644 subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdate.java delete mode 100644 subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdateBuffer.java delete mode 100644 subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdateTranslator.java delete mode 100644 subprojects/store/src/test/java/tools/refinery/store/query/test/QueryTest.java delete mode 100644 subprojects/store/src/test/java/tools/refinery/store/query/test/QueryTransactionTest.java (limited to 'subprojects/store/src') diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/QueriableModel.java b/subprojects/store/src/main/java/tools/refinery/store/query/QueriableModel.java deleted file mode 100644 index f669b3ed..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/QueriableModel.java +++ /dev/null @@ -1,30 +0,0 @@ -package tools.refinery.store.query; - -import java.util.Optional; -import java.util.Set; -import java.util.stream.Stream; - -import tools.refinery.store.model.Model; -import tools.refinery.store.query.building.DNFPredicate; - -public interface QueriableModel extends Model{ - Set getPredicates(); - - void flushChanges(); - - boolean hasResult(DNFPredicate predicate); - - boolean hasResult(DNFPredicate predicate, Object[] parameters); - - Optional oneResult(DNFPredicate predicate); - - Optional oneResult(DNFPredicate predicate, Object[] parameters); - - Stream allResults(DNFPredicate predicate); - - Stream allResults(DNFPredicate predicate, Object[] parameters); - - int countResults(DNFPredicate predicate); - - int countResults(DNFPredicate predicate, Object[] parameters); -} diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/QueriableModelStore.java b/subprojects/store/src/main/java/tools/refinery/store/query/QueriableModelStore.java deleted file mode 100644 index 3a5b51ff..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/QueriableModelStore.java +++ /dev/null @@ -1,23 +0,0 @@ -package tools.refinery.store.query; - -import java.util.Set; - -import tools.refinery.store.model.ModelDiffCursor; -import tools.refinery.store.model.ModelStore; -import tools.refinery.store.model.representation.DataRepresentation; -import tools.refinery.store.query.building.DNFPredicate; -import tools.refinery.store.query.view.RelationView; - -public interface QueriableModelStore extends ModelStore{ - @SuppressWarnings("squid:S1452") - Set> getDataRepresentations(); - @SuppressWarnings("squid:S1452") - Set> getViews(); - Set getPredicates(); - - QueriableModel createModel(); - QueriableModel createModel(long state); - - Set getStates(); - ModelDiffCursor getDiffCursor(long from, long to); -} diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/QueriableModelStoreImpl.java b/subprojects/store/src/main/java/tools/refinery/store/query/QueriableModelStoreImpl.java deleted file mode 100644 index 653783dd..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/QueriableModelStoreImpl.java +++ /dev/null @@ -1,127 +0,0 @@ -package tools.refinery.store.query; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; - -import tools.refinery.store.model.ModelDiffCursor; -import tools.refinery.store.model.ModelStore; -import tools.refinery.store.model.ModelStoreImpl; -import tools.refinery.store.model.representation.DataRepresentation; -import tools.refinery.store.query.building.DNFAnd; -import tools.refinery.store.query.building.DNFAtom; -import tools.refinery.store.query.building.DNFPredicate; -import tools.refinery.store.query.building.PredicateAtom; -import tools.refinery.store.query.building.RelationAtom; -import tools.refinery.store.query.internal.DNF2PQuery; -import tools.refinery.store.query.internal.QueriableModelImpl; -import tools.refinery.store.query.internal.RawPatternMatcher; -import tools.refinery.store.query.internal.DNF2PQuery.SimplePQuery; -import tools.refinery.store.query.view.RelationView; - -public class QueriableModelStoreImpl implements QueriableModelStore { - protected final ModelStore store; - protected final Set> relationViews; - protected final Map> predicates; - - public QueriableModelStoreImpl(Set> dataRepresentations, - Set> relationViews, Set predicates) { - this.store = new ModelStoreImpl(dataRepresentations); - validateViews(dataRepresentations, relationViews); - this.relationViews = Collections.unmodifiableSet(relationViews); - validatePredicates(relationViews, predicates); - this.predicates = initPredicates(predicates); - } - - private void validateViews(Set> dataRepresentations, Set> relationViews) { - for (RelationView relationView : relationViews) { - // TODO: make it work for non-relation representation? - if (!dataRepresentations.contains(relationView.getRepresentation())) { - throw new IllegalArgumentException( - DataRepresentation.class.getSimpleName() + " " + relationView.getStringID() + " added to " - + QueriableModelStore.class.getSimpleName() + " without a referred representation."); - } - } - } - - private void validatePredicates(Set> relationViews, Set predicates) { - for (DNFPredicate dnfPredicate : predicates) { - for (DNFAnd clause : dnfPredicate.getClauses()) { - for (DNFAtom atom : clause.getConstraints()) { - if (atom instanceof RelationAtom relationAtom) { - validateRelationAtom(relationViews, dnfPredicate, relationAtom); - } else if (atom instanceof PredicateAtom predicateAtom) { - validatePredicateAtom(predicates, dnfPredicate, predicateAtom); - } - } - } - } - } - - private void validateRelationAtom(Set> relationViews, DNFPredicate dnfPredicate, - RelationAtom relationAtom) { - if (!relationViews.contains(relationAtom.getView())) { - throw new IllegalArgumentException(DNFPredicate.class.getSimpleName() + " " - + dnfPredicate.getUniqueName() + " contains reference to a view of " - + relationAtom.getView().getRepresentation().getName() - + " that is not in the model."); - } - } - private void validatePredicateAtom(Set predicates, DNFPredicate dnfPredicate, - PredicateAtom predicateAtom) { - if (!predicates.contains(predicateAtom.getReferred())) { - throw new IllegalArgumentException( - DNFPredicate.class.getSimpleName() + " " + dnfPredicate.getUniqueName() - + " contains reference to a predicate " - + predicateAtom.getReferred().getName() - + "that is not in the model."); - } - } - - private Map> initPredicates(Set predicates) { - Map> result = new HashMap<>(); - Map dnf2PQueryMap = new HashMap<>(); - for (DNFPredicate dnfPredicate : predicates) { - GenericQuerySpecification query = DNF2PQuery.translate(dnfPredicate,dnf2PQueryMap).build(); - result.put(dnfPredicate, query); - } - - return result; - } - - @Override - public Set> getDataRepresentations() { - return store.getDataRepresentations(); - } - @Override - public Set> getViews() { - return this.relationViews; - } - @Override - public Set getPredicates() { - return predicates.keySet(); - } - - @Override - public QueriableModel createModel() { - return new QueriableModelImpl(this, this.store.createModel(), predicates); - } - - @Override - public QueriableModel createModel(long state) { - return new QueriableModelImpl(this, this.store.createModel(state), predicates); - } - - @Override - public synchronized Set getStates() { - return this.store.getStates(); - } - - @Override - public synchronized ModelDiffCursor getDiffCursor(long from, long to) { - return this.store.getDiffCursor(from, to); - } -} diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModel.java b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModel.java new file mode 100644 index 00000000..187abbc2 --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModel.java @@ -0,0 +1,32 @@ +package tools.refinery.store.query; + +import tools.refinery.store.model.Model; +import tools.refinery.store.query.building.DNFPredicate; + +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; + +public interface QueryableModel extends Model{ + Set getPredicates(); + + boolean hasChanges(); + + void flushChanges(); + + boolean hasResult(DNFPredicate predicate); + + boolean hasResult(DNFPredicate predicate, Object[] parameters); + + Optional oneResult(DNFPredicate predicate); + + Optional oneResult(DNFPredicate predicate, Object[] parameters); + + Stream allResults(DNFPredicate predicate); + + Stream allResults(DNFPredicate predicate, Object[] parameters); + + int countResults(DNFPredicate predicate); + + int countResults(DNFPredicate predicate, Object[] parameters); +} 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 new file mode 100644 index 00000000..08efe17c --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java @@ -0,0 +1,23 @@ +package tools.refinery.store.query; + +import tools.refinery.store.model.ModelDiffCursor; +import tools.refinery.store.model.ModelStore; +import tools.refinery.store.model.representation.DataRepresentation; +import tools.refinery.store.query.building.DNFPredicate; +import tools.refinery.store.query.view.RelationView; + +import java.util.Set; + +public interface QueryableModelStore extends ModelStore{ + @SuppressWarnings("squid:S1452") + Set> getDataRepresentations(); + @SuppressWarnings("squid:S1452") + Set> getViews(); + Set getPredicates(); + + QueryableModel createModel(); + QueryableModel createModel(long state); + + Set getStates(); + ModelDiffCursor getDiffCursor(long from, long to); +} diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/building/RelationAtom.java b/subprojects/store/src/main/java/tools/refinery/store/query/building/RelationAtom.java index 1238f1d7..f66245fc 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/query/building/RelationAtom.java +++ b/subprojects/store/src/main/java/tools/refinery/store/query/building/RelationAtom.java @@ -1,35 +1,17 @@ package tools.refinery.store.query.building; +import tools.refinery.store.query.view.RelationView; + +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; -import tools.refinery.store.query.view.FilteredRelationView; -import tools.refinery.store.query.view.RelationView; - -public class RelationAtom implements DNFAtom { - RelationView view; - List substitution; - +public record RelationAtom(RelationView view, List substitution) implements DNFAtom { public RelationAtom(RelationView view, List substitution) { this.view = view; - this.substitution = substitution; - } - - public RelationView getView() { - return view; - } - - public void setView(FilteredRelationView view) { - this.view = view; - } - - public List getSubstitution() { - return substitution; - } - - public void setSubstitution(List substitution) { - this.substitution = substitution; + // Create a mutable copy of substitution so that unifyVariables can change it. + this.substitution = new ArrayList<>(substitution); } @Override diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/DNF2PQuery.java b/subprojects/store/src/main/java/tools/refinery/store/query/internal/DNF2PQuery.java deleted file mode 100644 index bcc03fb4..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/DNF2PQuery.java +++ /dev/null @@ -1,189 +0,0 @@ -package tools.refinery.store.query.internal; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.InputMismatchException; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; -import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; -import org.eclipse.viatra.query.runtime.api.scope.QueryScope; -import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; -import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; -import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; -import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; -import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; -import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; -import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; -import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.BinaryTransitiveClosure; -import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; -import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; -import org.eclipse.viatra.query.runtime.matchers.psystem.queries.BasePQuery; -import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; -import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; -import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; - -import tools.refinery.store.query.building.DNFAnd; -import tools.refinery.store.query.building.DNFAtom; -import tools.refinery.store.query.building.DNFPredicate; -import tools.refinery.store.query.building.EquivalenceAtom; -import tools.refinery.store.query.building.PredicateAtom; -import tools.refinery.store.query.building.RelationAtom; -import tools.refinery.store.query.building.Variable; - -public class DNF2PQuery { - - public static SimplePQuery translate(DNFPredicate predicate, Map dnf2PQueryMap) { - SimplePQuery query = dnf2PQueryMap.get(predicate); - if (query != null) { - return query; - } - query = new DNF2PQuery().new SimplePQuery(predicate.getName()); - Map parameters = new HashMap<>(); - - predicate.getVariables().forEach(variable -> parameters.put(variable, new PParameter(variable.getName()))); - List parameterList = new ArrayList<>(); - for(var param : predicate.getVariables()) { - parameterList.add(parameters.get(param)); - } - query.setParameter(parameterList); - for (DNFAnd clause : predicate.getClauses()) { - PBody body = new PBody(query); - List symbolicParameters = new ArrayList<>(); - for(var param : predicate.getVariables()) { - PVariable pVar = body.getOrCreateVariableByName(param.getName()); - symbolicParameters.add(new ExportedParameter(body, pVar, parameters.get(param))); - } - body.setSymbolicParameters(symbolicParameters); - query.addBody(body); - for (DNFAtom constraint : clause.getConstraints()) { - translateDNFAtom(constraint, body, dnf2PQueryMap); - } - } - dnf2PQueryMap.put(predicate, query); - return query; - } - - private static void translateDNFAtom(DNFAtom constraint, PBody body, Map dnf2PQueryMap) { - if (constraint instanceof EquivalenceAtom equivalence) { - translateEquivalenceAtom(equivalence, body); - } - if (constraint instanceof RelationAtom relation) { - translateRelationAtom(relation, body); - } - if (constraint instanceof PredicateAtom predicate) { - translatePredicateAtom(predicate, body, dnf2PQueryMap); - } - } - - private static void translateEquivalenceAtom(EquivalenceAtom equivalence, PBody body) { - PVariable varSource = body.getOrCreateVariableByName(equivalence.getLeft().getName()); - PVariable varTarget = body.getOrCreateVariableByName(equivalence.getRight().getName()); - if (equivalence.isPositive()) - new Equality(body, varSource, varTarget); - else - new Inequality(body, varSource, varTarget); - } - - private static void translateRelationAtom(RelationAtom relation, PBody body) { - if (relation.getSubstitution().size() != relation.getView().getArity()) { - throw new IllegalArgumentException("Arity (" + relation.getView().getArity() - + ") does not match parameter numbers (" + relation.getSubstitution().size() + ")"); - } - Object[] variables = new Object[relation.getSubstitution().size()]; - for (int i = 0; i < relation.getSubstitution().size(); i++) { - variables[i] = body.getOrCreateVariableByName(relation.getSubstitution().get(i).getName()); - } - new TypeConstraint(body, Tuples.flatTupleOf(variables), relation.getView()); - } - - private static void translatePredicateAtom(PredicateAtom predicate, PBody body, Map dnf2PQueryMap) { - Object[] variables = new Object[predicate.getSubstitution().size()]; - for (int i = 0; i < predicate.getSubstitution().size(); i++) { - variables[i] = body.getOrCreateVariableByName(predicate.getSubstitution().get(i).getName()); - } - if (predicate.isPositive()) { - if (predicate.isTransitive()) { - if (predicate.getSubstitution().size() != 2) { - throw new IllegalArgumentException("Transitive Predicate Atoms must be binary."); - } - new BinaryTransitiveClosure(body, Tuples.flatTupleOf(variables), - DNF2PQuery.translate(predicate.getReferred(), dnf2PQueryMap)); - } else { - new PositivePatternCall(body, Tuples.flatTupleOf(variables), - DNF2PQuery.translate(predicate.getReferred(), dnf2PQueryMap)); - } - } else { - if (predicate.isTransitive()) { - throw new InputMismatchException("Transitive Predicate Atoms cannot be negative."); - } else { - new NegativePatternCall(body, Tuples.flatTupleOf(variables), - DNF2PQuery.translate(predicate.getReferred(), dnf2PQueryMap)); - } - } - } - - public class SimplePQuery extends BasePQuery { - - private String fullyQualifiedName; - private List parameters; - private LinkedHashSet bodies = new LinkedHashSet<>(); - - public SimplePQuery(String name) { - super(PVisibility.PUBLIC); - fullyQualifiedName = name; - } - - @Override - public String getFullyQualifiedName() { - return fullyQualifiedName; - } - - public void setParameter(List parameters) { - this.parameters = parameters; - } - - @Override - public List getParameters() { - return parameters; - } - - public void addBody(PBody body) { - bodies.add(body); - } - - @Override - protected Set doGetContainedBodies() { - setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); - return bodies; - } - - public GenericQuerySpecification build() { - return new GenericQuerySpecification(this) { - - @Override - public Class getPreferredScopeClass() { - return RelationalScope.class; - } - - @Override - protected RawPatternMatcher instantiate(ViatraQueryEngine engine) { - RawPatternMatcher matcher = engine.getExistingMatcher(this); - if (matcher == null) { - matcher = engine.getMatcher(this); - } - return matcher; - } - - @Override - public RawPatternMatcher instantiate() { - return new RawPatternMatcher(this); - } - - }; - } - } -} \ No newline at end of file diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/DummyBaseIndexer.java b/subprojects/store/src/main/java/tools/refinery/store/query/internal/DummyBaseIndexer.java deleted file mode 100644 index 49637071..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/DummyBaseIndexer.java +++ /dev/null @@ -1,59 +0,0 @@ -package tools.refinery.store.query.internal; - -import java.lang.reflect.InvocationTargetException; -import java.util.concurrent.Callable; - -import org.eclipse.viatra.query.runtime.api.scope.IBaseIndex; -import org.eclipse.viatra.query.runtime.api.scope.IIndexingErrorListener; -import org.eclipse.viatra.query.runtime.api.scope.IInstanceObserver; -import org.eclipse.viatra.query.runtime.api.scope.ViatraBaseIndexChangeListener; - -/** - * copied from org.eclipse.viatra.query.runtime.tabular.TabularEngineContext; - */ -public class DummyBaseIndexer implements IBaseIndex{ - - @Override - public V coalesceTraversals(Callable callable) throws InvocationTargetException { - try { - return callable.call(); - } catch (Exception e) { - throw new InvocationTargetException(e); - } - } - - @Override - public void addBaseIndexChangeListener(ViatraBaseIndexChangeListener listener) { - // no notification support - } - - @Override - public void removeBaseIndexChangeListener(ViatraBaseIndexChangeListener listener) { - // no notification support - } - - @Override - public void resampleDerivedFeatures() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addIndexingErrorListener(IIndexingErrorListener listener) { - return true; - } - - @Override - public boolean removeIndexingErrorListener(IIndexingErrorListener listener) { - return true; - } - - @Override - public boolean addInstanceObserver(IInstanceObserver observer, Object observedObject) { - return true; - } - - @Override - public boolean removeInstanceObserver(IInstanceObserver observer, Object observedObject) { - return true; - } -} diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/ModelUpdateListener.java b/subprojects/store/src/main/java/tools/refinery/store/query/internal/ModelUpdateListener.java deleted file mode 100644 index aa80985f..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/ModelUpdateListener.java +++ /dev/null @@ -1,103 +0,0 @@ -package tools.refinery.store.query.internal; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; -import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; - -import tools.refinery.store.model.Tuple; -import tools.refinery.store.model.representation.Relation; -import tools.refinery.store.query.view.RelationView; - -public class ModelUpdateListener { - /** - * Collections of Relations and their Views. - */ - private final Map, Set>> relation2View; - /** - * Collection of Views and their buffers. - */ - private final Map, Set>> view2Buffers; - - public ModelUpdateListener(Set> relationViews) { - this.relation2View = new HashMap<>(); - this.view2Buffers = new HashMap<>(); - - for (RelationView relationView : relationViews) { - registerView(relationView); - } - } - - private void registerView(RelationView view) { - Relation relation = view.getRepresentation(); - - // 1. register views to relations, if necessary - var views = relation2View.computeIfAbsent(relation, x->new HashSet<>()); - views.add(view); - - // 2. register notifier map to views, if necessary - view2Buffers.computeIfAbsent(view, x->new HashSet<>()); - } - - boolean containsRelationalView(RelationView relationalKey) { - return view2Buffers.containsKey(relationalKey); - } - - void addListener(RelationView relationView, ITuple seed, IQueryRuntimeContextListener listener) { - if (view2Buffers.containsKey(relationView)) { - ViewUpdateTranslator updateListener = new ViewUpdateTranslator<>(relationView, seed, listener); - ViewUpdateBuffer updateBuffer = new ViewUpdateBuffer<>(updateListener); - view2Buffers.get(relationView).add(updateBuffer); - } else - throw new IllegalArgumentException(); - } - - void removeListener(RelationView relationView, ITuple seed, IQueryRuntimeContextListener listener) { - if (view2Buffers.containsKey(relationView)) { - Set> buffers = this.view2Buffers.get(relationView); - for(var buffer : buffers) { - if(buffer.getUpdateListener().key == seed && buffer.getUpdateListener().listener == listener) { - // remove buffer and terminate immediately, or it will break iterator. - buffers.remove(buffer); - return; - } - } - } else - throw new IllegalArgumentException(); - } - - public void addUpdate(Relation relation, Tuple key, D oldValue, D newValue) { - var views = this.relation2View.get(relation); - if (views != null) { - for (var view : views) { - var buffers = this.view2Buffers.get(view); - for (var buffer : buffers) { - @SuppressWarnings("unchecked") - var typedBuffer = (ViewUpdateBuffer) buffer; - typedBuffer.addChange(key, oldValue, newValue); - } - } - } - } - - public boolean hasChange() { - for (var bufferCollection : this.view2Buffers.values()) { - for (ViewUpdateBuffer buffer : bufferCollection) { - if (buffer.hasChange()) - return true; - } - } - return false; - } - - public void flush() { - for (var bufferCollection : this.view2Buffers.values()) { - for (ViewUpdateBuffer buffer : bufferCollection) { - buffer.flush(); - } - } - } -} diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/PredicateResult.java b/subprojects/store/src/main/java/tools/refinery/store/query/internal/PredicateResult.java deleted file mode 100644 index 65d23eb6..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/PredicateResult.java +++ /dev/null @@ -1,24 +0,0 @@ -package tools.refinery.store.query.internal; - -import java.util.Optional; -import java.util.stream.Stream; - -public interface PredicateResult { - - boolean hasResult(); - - boolean hasResult(Object[] parameters); - - Optional oneResult(); - - Optional oneResult(Object[] parameters); - - Stream allResults(); - - Stream allResults(Object[] parameters); - - int countResults(); - - int countResults(Object[] parameters); - -} \ No newline at end of file diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/QueriableModelImpl.java b/subprojects/store/src/main/java/tools/refinery/store/query/internal/QueriableModelImpl.java deleted file mode 100644 index 0f4d609f..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/QueriableModelImpl.java +++ /dev/null @@ -1,212 +0,0 @@ -package tools.refinery.store.query.internal; - -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Stream; - -import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine; -import org.eclipse.viatra.query.runtime.api.GenericQueryGroup; -import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; -import org.eclipse.viatra.query.runtime.api.IQueryGroup; - -import tools.refinery.store.map.Cursor; -import tools.refinery.store.map.DiffCursor; -import tools.refinery.store.model.Model; -import tools.refinery.store.model.ModelDiffCursor; -import tools.refinery.store.model.Tuple; -import tools.refinery.store.model.representation.DataRepresentation; -import tools.refinery.store.model.representation.Relation; -import tools.refinery.store.query.QueriableModel; -import tools.refinery.store.query.QueriableModelStore; -import tools.refinery.store.query.building.DNFPredicate; - -public class QueriableModelImpl implements QueriableModel { - protected final QueriableModelStore store; - protected final Model model; - protected final Map> predicates2PQuery; - - protected RelationalScope scope; - protected AdvancedViatraQueryEngine engine; - protected Map predicate2Matcher; - - public QueriableModelImpl(QueriableModelStore store, Model model, - Map> predicates2PQuery) { - this.store = store; - this.model = model; - this.predicates2PQuery = predicates2PQuery; - initEngine(); - } - - private void initEngine() { - this.scope = new RelationalScope(this.model, this.store.getViews()); - this.engine = AdvancedViatraQueryEngine.createUnmanagedEngine(this.scope); - this.predicate2Matcher = initMatchers(this.engine, this.predicates2PQuery); - } - - private Map initMatchers(AdvancedViatraQueryEngine engine, - Map> predicates2pQuery) { - // 1. prepare group - IQueryGroup queryGroup = GenericQueryGroup.of(Set.copyOf(predicates2pQuery.values())); - engine.prepareGroup(queryGroup, null); - - // 2. then get all matchers - Map result = new HashMap<>(); - for (var entry : predicates2pQuery.entrySet()) { - var matcher = engine.getMatcher(entry.getValue()); - result.put(entry.getKey(), matcher); - } - return result; - } - - @Override - public Set> getDataRepresentations() { - return model.getDataRepresentations(); - } - - @Override - public Set getPredicates() { - return store.getPredicates(); - } - - @Override - public V get(DataRepresentation representation, K key) { - return model.get(representation, key); - } - - @Override - public Cursor getAll(DataRepresentation representation) { - return model.getAll(representation); - } - - @SuppressWarnings("unchecked") - @Override - public V put(DataRepresentation representation, K key, V value) { - V oldValue = this.model.put(representation, key, value); - if(representation instanceof Relation relation) { - this.scope.processUpdate((Relation)relation, (Tuple)key, oldValue, value); - } - return oldValue; - } - - @Override - public void putAll(DataRepresentation representation, Cursor cursor) { - if(representation instanceof Relation) { - @SuppressWarnings("unchecked") - Relation relation = (Relation) representation; - while(cursor.move()) { - Tuple key = (Tuple) cursor.getKey(); - V newValue = cursor.getValue(); - V oldValue = this.model.put(relation, key, newValue); - this.scope.processUpdate(relation, key, oldValue, newValue); - } - } else { - this.model.putAll(representation, cursor); - } - } - - @Override - public long getSize(DataRepresentation representation) { - return model.getSize(representation); - } - - protected PredicateResult getPredicateResult(DNFPredicate predicate) { - var result = this.predicate2Matcher.get(predicate); - if (result == null) { - throw new IllegalArgumentException("Model does not contain predicate " + predicate.getName() + "!"); - } else - return result; - } - - protected void validateParameters(DNFPredicate predicate, Object[] parameters) { - int predicateArity = predicate.getVariables().size(); - int parameterArity = parameters.length; - if (parameterArity != predicateArity) { - throw new IllegalArgumentException("Predicate " + predicate.getName() + " with " + predicateArity - + " arity called with different number of parameters (" + parameterArity + ")!"); - } - } - - @Override - public boolean hasResult(DNFPredicate predicate) { - return getPredicateResult(predicate).hasResult(); - } - - @Override - public boolean hasResult(DNFPredicate predicate, Object[] parameters) { - validateParameters(predicate, parameters); - return getPredicateResult(predicate).hasResult(parameters); - } - - @Override - public Optional oneResult(DNFPredicate predicate){ - return getPredicateResult(predicate).oneResult(); - } - - @Override - public Optional oneResult(DNFPredicate predicate, Object[] parameters){ - validateParameters(predicate, parameters); - return getPredicateResult(predicate).oneResult(parameters); - } - - @Override - public Stream allResults(DNFPredicate predicate){ - return getPredicateResult(predicate).allResults(); - } - - @Override - public Stream allResults(DNFPredicate predicate, Object[] parameters){ - validateParameters(predicate, parameters); - return getPredicateResult(predicate).allResults(parameters); - } - - @Override - public int countResults(DNFPredicate predicate){ - return getPredicateResult(predicate).countResults(); - } - - @Override - public int countResults(DNFPredicate predicate, Object[] parameters){ - validateParameters(predicate, parameters); - return getPredicateResult(predicate).countResults(parameters); - - } - @Override - public void flushChanges() { - this.scope.flush(); - } - - @Override - public ModelDiffCursor getDiffCursor(long to) { - return model.getDiffCursor(to); - } - - @Override - public long commit() { - return this.model.commit(); - } - - @Override - public void restore(long state) { - restoreWithDiffReplay(state); - } - - public void restoreWithDiffReplay(long state) { - var modelDiffCursor = getDiffCursor(state); - for(DataRepresentation dataRepresentation : this.getDataRepresentations()) { - restoreRepresentationWithDiffReplay(modelDiffCursor, dataRepresentation); - } - } - - private void restoreRepresentationWithDiffReplay(ModelDiffCursor modelDiffCursor, - DataRepresentation dataRepresentation) { - DiffCursor diffCursor = modelDiffCursor.getCursor(dataRepresentation); - this.putAll(dataRepresentation, diffCursor); - } - - public void restoreWithReinit(long state) { - model.restore(state); - this.initEngine(); - } -} diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RawPatternMatcher.java b/subprojects/store/src/main/java/tools/refinery/store/query/internal/RawPatternMatcher.java deleted file mode 100644 index c6d6353c..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RawPatternMatcher.java +++ /dev/null @@ -1,57 +0,0 @@ -package tools.refinery.store.query.internal; - -import java.util.Optional; -import java.util.stream.Stream; - -import org.eclipse.viatra.query.runtime.api.GenericPatternMatcher; -import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; -import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; -import org.eclipse.viatra.query.runtime.matchers.tuple.AbstractTuple; - -public class RawPatternMatcher extends GenericPatternMatcher implements PredicateResult{ - - protected final Object[] empty; - - public RawPatternMatcher(GenericQuerySpecification specification) { - super(specification); - this.empty = new Object[specification.getParameterNames().size()]; - } - - @Override - public boolean hasResult() { - return hasResult(empty); - } - @Override - public boolean hasResult(Object[] parameters) { - return this.backend.hasMatch(parameters); - } - @Override - public Optional oneResult() { - return oneResult(empty); - } - @Override - public Optional oneResult(Object[] parameters) { - Optional tuple = this.backend.getOneArbitraryMatch(parameters); - if(tuple.isPresent()) { - return Optional.of(tuple.get().getElements()); - } else { - return Optional.empty(); - } - } - @Override - public Stream allResults() { - return allResults(empty); - } - @Override - public Stream allResults(Object[] parameters) { - return this.backend.getAllMatches(parameters).map(AbstractTuple::getElements); - } - @Override - public int countResults() { - return countResults(empty); - } - @Override - public int countResults(Object[] parameters) { - return backend.countMatches(parameters); - } -} diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalEngineContext.java b/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalEngineContext.java deleted file mode 100644 index dfbd8545..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalEngineContext.java +++ /dev/null @@ -1,33 +0,0 @@ -package tools.refinery.store.query.internal; - -import org.eclipse.viatra.query.runtime.api.scope.IBaseIndex; -import org.eclipse.viatra.query.runtime.api.scope.IEngineContext; -import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext; - -import tools.refinery.store.model.Model; - -public class RelationalEngineContext implements IEngineContext{ - private final IBaseIndex baseIndex = new DummyBaseIndexer(); - private final RelationalRuntimeContext runtimeContext; - - - public RelationalEngineContext(Model model, ModelUpdateListener updateListener) { - runtimeContext = new RelationalRuntimeContext(model, updateListener); - } - - @Override - public IBaseIndex getBaseIndex() { - return this.baseIndex; - } - - @Override - public void dispose() { - //lifecycle not controlled by engine - } - - @Override - public IQueryRuntimeContext getQueryRuntimeContext() { - return runtimeContext; - } - -} diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalQueryMetaContext.java b/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalQueryMetaContext.java deleted file mode 100644 index 05fb0904..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalQueryMetaContext.java +++ /dev/null @@ -1,58 +0,0 @@ -package tools.refinery.store.query.internal; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.eclipse.viatra.query.runtime.matchers.context.AbstractQueryMetaContext; -import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; -import org.eclipse.viatra.query.runtime.matchers.context.InputKeyImplication; - -import tools.refinery.store.query.view.RelationView; - -/** - * The meta context information for String scopes. - */ -public final class RelationalQueryMetaContext extends AbstractQueryMetaContext { - - @Override - public boolean isEnumerable(IInputKey key) { - ensureValidKey(key); - return key.isEnumerable(); - } - - @Override - public boolean isStateless(IInputKey key) { - ensureValidKey(key); - return key instanceof RelationView; - } - - @Override - public Collection getImplications(IInputKey implyingKey) { - ensureValidKey(implyingKey); - return new HashSet(); - } - - @Override - public Map, Set> getFunctionalDependencies(IInputKey key) { - ensureValidKey(key); - if (key instanceof RelationView) { - return new HashMap, Set>(); - } else { - return Collections.emptyMap(); - } - } - - public void ensureValidKey(IInputKey key) { - if (! (key instanceof RelationView)) - illegalInputKey(key); - } - - public void illegalInputKey(IInputKey key) { - throw new IllegalArgumentException("The input key " + key + " is not a valid input key."); - } - -} diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalRuntimeContext.java b/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalRuntimeContext.java deleted file mode 100644 index a186b5dd..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalRuntimeContext.java +++ /dev/null @@ -1,178 +0,0 @@ -package tools.refinery.store.query.internal; - -import static tools.refinery.store.util.CollectionsUtil.filter; -import static tools.refinery.store.util.CollectionsUtil.map; - -import java.lang.reflect.InvocationTargetException; -import java.util.Iterator; -import java.util.Optional; -import java.util.concurrent.Callable; - -import org.eclipse.viatra.query.runtime.base.core.NavigationHelperImpl; -import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; -import org.eclipse.viatra.query.runtime.matchers.context.IQueryMetaContext; -import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext; -import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; -import org.eclipse.viatra.query.runtime.matchers.context.IndexingService; -import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; -import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; -import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask; -import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; -import org.eclipse.viatra.query.runtime.matchers.util.Accuracy; - -import tools.refinery.store.model.Model; -import tools.refinery.store.query.view.RelationView; - -public class RelationalRuntimeContext implements IQueryRuntimeContext { - private final RelationalQueryMetaContext metaContext = new RelationalQueryMetaContext(); - private final ModelUpdateListener modelUpdateListener; - private final Model model; - - public RelationalRuntimeContext(Model model, ModelUpdateListener relationUpdateListener) { - this.model = model; - this.modelUpdateListener = relationUpdateListener; - } - - @Override - public IQueryMetaContext getMetaContext() { - return metaContext; - } - - /** - * TODO: check {@link NavigationHelperImpl#coalesceTraversals(Callable)} - */ - @Override - public V coalesceTraversals(Callable callable) throws InvocationTargetException { - try { - return callable.call(); - } catch (Exception e) { - throw new InvocationTargetException(e); - } - } - - @Override - public boolean isCoalescing() { - return true; - } - - @Override - public boolean isIndexed(IInputKey key, IndexingService service) { - if(key instanceof RelationView relationalKey) { - return this.modelUpdateListener.containsRelationalView(relationalKey); - } else { - return false; - } - } - - @Override - public void ensureIndexed(IInputKey key, IndexingService service) { - if(!isIndexed(key, service)) { - throw new IllegalStateException("Engine tries to index a new key " +key); - } - } - @SuppressWarnings("squid:S1452") - RelationView checkKey(IInputKey key) { - if(key instanceof RelationView) { - RelationView relationViewKey = (RelationView) key; - if(modelUpdateListener.containsRelationalView(relationViewKey)) { - return relationViewKey; - } else { - throw new IllegalStateException("Query is asking for non-indexed key"); - } - } else { - throw new IllegalStateException("Query is asking for non-relational key"); - } - } - - @Override - public int countTuples(IInputKey key, TupleMask seedMask, ITuple seed) { - RelationView relationalViewKey = checkKey(key); - Iterable allObjects = relationalViewKey.getAll(model); - Iterable filteredBySeed = filter(allObjects,objectArray -> isMatching(objectArray,seedMask,seed)); - Iterator iterator = filteredBySeed.iterator(); - int result = 0; - while(iterator.hasNext()) { - iterator.next(); - result++; - } - return result; - } - - @Override - public Optional estimateCardinality(IInputKey key, TupleMask groupMask, Accuracy requiredAccuracy) { - return Optional.empty(); - } - - @Override - public Iterable enumerateTuples(IInputKey key, TupleMask seedMask, ITuple seed) { - RelationView relationalViewKey = checkKey(key); - Iterable allObjects = relationalViewKey.getAll(model); - Iterable filteredBySeed = filter(allObjects,objectArray -> isMatching(objectArray,seedMask,seed)); - return map(filteredBySeed,Tuples::flatTupleOf); - } - - private boolean isMatching(Object[] tuple, TupleMask seedMask, ITuple seed) { - for(int i=0; i enumerateValues(IInputKey key, TupleMask seedMask, ITuple seed) { - return enumerateTuples(key, seedMask, seed); - } - - @Override - public boolean containsTuple(IInputKey key, ITuple seed) { - RelationView relationalViewKey = checkKey(key); - return relationalViewKey.get(model,seed.getElements()); - } - - @Override - public void addUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) { - RelationView relationalKey = checkKey(key); - this.modelUpdateListener.addListener(relationalKey, seed, listener); - - } - - @Override - public void removeUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) { - RelationView relationalKey = checkKey(key); - this.modelUpdateListener.removeListener(relationalKey, seed, listener); - } - - @Override - public Object wrapElement(Object externalElement) { - return externalElement; - } - - @Override - public Object unwrapElement(Object internalElement) { - return internalElement; - } - - @Override - public Tuple wrapTuple(Tuple externalElements) { - return externalElements; - } - - @Override - public Tuple unwrapTuple(Tuple internalElements) { - return internalElements; - } - - @Override - public void ensureWildcardIndexing(IndexingService service) { - throw new UnsupportedOperationException(); - } - - @Override - public void executeAfterTraversal(Runnable runnable) throws InvocationTargetException { - runnable.run(); - } -} diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalScope.java b/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalScope.java deleted file mode 100644 index e8d45356..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalScope.java +++ /dev/null @@ -1,43 +0,0 @@ -package tools.refinery.store.query.internal; - -import java.util.Set; - -import org.apache.log4j.Logger; -import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; -import org.eclipse.viatra.query.runtime.api.scope.IEngineContext; -import org.eclipse.viatra.query.runtime.api.scope.IIndexingErrorListener; -import org.eclipse.viatra.query.runtime.api.scope.QueryScope; - -import tools.refinery.store.model.Model; -import tools.refinery.store.model.Tuple; -import tools.refinery.store.model.representation.Relation; -import tools.refinery.store.query.view.RelationView; - -public class RelationalScope extends QueryScope{ - private final Model model; - private final ModelUpdateListener updateListener; - - public RelationalScope(Model model, Set> relationViews) { - this.model = model; - this.updateListener = new ModelUpdateListener(relationViews); - //this.changeListener = new - } - - public void processUpdate(Relation relation, Tuple key, D oldValue, D newValue) { - updateListener.addUpdate(relation, key, oldValue, newValue); - } - - public boolean hasChange() { - return updateListener.hasChange(); - } - - public void flush() { - updateListener.flush(); - } - - @Override - protected IEngineContext createEngineContext(ViatraQueryEngine engine, IIndexingErrorListener errorListener, - Logger logger) { - return new RelationalEngineContext(model, updateListener); - } -} diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdate.java b/subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdate.java deleted file mode 100644 index 7d1a4c05..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdate.java +++ /dev/null @@ -1,34 +0,0 @@ -package tools.refinery.store.query.internal; - -import java.util.Arrays; -import java.util.Objects; - -record ViewUpdate (Object[] tuple, boolean isInsertion) { - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + Arrays.deepHashCode(tuple); - result = prime * result + Objects.hash(isInsertion); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ViewUpdate other = (ViewUpdate) obj; - return isInsertion == other.isInsertion && Arrays.deepEquals(tuple, other.tuple); - } - - @Override - public String toString() { - return "ViewUpdate [" + Arrays.toString(tuple) + "insertion= "+this.isInsertion+"]"; - } - -} diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdateBuffer.java b/subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdateBuffer.java deleted file mode 100644 index 6bc4c96a..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdateBuffer.java +++ /dev/null @@ -1,46 +0,0 @@ -package tools.refinery.store.query.internal; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import tools.refinery.store.model.Tuple; - -public class ViewUpdateBuffer { - protected final ViewUpdateTranslator updateListener; - protected final List buffer = new ArrayList<>(); - - public ViewUpdateBuffer(ViewUpdateTranslator updateListener) { - this.updateListener = updateListener; - } - - public ViewUpdateTranslator getUpdateListener() { - return updateListener; - } - - public boolean hasChange() { - return ! buffer.isEmpty(); - } - - public void addChange(Tuple tuple, D oldValue, D newValue) { - if(oldValue != newValue) { - Object[] oldTuple = updateListener.isMatching(tuple, oldValue); - Object[] newTuple = updateListener.isMatching(tuple, newValue); - if(!Arrays.equals(oldTuple, newTuple)) { - if(oldTuple != null) { - buffer.add(new ViewUpdate(oldTuple, false)); - } - if(newTuple != null) { - buffer.add(new ViewUpdate(newTuple, true)); - } - } - } - } - - public void flush() { - for (ViewUpdate viewChange : buffer) { - updateListener.processChange(viewChange); - } - buffer.clear(); - } -} diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdateTranslator.java b/subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdateTranslator.java deleted file mode 100644 index 1c210c5f..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdateTranslator.java +++ /dev/null @@ -1,57 +0,0 @@ -package tools.refinery.store.query.internal; - -import java.util.Objects; - -import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; -import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; -import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; - -import tools.refinery.store.model.Tuple; -import tools.refinery.store.query.view.RelationView; - -public class ViewUpdateTranslator { - final RelationView key; - final ITuple filter; - final IQueryRuntimeContextListener listener; - - public ViewUpdateTranslator(RelationView key, ITuple filter, IQueryRuntimeContextListener listener) { - super(); - this.key = key; - this.filter = filter; - this.listener = listener; - } - - public void processChange(ViewUpdate change) { - listener.update(key, Tuples.flatTupleOf(change.tuple()), change.isInsertion()); - } - - public Object[] isMatching(Tuple tuple, D value){ - return isMatching(key.getWrappedKey().transform(tuple, value), filter); - } - @SuppressWarnings("squid:S1168") - private Object[] isMatching(Object[] tuple, ITuple filter) { - for(int i = 0; i other = (ViewUpdateTranslator) obj; - return Objects.equals(filter, other.filter) && Objects.equals(key, other.key) - && Objects.equals(listener, other.listener); - } -} diff --git a/subprojects/store/src/test/java/tools/refinery/store/query/test/QueryTest.java b/subprojects/store/src/test/java/tools/refinery/store/query/test/QueryTest.java deleted file mode 100644 index 02381bcd..00000000 --- a/subprojects/store/src/test/java/tools/refinery/store/query/test/QueryTest.java +++ /dev/null @@ -1,445 +0,0 @@ -package tools.refinery.store.query.test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Stream; - -import org.junit.jupiter.api.Test; - -import tools.refinery.store.model.Tuple; -import tools.refinery.store.model.representation.Relation; -import tools.refinery.store.model.representation.TruthValue; -import tools.refinery.store.query.QueriableModel; -import tools.refinery.store.query.QueriableModelStore; -import tools.refinery.store.query.QueriableModelStoreImpl; -import tools.refinery.store.query.building.DNFAnd; -import tools.refinery.store.query.building.DNFPredicate; -import tools.refinery.store.query.building.EquivalenceAtom; -import tools.refinery.store.query.building.PredicateAtom; -import tools.refinery.store.query.building.RelationAtom; -import tools.refinery.store.query.building.Variable; -import tools.refinery.store.query.view.FilteredRelationView; -import tools.refinery.store.query.view.KeyOnlyRelationView; -import tools.refinery.store.query.view.RelationView; - -class QueryTest { - - static void compareMatchSets(Stream matchSet, Set> expected) { - Set> translatedMatchSet = new HashSet<>(); - var interator = matchSet.iterator(); - while (interator.hasNext()) { - var element = interator.next(); - List elementToTranslatedMatchSet = new ArrayList<>(); - for (int i = 0; i < element.length; i++) { - elementToTranslatedMatchSet.add((Tuple) element[i]); - } - translatedMatchSet.add(elementToTranslatedMatchSet); - } - - assertEquals(expected, translatedMatchSet); - } - - @Test - void typeConstraintTest() { - Relation person = new Relation<>("Person", 1, false); - Relation asset = new Relation<>("Asset", 1, false); - RelationView persionView = new KeyOnlyRelationView(person); - - List parameters = Arrays.asList(new Variable("p1")); - RelationAtom personRelationAtom = new RelationAtom(persionView, parameters); - DNFAnd clause = new DNFAnd(Collections.emptySet(), Arrays.asList(personRelationAtom)); - DNFPredicate predicate = new DNFPredicate("TypeConstraint", parameters, Arrays.asList(clause)); - - QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, asset), Set.of(persionView), - Set.of(predicate)); - QueriableModel model = store.createModel(); - - model.put(person, Tuple.of(0), true); - model.put(person, Tuple.of(1), true); - model.put(asset, Tuple.of(1), true); - model.put(asset, Tuple.of(2), true); - - model.flushChanges(); - assertEquals(2, model.countResults(predicate)); - compareMatchSets(model.allResults(predicate), Set.of(List.of(Tuple.of(0)), List.of(Tuple.of(1)))); - } - - @Test - void relationConstraintTest() { - Relation person = new Relation("Person", 1, false); - Relation friend = new Relation<>("friend", 2, TruthValue.FALSE); - RelationView persionView = new KeyOnlyRelationView(person); - RelationView friendMustView = new FilteredRelationView(friend, (k, v) -> v.must()); - - Variable p1 = new Variable("p1"); - Variable p2 = new Variable("p2"); - List parameters = Arrays.asList(p1, p2); - - RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1)); - RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2)); - RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); - DNFAnd clause = new DNFAnd(Collections.emptySet(), - Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); - DNFPredicate predicate = new DNFPredicate("RelationConstraint", parameters, Arrays.asList(clause)); - - QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, friend), - Set.of(persionView, friendMustView), Set.of(predicate)); - QueriableModel model = store.createModel(); - - assertEquals(0, model.countResults(predicate)); - - model.put(person, Tuple.of(0), true); - model.put(person, Tuple.of(1), true); - model.put(person, Tuple.of(2), true); - model.put(friend, Tuple.of(0, 1), TruthValue.TRUE); - model.put(friend, Tuple.of(1, 0), TruthValue.TRUE); - model.put(friend, Tuple.of(1, 2), TruthValue.TRUE); - - assertEquals(0, model.countResults(predicate)); - - model.flushChanges(); - assertEquals(3, model.countResults(predicate)); - compareMatchSets(model.allResults(predicate), Set.of(List.of(Tuple.of(0), Tuple.of(1)), - List.of(Tuple.of(1), Tuple.of(0)), List.of(Tuple.of(1), Tuple.of(2)))); - } - - @Test - void andTest() { - Relation person = new Relation("Person", 1, false); - Relation friend = new Relation<>("friend", 2, TruthValue.FALSE); - RelationView persionView = new KeyOnlyRelationView(person); - RelationView friendMustView = new FilteredRelationView(friend, (k, v) -> v.must()); - - Variable p1 = new Variable("p1"); - Variable p2 = new Variable("p2"); - List parameters = Arrays.asList(p1, p2); - - RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1)); - RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2)); - RelationAtom friendRelationAtom1 = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); - RelationAtom friendRelationAtom2 = new RelationAtom(friendMustView, Arrays.asList(p2, p1)); - DNFAnd clause = new DNFAnd(Collections.emptySet(), - Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom1, friendRelationAtom2)); - DNFPredicate predicate = new DNFPredicate("RelationConstraint", parameters, Arrays.asList(clause)); - - QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, friend), - Set.of(persionView, friendMustView), Set.of(predicate)); - QueriableModel model = store.createModel(); - - assertEquals(0, model.countResults(predicate)); - - model.put(person, Tuple.of(0), true); - model.put(person, Tuple.of(1), true); - model.put(person, Tuple.of(2), true); - - model.put(friend, Tuple.of(0, 1), TruthValue.TRUE); - model.put(friend, Tuple.of(0, 2), TruthValue.TRUE); - - model.flushChanges(); - assertEquals(0, model.countResults(predicate)); - - model.put(friend, Tuple.of(1, 0), TruthValue.TRUE); - model.flushChanges(); - assertEquals(2, model.countResults(predicate)); - compareMatchSets(model.allResults(predicate), - Set.of(List.of(Tuple.of(0), Tuple.of(1)), List.of(Tuple.of(1), Tuple.of(0)))); - - model.put(friend, Tuple.of(2, 0), TruthValue.TRUE); - model.flushChanges(); - assertEquals(4, model.countResults(predicate)); - compareMatchSets(model.allResults(predicate), - Set.of(List.of(Tuple.of(0), Tuple.of(1)), List.of(Tuple.of(1), Tuple.of(0)), - List.of(Tuple.of(0), Tuple.of(2)), List.of(Tuple.of(2), Tuple.of(0)))); - } - - @Test - void existTest() { - Relation person = new Relation("Person", 1, false); - Relation friend = new Relation<>("friend", 2, TruthValue.FALSE); - RelationView persionView = new KeyOnlyRelationView(person); - RelationView friendMustView = new FilteredRelationView(friend, (k, v) -> v.must()); - - Variable p1 = new Variable("p1"); - Variable p2 = new Variable("p2"); - List parameters = Arrays.asList(p1); - - RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1)); - RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2)); - RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); - DNFAnd clause = new DNFAnd(Set.of(p2), - Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); - DNFPredicate predicate = new DNFPredicate("RelationConstraint", parameters, Arrays.asList(clause)); - - QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, friend), - Set.of(persionView, friendMustView), Set.of(predicate)); - QueriableModel model = store.createModel(); - - assertEquals(0, model.countResults(predicate)); - - model.put(person, Tuple.of(0), true); - model.put(person, Tuple.of(1), true); - model.put(person, Tuple.of(2), true); - model.put(friend, Tuple.of(0, 1), TruthValue.TRUE); - model.put(friend, Tuple.of(1, 0), TruthValue.TRUE); - model.put(friend, Tuple.of(1, 2), TruthValue.TRUE); - - assertEquals(0, model.countResults(predicate)); - - model.flushChanges(); - assertEquals(2, model.countResults(predicate)); - compareMatchSets(model.allResults(predicate), Set.of(List.of(Tuple.of(0)), List.of(Tuple.of(1)))); - } - - @Test - void orTest() { - Relation person = new Relation<>("Person", 1, false); - Relation animal = new Relation<>("Animal", 1, false); - Relation friend = new Relation<>("friend", 2, TruthValue.FALSE); - RelationView persionView = new KeyOnlyRelationView(person); - RelationView animalView = new KeyOnlyRelationView(animal); - RelationView friendMustView = new FilteredRelationView(friend, (k, v) -> v.must()); - - Variable p1 = new Variable("p1"); - Variable p2 = new Variable("p2"); - List parameters = Arrays.asList(p1, p2); - - // Person-Person friendship - RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1)); - RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2)); - RelationAtom friendRelationAtom1 = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); - DNFAnd clause1 = new DNFAnd(Collections.emptySet(), - Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom1)); - - // Animal-Animal friendship - RelationAtom animalRelationAtom1 = new RelationAtom(animalView, Arrays.asList(p1)); - RelationAtom animalRelationAtom2 = new RelationAtom(animalView, Arrays.asList(p2)); - RelationAtom friendRelationAtom2 = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); - DNFAnd clause2 = new DNFAnd(Collections.emptySet(), - Arrays.asList(animalRelationAtom1, animalRelationAtom2, friendRelationAtom2)); - - // No inter-species friendship - - DNFPredicate predicate = new DNFPredicate("Or", parameters, Arrays.asList(clause1, clause2)); - - QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, animal, friend), - Set.of(persionView, animalView, friendMustView), Set.of(predicate)); - QueriableModel model = store.createModel(); - - model.put(person, Tuple.of(0), true); - model.put(person, Tuple.of(1), true); - model.put(animal, Tuple.of(2), true); - model.put(animal, Tuple.of(3), true); - model.put(friend, Tuple.of(0, 1), TruthValue.TRUE); - model.put(friend, Tuple.of(0, 2), TruthValue.TRUE); - model.put(friend, Tuple.of(2, 3), TruthValue.TRUE); - model.put(friend, Tuple.of(3, 0), TruthValue.TRUE); - - model.flushChanges(); - assertEquals(2, model.countResults(predicate)); - compareMatchSets(model.allResults(predicate), - Set.of(List.of(Tuple.of(0), Tuple.of(1)), List.of(Tuple.of(2), Tuple.of(3)))); - } - - @Test - void equalityTest() { - Relation person = new Relation("Person", 1, false); - RelationView persionView = new KeyOnlyRelationView(person); - - Variable p1 = new Variable("p1"); - Variable p2 = new Variable("p2"); - List parameters = Arrays.asList(p1, p2); - - RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1)); - RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2)); - EquivalenceAtom equivalenceAtom = new EquivalenceAtom(true, p1, p2); - DNFAnd clause = new DNFAnd(Collections.emptySet(), - Arrays.asList(personRelationAtom1, personRelationAtom2, equivalenceAtom)); - DNFPredicate predicate = new DNFPredicate("Equality", parameters, Arrays.asList(clause)); - - QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person), Set.of(persionView), Set.of(predicate)); - QueriableModel model = store.createModel(); - - model.put(person, Tuple.of(0), true); - model.put(person, Tuple.of(1), true); - model.put(person, Tuple.of(2), true); - - model.flushChanges(); - assertEquals(3, model.countResults(predicate)); - compareMatchSets(model.allResults(predicate), Set.of(List.of(Tuple.of(0), Tuple.of(0)), - List.of(Tuple.of(1), Tuple.of(1)), List.of(Tuple.of(2), Tuple.of(2)))); - } - - @Test - void inequalityTest() { - Relation person = new Relation("Person", 1, false); - Relation friend = new Relation<>("friend", 2, TruthValue.FALSE); - RelationView persionView = new KeyOnlyRelationView(person); - RelationView friendMustView = new FilteredRelationView(friend, (k, v) -> v.must()); - - Variable p1 = new Variable("p1"); - Variable p2 = new Variable("p2"); - Variable p3 = new Variable("p3"); - List parameters = Arrays.asList(p1, p2, p3); - - RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1)); - RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2)); - RelationAtom friendRelationAtom1 = new RelationAtom(friendMustView, Arrays.asList(p1, p3)); - RelationAtom friendRelationAtom2 = new RelationAtom(friendMustView, Arrays.asList(p2, p3)); - EquivalenceAtom inequivalenceAtom = new EquivalenceAtom(false, p1, p2); - DNFAnd clause = new DNFAnd(Collections.emptySet(), Arrays.asList(personRelationAtom1, personRelationAtom2, - friendRelationAtom1, friendRelationAtom2, inequivalenceAtom)); - DNFPredicate predicate = new DNFPredicate("Inequality", parameters, Arrays.asList(clause)); - - QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, friend), - Set.of(persionView, friendMustView), Set.of(predicate)); - QueriableModel model = store.createModel(); - - model.put(person, Tuple.of(0), true); - model.put(person, Tuple.of(1), true); - model.put(person, Tuple.of(2), true); - model.put(friend, Tuple.of(0, 2), TruthValue.TRUE); - model.put(friend, Tuple.of(1, 2), TruthValue.TRUE); - - model.flushChanges(); - assertEquals(2, model.countResults(predicate)); - compareMatchSets(model.allResults(predicate), - Set.of(List.of(Tuple.of(0), Tuple.of(1), Tuple.of(2)), List.of(Tuple.of(1), Tuple.of(0), Tuple.of(2)))); - } - - @Test - void patternCallTest() { - Relation person = new Relation("Person", 1, false); - Relation friend = new Relation<>("friend", 2, TruthValue.FALSE); - RelationView persionView = new KeyOnlyRelationView(person); - RelationView friendMustView = new FilteredRelationView(friend, (k, v) -> v.must()); - - Variable p1 = new Variable("p1"); - Variable p2 = new Variable("p2"); - List parameters = Arrays.asList(p1, p2); - - RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1)); - RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2)); - RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); - DNFAnd clause = new DNFAnd(Collections.emptySet(), - Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); - DNFPredicate friendPredicate = new DNFPredicate("RelationConstraint", parameters, Arrays.asList(clause)); - - Variable p3 = new Variable("p3"); - Variable p4 = new Variable("p4"); - List substitution = Arrays.asList(p3, p4); - RelationAtom personRelationAtom3 = new RelationAtom(persionView, Arrays.asList(p3)); - RelationAtom personRelationAtom4 = new RelationAtom(persionView, Arrays.asList(p4)); - PredicateAtom friendPredicateAtom = new PredicateAtom(true, false, friendPredicate, substitution); - DNFAnd patternCallClause = new DNFAnd(Collections.emptySet(), - Arrays.asList(personRelationAtom3, personRelationAtom4, friendPredicateAtom)); - DNFPredicate predicate = new DNFPredicate("PatternCall", substitution, Arrays.asList(patternCallClause)); - - QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, friend), - Set.of(persionView, friendMustView), Set.of(friendPredicate, predicate)); - QueriableModel model = store.createModel(); - - model.put(person, Tuple.of(0), true); - model.put(person, Tuple.of(1), true); - model.put(person, Tuple.of(2), true); - model.put(friend, Tuple.of(0, 1), TruthValue.TRUE); - model.put(friend, Tuple.of(1, 0), TruthValue.TRUE); - model.put(friend, Tuple.of(1, 2), TruthValue.TRUE); - - model.flushChanges(); - - assertEquals(3, model.countResults(friendPredicate)); - } - - @Test - void negativePatternCallTest() { - Relation person = new Relation("Person", 1, false); - Relation friend = new Relation<>("friend", 2, TruthValue.FALSE); - RelationView persionView = new KeyOnlyRelationView(person); - RelationView friendMustView = new FilteredRelationView(friend, (k, v) -> v.must()); - - Variable p1 = new Variable("p1"); - Variable p2 = new Variable("p2"); - List parameters = Arrays.asList(p1, p2); - - RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1)); - RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2)); - RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); - DNFAnd clause = new DNFAnd(Collections.emptySet(), - Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); - DNFPredicate friendPredicate = new DNFPredicate("RelationConstraint", parameters, Arrays.asList(clause)); - - Variable p3 = new Variable("p3"); - Variable p4 = new Variable("p4"); - List substitution = Arrays.asList(p3, p4); - RelationAtom personRelationAtom3 = new RelationAtom(persionView, Arrays.asList(p3)); - RelationAtom personRelationAtom4 = new RelationAtom(persionView, Arrays.asList(p4)); - PredicateAtom friendPredicateAtom = new PredicateAtom(false, false, friendPredicate, substitution); - DNFAnd negativePatternCallClause = new DNFAnd(Collections.emptySet(), - Arrays.asList(personRelationAtom3, personRelationAtom4, friendPredicateAtom)); - DNFPredicate predicate = new DNFPredicate("NegativePatternCall", substitution, - Arrays.asList(negativePatternCallClause)); - - QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, friend), - Set.of(persionView, friendMustView), Set.of(friendPredicate, predicate)); - QueriableModel model = store.createModel(); - - model.put(person, Tuple.of(0), true); - model.put(person, Tuple.of(1), true); - model.put(person, Tuple.of(2), true); - model.put(friend, Tuple.of(0, 1), TruthValue.TRUE); - model.put(friend, Tuple.of(1, 0), TruthValue.TRUE); - model.put(friend, Tuple.of(1, 2), TruthValue.TRUE); - - model.flushChanges(); - assertEquals(6, model.countResults(predicate)); - } - - @Test - void transitivePatternCallTest() { - Relation person = new Relation("Person", 1, false); - Relation friend = new Relation<>("friend", 2, TruthValue.FALSE); - RelationView persionView = new KeyOnlyRelationView(person); - RelationView friendMustView = new FilteredRelationView(friend, (k, v) -> v.must()); - - Variable p1 = new Variable("p1"); - Variable p2 = new Variable("p2"); - List parameters = Arrays.asList(p1, p2); - - RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1)); - RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2)); - RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); - DNFAnd clause = new DNFAnd(Collections.emptySet(), - Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); - DNFPredicate friendPredicate = new DNFPredicate("RelationConstraint", parameters, Arrays.asList(clause)); - - Variable p3 = new Variable("p3"); - Variable p4 = new Variable("p4"); - List substitution = Arrays.asList(p3, p4); - RelationAtom personRelationAtom3 = new RelationAtom(persionView, Arrays.asList(p3)); - RelationAtom personRelationAtom4 = new RelationAtom(persionView, Arrays.asList(p4)); - PredicateAtom friendPredicateAtom = new PredicateAtom(true, true, friendPredicate, substitution); - DNFAnd patternCallClause = new DNFAnd(Collections.emptySet(), - Arrays.asList(personRelationAtom3, personRelationAtom4, friendPredicateAtom)); - DNFPredicate predicate = new DNFPredicate("TransitivePatternCall", substitution, - Arrays.asList(patternCallClause)); - - QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, friend), - Set.of(persionView, friendMustView), Set.of(friendPredicate, predicate)); - QueriableModel model = store.createModel(); - - model.put(person, Tuple.of(0), true); - model.put(person, Tuple.of(1), true); - model.put(person, Tuple.of(2), true); - model.put(friend, Tuple.of(0, 1), TruthValue.TRUE); - model.put(friend, Tuple.of(1, 2), TruthValue.TRUE); - - model.flushChanges(); - assertEquals(3, model.countResults(predicate)); - } -} \ No newline at end of file diff --git a/subprojects/store/src/test/java/tools/refinery/store/query/test/QueryTransactionTest.java b/subprojects/store/src/test/java/tools/refinery/store/query/test/QueryTransactionTest.java deleted file mode 100644 index e72186b9..00000000 --- a/subprojects/store/src/test/java/tools/refinery/store/query/test/QueryTransactionTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package tools.refinery.store.query.test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Set; - -import org.junit.jupiter.api.Test; - -import tools.refinery.store.model.Tuple; -import tools.refinery.store.model.representation.Relation; -import tools.refinery.store.query.QueriableModel; -import tools.refinery.store.query.QueriableModelStore; -import tools.refinery.store.query.QueriableModelStoreImpl; -import tools.refinery.store.query.building.DNFAnd; -import tools.refinery.store.query.building.DNFPredicate; -import tools.refinery.store.query.building.RelationAtom; -import tools.refinery.store.query.building.Variable; -import tools.refinery.store.query.view.KeyOnlyRelationView; -import tools.refinery.store.query.view.RelationView; - -class QueryTransactionTest { - @Test - void flushTest() { - Relation person = new Relation<>("Person", 1, false); - Relation asset = new Relation<>("Asset", 1, false); - RelationView persionView = new KeyOnlyRelationView(person); - - List parameters = Arrays.asList(new Variable("p1")); - RelationAtom personRelationAtom = new RelationAtom(persionView, parameters); - DNFAnd clause = new DNFAnd(Collections.emptySet(), Arrays.asList(personRelationAtom)); - DNFPredicate predicate = new DNFPredicate("TypeConstraint", parameters, Arrays.asList(clause)); - - QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, asset), Set.of(persionView), - Set.of(predicate)); - QueriableModel model = store.createModel(); - - assertEquals(0, model.countResults(predicate)); - - model.put(person, Tuple.of(0), true); - model.put(person, Tuple.of(1), true); - model.put(asset, Tuple.of(1), true); - model.put(asset, Tuple.of(2), true); - - assertEquals(0, model.countResults(predicate)); - - model.flushChanges(); - assertEquals(2, model.countResults(predicate)); - - model.put(person, Tuple.of(4), true); - assertEquals(2, model.countResults(predicate)); - - model.flushChanges(); - assertEquals(3, model.countResults(predicate)); - } -} -- cgit v1.2.3-70-g09d2