diff options
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.java | 48 |
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 @@ | |||
1 | package tools.refinery.store.query.viatra.internal.matcher; | ||
2 | |||
3 | import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask; | ||
4 | import org.eclipse.viatra.query.runtime.rete.index.Indexer; | ||
5 | import org.eclipse.viatra.query.runtime.rete.matcher.ReteEngine; | ||
6 | import org.eclipse.viatra.query.runtime.rete.matcher.RetePatternMatcher; | ||
7 | import org.eclipse.viatra.query.runtime.rete.traceability.RecipeTraceInfo; | ||
8 | |||
9 | import java.lang.invoke.MethodHandle; | ||
10 | import java.lang.invoke.MethodHandles; | ||
11 | import java.lang.invoke.MethodType; | ||
12 | |||
13 | final 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 | } | ||