aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalViatraMatcher.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalViatraMatcher.java')
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalViatraMatcher.java89
1 files changed, 89 insertions, 0 deletions
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalViatraMatcher.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalViatraMatcher.java
new file mode 100644
index 00000000..b9bc3f1e
--- /dev/null
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalViatraMatcher.java
@@ -0,0 +1,89 @@
1package tools.refinery.store.query.viatra.internal.matcher;
2
3import org.eclipse.viatra.query.runtime.matchers.backend.IQueryResultProvider;
4import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask;
5import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples;
6import org.eclipse.viatra.query.runtime.rete.index.Indexer;
7import org.eclipse.viatra.query.runtime.rete.matcher.RetePatternMatcher;
8import tools.refinery.store.map.Cursor;
9import tools.refinery.store.map.Cursors;
10import tools.refinery.store.query.ModelQueryAdapter;
11import tools.refinery.store.query.ResultSet;
12import tools.refinery.store.query.dnf.Query;
13import tools.refinery.store.query.dnf.RelationalQuery;
14import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl;
15import tools.refinery.store.tuple.TupleLike;
16
17/**
18 * Directly access the tuples inside a VIATRA pattern matcher.<p>
19 * This class neglects calling
20 * {@link org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext#wrapTuple(org.eclipse.viatra.query.runtime.matchers.tuple.Tuple)}
21 * and
22 * {@link org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext#unwrapTuple(org.eclipse.viatra.query.runtime.matchers.tuple.Tuple)},
23 * because {@link tools.refinery.store.query.viatra.internal.context.RelationalRuntimeContext} provides a trivial
24 * implementation for these methods.
25 * Using this class with any other runtime context may lead to undefined behavior.
26 */
27public class RelationalViatraMatcher implements ResultSet<Boolean> {
28 private final ViatraModelQueryAdapterImpl adapter;
29 private final RelationalQuery query;
30 private final TupleMask emptyMask;
31 private final TupleMask identityMask;
32 private final IQueryResultProvider backend;
33 private final Indexer emptyMaskIndexer;
34
35 public RelationalViatraMatcher(ViatraModelQueryAdapterImpl adapter, RelationalQuery query,
36 RawPatternMatcher rawPatternMatcher) {
37 this.adapter = adapter;
38 this.query = query;
39 int arity = query.arity();
40 emptyMask = TupleMask.empty(arity);
41 identityMask = TupleMask.identity(arity);
42 backend = rawPatternMatcher.getBackend();
43 if (backend instanceof RetePatternMatcher reteBackend) {
44 emptyMaskIndexer = IndexerUtils.getIndexer(reteBackend, emptyMask);
45 } else {
46 emptyMaskIndexer = null;
47 }
48 }
49
50 @Override
51 public ModelQueryAdapter getAdapter() {
52 return adapter;
53 }
54
55 @Override
56 public Query<Boolean> getQuery() {
57 return query;
58 }
59
60 @Override
61 public Boolean get(TupleLike parameters) {
62 var tuple = MatcherUtils.toViatraTuple(parameters);
63 if (emptyMaskIndexer == null) {
64 return backend.hasMatch(identityMask, tuple);
65 }
66 var matches = emptyMaskIndexer.get(Tuples.staticArityFlatTupleOf());
67 return matches != null && matches.contains(tuple);
68 }
69
70 @Override
71 public Cursor<TupleLike, Boolean> getAll() {
72 if (emptyMaskIndexer == null) {
73 var allMatches = backend.getAllMatches(emptyMask, Tuples.staticArityFlatTupleOf());
74 return new RelationalCursor(allMatches.iterator());
75 }
76 var matches = emptyMaskIndexer.get(Tuples.staticArityFlatTupleOf());
77 return matches == null ? Cursors.empty() : new RelationalCursor(matches.stream().iterator());
78 }
79
80 @Override
81 public int size() {
82 if (emptyMaskIndexer == null) {
83 return backend.countMatches(emptyMask, Tuples.staticArityFlatTupleOf());
84 }
85 var matches = emptyMaskIndexer.get(Tuples.staticArityFlatTupleOf());
86 return matches == null ? 0 : matches.size();
87 }
88
89}