diff options
author | 2023-03-01 21:20:10 +0100 | |
---|---|---|
committer | 2023-03-01 21:20:10 +0100 | |
commit | 2bf484cd882949c53a82c40e28319f74ef8ae477 (patch) | |
tree | 083eb6793b0fc6fd77f402c51cd5579cfa4c56a2 | |
parent | refactor: more direct access to VIATRA result set (diff) | |
download | refinery-2bf484cd882949c53a82c40e28319f74ef8ae477.tar.gz refinery-2bf484cd882949c53a82c40e28319f74ef8ae477.tar.zst refinery-2bf484cd882949c53a82c40e28319f74ef8ae477.zip |
refactor: use Cursor in query result sets
6 files changed, 94 insertions, 17 deletions
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RawPatternMatcher.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RawPatternMatcher.java index 8f56586e..5924ff15 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RawPatternMatcher.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RawPatternMatcher.java | |||
@@ -9,13 +9,13 @@ import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask; | |||
9 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | 9 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; |
10 | import org.eclipse.viatra.query.runtime.rete.index.Indexer; | 10 | import org.eclipse.viatra.query.runtime.rete.index.Indexer; |
11 | import org.eclipse.viatra.query.runtime.rete.matcher.RetePatternMatcher; | 11 | import org.eclipse.viatra.query.runtime.rete.matcher.RetePatternMatcher; |
12 | import tools.refinery.store.map.Cursor; | ||
13 | import tools.refinery.store.map.Cursors; | ||
12 | import tools.refinery.store.query.ResultSet; | 14 | import tools.refinery.store.query.ResultSet; |
13 | import tools.refinery.store.query.viatra.ViatraTupleLike; | 15 | import tools.refinery.store.query.viatra.ViatraTupleLike; |
14 | import tools.refinery.store.tuple.Tuple; | 16 | import tools.refinery.store.tuple.Tuple; |
15 | import tools.refinery.store.tuple.TupleLike; | 17 | import tools.refinery.store.tuple.TupleLike; |
16 | 18 | ||
17 | import java.util.stream.Stream; | ||
18 | |||
19 | /** | 19 | /** |
20 | * Directly access the tuples inside a VIATRA pattern matcher.<p> | 20 | * Directly access the tuples inside a VIATRA pattern matcher.<p> |
21 | * This class neglects calling | 21 | * This class neglects calling |
@@ -64,12 +64,12 @@ public class RawPatternMatcher extends GenericPatternMatcher implements ResultSe | |||
64 | } | 64 | } |
65 | 65 | ||
66 | @Override | 66 | @Override |
67 | public Stream<TupleLike> allResults() { | 67 | public Cursor<TupleLike, Boolean> allResults() { |
68 | if (emptyMaskIndexer == null) { | 68 | if (emptyMaskIndexer == null) { |
69 | return backend.getAllMatches(empty).map(ViatraTupleLike::new); | 69 | return new ResultSetCursor(backend.getAllMatches(empty).iterator()); |
70 | } | 70 | } |
71 | var matches = emptyMaskIndexer.get(Tuples.staticArityFlatTupleOf()); | 71 | var matches = emptyMaskIndexer.get(Tuples.staticArityFlatTupleOf()); |
72 | return matches == null ? Stream.of() : matches.stream().map(ViatraTupleLike::new); | 72 | return matches == null ? Cursors.empty() : new ResultSetCursor(matches.stream().iterator()); |
73 | } | 73 | } |
74 | 74 | ||
75 | @Override | 75 | @Override |
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/ResultSetCursor.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/ResultSetCursor.java new file mode 100644 index 00000000..5e6d1970 --- /dev/null +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/ResultSetCursor.java | |||
@@ -0,0 +1,43 @@ | |||
1 | package tools.refinery.store.query.viatra.internal.pquery; | ||
2 | |||
3 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; | ||
4 | import tools.refinery.store.map.Cursor; | ||
5 | import tools.refinery.store.query.viatra.ViatraTupleLike; | ||
6 | import tools.refinery.store.tuple.TupleLike; | ||
7 | |||
8 | import java.util.Iterator; | ||
9 | |||
10 | class ResultSetCursor implements Cursor<TupleLike, Boolean> { | ||
11 | private final Iterator<? extends ITuple> tuplesIterator; | ||
12 | private boolean terminated; | ||
13 | private TupleLike key; | ||
14 | |||
15 | public ResultSetCursor(Iterator<? extends ITuple> tuplesIterator) { | ||
16 | this.tuplesIterator = tuplesIterator; | ||
17 | } | ||
18 | |||
19 | @Override | ||
20 | public TupleLike getKey() { | ||
21 | return key; | ||
22 | } | ||
23 | |||
24 | @Override | ||
25 | public Boolean getValue() { | ||
26 | return true; | ||
27 | } | ||
28 | |||
29 | @Override | ||
30 | public boolean isTerminated() { | ||
31 | return terminated; | ||
32 | } | ||
33 | |||
34 | @Override | ||
35 | public boolean move() { | ||
36 | if (!terminated && tuplesIterator.hasNext()) { | ||
37 | key = new ViatraTupleLike(tuplesIterator.next()); | ||
38 | return true; | ||
39 | } | ||
40 | terminated = true; | ||
41 | return false; | ||
42 | } | ||
43 | } | ||
diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTest.java index 3dd517c4..8b25419d 100644 --- a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTest.java +++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTest.java | |||
@@ -1,6 +1,7 @@ | |||
1 | package tools.refinery.store.query.viatra; | 1 | package tools.refinery.store.query.viatra; |
2 | 2 | ||
3 | import org.junit.jupiter.api.Test; | 3 | import org.junit.jupiter.api.Test; |
4 | import tools.refinery.store.map.Cursor; | ||
4 | import tools.refinery.store.model.ModelStore; | 5 | import tools.refinery.store.model.ModelStore; |
5 | import tools.refinery.store.query.Dnf; | 6 | import tools.refinery.store.query.Dnf; |
6 | import tools.refinery.store.query.ModelQuery; | 7 | import tools.refinery.store.query.ModelQuery; |
@@ -14,7 +15,6 @@ import tools.refinery.store.tuple.TupleLike; | |||
14 | 15 | ||
15 | import java.util.HashSet; | 16 | import java.util.HashSet; |
16 | import java.util.Set; | 17 | import java.util.Set; |
17 | import java.util.stream.Stream; | ||
18 | 18 | ||
19 | import static org.junit.jupiter.api.Assertions.*; | 19 | import static org.junit.jupiter.api.Assertions.*; |
20 | import static tools.refinery.store.query.literal.Literals.not; | 20 | import static tools.refinery.store.query.literal.Literals.not; |
@@ -712,11 +712,10 @@ class QueryTest { | |||
712 | assertThrows(IllegalArgumentException.class, () -> queryBuilder.queries(predicate)); | 712 | assertThrows(IllegalArgumentException.class, () -> queryBuilder.queries(predicate)); |
713 | } | 713 | } |
714 | 714 | ||
715 | static void compareMatchSets(Stream<TupleLike> matchSet, Set<Tuple> expected) { | 715 | private static void compareMatchSets(Cursor<TupleLike, Boolean> cursor, Set<Tuple> expected) { |
716 | Set<Tuple> translatedMatchSet = new HashSet<>(); | 716 | Set<Tuple> translatedMatchSet = new HashSet<>(); |
717 | var iterator = matchSet.iterator(); | 717 | while (cursor.move()) { |
718 | while (iterator.hasNext()) { | 718 | var element = cursor.getKey(); |
719 | var element = iterator.next(); | ||
720 | translatedMatchSet.add(element.toTuple()); | 719 | translatedMatchSet.add(element.toTuple()); |
721 | } | 720 | } |
722 | assertEquals(expected, translatedMatchSet); | 721 | assertEquals(expected, translatedMatchSet); |
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/EmptyResultSet.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/EmptyResultSet.java index 0c2e07d6..9ff6df26 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/EmptyResultSet.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/EmptyResultSet.java | |||
@@ -1,9 +1,9 @@ | |||
1 | package tools.refinery.store.query; | 1 | package tools.refinery.store.query; |
2 | 2 | ||
3 | import tools.refinery.store.map.Cursor; | ||
4 | import tools.refinery.store.map.Cursors; | ||
3 | import tools.refinery.store.tuple.TupleLike; | 5 | import tools.refinery.store.tuple.TupleLike; |
4 | 6 | ||
5 | import java.util.stream.Stream; | ||
6 | |||
7 | public class EmptyResultSet implements ResultSet { | 7 | public class EmptyResultSet implements ResultSet { |
8 | @Override | 8 | @Override |
9 | public boolean hasResult(TupleLike parameters) { | 9 | public boolean hasResult(TupleLike parameters) { |
@@ -11,8 +11,8 @@ public class EmptyResultSet implements ResultSet { | |||
11 | } | 11 | } |
12 | 12 | ||
13 | @Override | 13 | @Override |
14 | public Stream<TupleLike> allResults() { | 14 | public Cursor<TupleLike, Boolean> allResults() { |
15 | return Stream.of(); | 15 | return Cursors.empty(); |
16 | } | 16 | } |
17 | 17 | ||
18 | @Override | 18 | @Override |
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/ResultSet.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/ResultSet.java index 407cf075..d2b8c9dd 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/ResultSet.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/ResultSet.java | |||
@@ -1,9 +1,8 @@ | |||
1 | package tools.refinery.store.query; | 1 | package tools.refinery.store.query; |
2 | 2 | ||
3 | import tools.refinery.store.map.Cursor; | ||
3 | import tools.refinery.store.tuple.TupleLike; | 4 | import tools.refinery.store.tuple.TupleLike; |
4 | 5 | ||
5 | import java.util.stream.Stream; | ||
6 | |||
7 | public interface ResultSet { | 6 | public interface ResultSet { |
8 | default boolean hasResult() { | 7 | default boolean hasResult() { |
9 | return countResults() > 0; | 8 | return countResults() > 0; |
@@ -11,7 +10,7 @@ public interface ResultSet { | |||
11 | 10 | ||
12 | boolean hasResult(TupleLike parameters); | 11 | boolean hasResult(TupleLike parameters); |
13 | 12 | ||
14 | Stream<TupleLike> allResults(); | 13 | Cursor<TupleLike, Boolean> allResults(); |
15 | 14 | ||
16 | int countResults(); | 15 | int countResults(); |
17 | } | 16 | } |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/Cursors.java b/subprojects/store/src/main/java/tools/refinery/store/map/Cursors.java new file mode 100644 index 00000000..fc8e628b --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/map/Cursors.java | |||
@@ -0,0 +1,36 @@ | |||
1 | package tools.refinery.store.map; | ||
2 | |||
3 | public final class Cursors { | ||
4 | private Cursors() { | ||
5 | throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); | ||
6 | } | ||
7 | |||
8 | public static <K, V> Cursor<K, V> empty() { | ||
9 | return new Empty<>(); | ||
10 | } | ||
11 | |||
12 | private static class Empty<K, V> implements Cursor<K, V> { | ||
13 | private boolean terminated = false; | ||
14 | |||
15 | @Override | ||
16 | public K getKey() { | ||
17 | return null; | ||
18 | } | ||
19 | |||
20 | @Override | ||
21 | public V getValue() { | ||
22 | return null; | ||
23 | } | ||
24 | |||
25 | @Override | ||
26 | public boolean isTerminated() { | ||
27 | return terminated; | ||
28 | } | ||
29 | |||
30 | @Override | ||
31 | public boolean move() { | ||
32 | terminated = true; | ||
33 | return false; | ||
34 | } | ||
35 | } | ||
36 | } | ||