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