aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/IndexerUtils.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/IndexerUtils.java')
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/IndexerUtils.java48
1 files changed, 48 insertions, 0 deletions
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/IndexerUtils.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/IndexerUtils.java
new file mode 100644
index 00000000..55eb8c44
--- /dev/null
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/IndexerUtils.java
@@ -0,0 +1,48 @@
1package tools.refinery.store.query.viatra.internal.matcher;
2
3import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask;
4import org.eclipse.viatra.query.runtime.rete.index.Indexer;
5import org.eclipse.viatra.query.runtime.rete.matcher.ReteEngine;
6import org.eclipse.viatra.query.runtime.rete.matcher.RetePatternMatcher;
7import org.eclipse.viatra.query.runtime.rete.traceability.RecipeTraceInfo;
8
9import java.lang.invoke.MethodHandle;
10import java.lang.invoke.MethodHandles;
11import java.lang.invoke.MethodType;
12
13final class IndexerUtils {
14 private static final MethodHandle GET_ENGINE_HANDLE;
15 private static final MethodHandle GET_PRODUCTION_NODE_TRACE_HANDLE;
16 private static final MethodHandle ACCESS_PROJECTION_HANDLE;
17
18 static {
19 try {
20 var lookup = MethodHandles.privateLookupIn(RetePatternMatcher.class, MethodHandles.lookup());
21 GET_ENGINE_HANDLE = lookup.findGetter(RetePatternMatcher.class, "engine", ReteEngine.class);
22 GET_PRODUCTION_NODE_TRACE_HANDLE = lookup.findGetter(RetePatternMatcher.class, "productionNodeTrace",
23 RecipeTraceInfo.class);
24 ACCESS_PROJECTION_HANDLE = lookup.findVirtual(ReteEngine.class, "accessProjection",
25 MethodType.methodType(Indexer.class, RecipeTraceInfo.class, TupleMask.class));
26 } catch (IllegalAccessException | NoSuchFieldException | NoSuchMethodException e) {
27 throw new IllegalStateException("Cannot access private members of %s"
28 .formatted(RetePatternMatcher.class.getPackageName()), e);
29 }
30 }
31
32 private IndexerUtils() {
33 throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
34 }
35
36 public static Indexer getIndexer(RetePatternMatcher backend, TupleMask mask) {
37 try {
38 var engine = (ReteEngine) GET_ENGINE_HANDLE.invokeExact(backend);
39 var trace = (RecipeTraceInfo) GET_PRODUCTION_NODE_TRACE_HANDLE.invokeExact(backend);
40 return (Indexer) ACCESS_PROJECTION_HANDLE.invokeExact(engine, trace, mask);
41 } catch (Error e) {
42 // Fatal JVM errors should not be wrapped.
43 throw e;
44 } catch (Throwable e) {
45 throw new IllegalStateException("Cannot access matcher for mask " + mask, e);
46 }
47 }
48}