aboutsummaryrefslogtreecommitdiffstats
path: root/model-data/src/main/java/org/eclipse/viatra/solver/data/query/internal/RelationalRuntimeContext.java
diff options
context:
space:
mode:
Diffstat (limited to 'model-data/src/main/java/org/eclipse/viatra/solver/data/query/internal/RelationalRuntimeContext.java')
-rw-r--r--model-data/src/main/java/org/eclipse/viatra/solver/data/query/internal/RelationalRuntimeContext.java183
1 files changed, 183 insertions, 0 deletions
diff --git a/model-data/src/main/java/org/eclipse/viatra/solver/data/query/internal/RelationalRuntimeContext.java b/model-data/src/main/java/org/eclipse/viatra/solver/data/query/internal/RelationalRuntimeContext.java
new file mode 100644
index 00000000..8f6fb8dd
--- /dev/null
+++ b/model-data/src/main/java/org/eclipse/viatra/solver/data/query/internal/RelationalRuntimeContext.java
@@ -0,0 +1,183 @@
1package org.eclipse.viatra.solver.data.query.internal;
2
3import static org.eclipse.viatra.solver.data.util.CollectionsUtil.filter;
4import static org.eclipse.viatra.solver.data.util.CollectionsUtil.map;
5
6import java.lang.reflect.InvocationTargetException;
7import java.util.Iterator;
8import java.util.Optional;
9import java.util.concurrent.Callable;
10
11import org.eclipse.viatra.query.runtime.base.core.NavigationHelperImpl;
12import org.eclipse.viatra.query.runtime.matchers.context.IInputKey;
13import org.eclipse.viatra.query.runtime.matchers.context.IQueryMetaContext;
14import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext;
15import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener;
16import org.eclipse.viatra.query.runtime.matchers.context.IndexingService;
17import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple;
18import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple;
19import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask;
20import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples;
21import org.eclipse.viatra.query.runtime.matchers.util.Accuracy;
22
23public class RelationalRuntimeContext implements IQueryRuntimeContext {
24 private final RelationalQueryMetaContext metaContext = new RelationalQueryMetaContext();
25 private final RelationUpdateListener relationUpdateListener;
26
27 public RelationalRuntimeContext(RelationUpdateListener relationUpdateListener) {
28 this.relationUpdateListener = relationUpdateListener;
29 }
30
31 @Override
32 public IQueryMetaContext getMetaContext() {
33 return metaContext;
34 }
35
36 //
37 /**
38 * TODO: check {@link NavigationHelperImpl#coalesceTraversals(Callable)}
39 */
40 @Override
41 public <V> V coalesceTraversals(Callable<V> callable) throws InvocationTargetException {
42 try {
43 return callable.call();
44 } catch (Exception e) {
45 throw new InvocationTargetException(e);
46 }
47 }
48
49 @Override
50 public boolean isCoalescing() {
51 return true;
52 }
53
54 @Override
55 public boolean isIndexed(IInputKey key, IndexingService service) {
56 if(key instanceof RelationViewKey<?>) {
57 RelationViewKey<?> relationalKey = (RelationViewKey<?>) key;
58 return this.relationUpdateListener.containsRelationalView(relationalKey);
59 } else {
60 return false;
61 }
62 }
63
64 @Override
65 public void ensureIndexed(IInputKey key, IndexingService service) {
66 if(!isIndexed(key, service)) {
67 throw new IllegalStateException("Engine tries to index a new key " +key);
68 }
69 }
70
71 RelationViewKey<?> checkKey(IInputKey key) {
72 if(key instanceof RelationViewKey) {
73 RelationViewKey<?> relationViewKey = (RelationViewKey<?>) key;
74 if(relationUpdateListener.containsRelationalView(relationViewKey)) {
75 return relationViewKey;
76 } else {
77 throw new IllegalStateException("Query is asking for non-indexed key");
78 }
79 } else {
80 throw new IllegalStateException("Query is asking for non-relational key");
81 }
82 }
83
84 @Override
85 public int countTuples(IInputKey key, TupleMask seedMask, ITuple seed) {
86 RelationViewKey<?> relationalViewKey = checkKey(key);
87 Iterable<Object[]> allObjects = relationalViewKey.getWrappedKey().getAll();
88 Iterable<Object[]> filteredBySeed = filter(allObjects,objectArray -> isMatching(objectArray,seedMask,seed));
89 Iterator<Object[]> iterator = filteredBySeed.iterator();
90 int result = 0;
91 while(iterator.hasNext()) {
92 iterator.next();
93 result++;
94 }
95 return result;
96 }
97
98 @Override
99 public Optional<Long> estimateCardinality(IInputKey key, TupleMask groupMask, Accuracy requiredAccuracy) {
100 return Optional.empty();
101 }
102
103 @Override
104 public Iterable<Tuple> enumerateTuples(IInputKey key, TupleMask seedMask, ITuple seed) {
105 RelationViewKey<?> relationalViewKey = checkKey(key);
106 Iterable<Object[]> allObjects = relationalViewKey.getWrappedKey().getAll();
107 Iterable<Object[]> filteredBySeed = filter(allObjects,objectArray -> isMatching(objectArray,seedMask,seed));
108 return map(filteredBySeed,Tuples::flatTupleOf);
109 }
110
111 private boolean isMatching(Object[] tuple, TupleMask seedMask, ITuple seed) {
112 for(int i=0; i<seedMask.indices.length; i++) {
113 final Object seedElement = seed.get(i);
114 final Object tupleElement = tuple[seedMask.indices[i]];
115 if(!tupleElement.equals(seedElement)) {
116 return false;
117 }
118 }
119 return true;
120 }
121// private Object[] toObjectMask(RelationViewKey<?> relationalViewKey, TupleMask seedMask, ITuple seed) {
122// final int arity = relationalViewKey.getArity();
123// Object[] result = new Object[arity];
124// for(int i = 0; i<seedMask.indices.length; i++) {
125// result[seedMask.indices[i]] = seed.get(i);
126// }
127// return result;
128// }
129
130 @Override
131 public Iterable<? extends Object> enumerateValues(IInputKey key, TupleMask seedMask, ITuple seed) {
132 return enumerateTuples(key, seedMask, seed);
133 }
134
135 @Override
136 public boolean containsTuple(IInputKey key, ITuple seed) {
137 RelationViewKey<?> relationalViewKey = checkKey(key);
138 return relationalViewKey.getWrappedKey().get(seed.getElements());
139 }
140
141 @Override
142 public void addUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) {
143 RelationViewKey<?> relationalKey = checkKey(key);
144 this.relationUpdateListener.addListener(relationalKey, seed, listener);
145
146 }
147
148 @Override
149 public void removeUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) {
150 RelationViewKey<?> relationalKey = checkKey(key);
151 this.relationUpdateListener.removeListener(relationalKey, seed, listener);
152 }
153
154 @Override
155 public Object wrapElement(Object externalElement) {
156 return externalElement;
157 }
158
159 @Override
160 public Object unwrapElement(Object internalElement) {
161 return internalElement;
162 }
163
164 @Override
165 public Tuple wrapTuple(Tuple externalElements) {
166 return externalElements;
167 }
168
169 @Override
170 public Tuple unwrapTuple(Tuple internalElements) {
171 return internalElements;
172 }
173
174 @Override
175 public void ensureWildcardIndexing(IndexingService service) {
176 throw new UnsupportedOperationException();
177 }
178
179 @Override
180 public void executeAfterTraversal(Runnable runnable) throws InvocationTargetException {
181 runnable.run();
182 }
183}