aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/context/IQueryRuntimeContext.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/context/IQueryRuntimeContext.java')
-rw-r--r--subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/context/IQueryRuntimeContext.java281
1 files changed, 281 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/context/IQueryRuntimeContext.java b/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/context/IQueryRuntimeContext.java
new file mode 100644
index 00000000..c2e90614
--- /dev/null
+++ b/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/context/IQueryRuntimeContext.java
@@ -0,0 +1,281 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Bergmann Gabor, Istvan Rath and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package tools.refinery.viatra.runtime.matchers.context;
10
11import java.lang.reflect.InvocationTargetException;
12import java.util.Optional;
13import java.util.concurrent.Callable;
14
15import tools.refinery.viatra.runtime.matchers.planning.helpers.StatisticsHelper;
16import tools.refinery.viatra.runtime.matchers.tuple.ITuple;
17import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
18import tools.refinery.viatra.runtime.matchers.tuple.TupleMask;
19import tools.refinery.viatra.runtime.matchers.util.Accuracy;
20
21/**
22 * Provides instance model information (relations corresponding to input keys) to query evaluator backends at runtime.
23 * Implementors shall extend {@link AbstractQueryRuntimeContext} instead directly this interface.
24 *
25 * @author Bergmann Gabor
26 * @noimplement This interface is not intended to be implemented by clients. Extend {@link AbstractQueryRuntimeContext} instead.
27 */
28public interface IQueryRuntimeContext {
29 /**
30 * Provides metamodel-specific info independent of the runtime instance model.
31 */
32 public IQueryMetaContext getMetaContext();
33
34
35 /**
36 * The given callable will be executed, and all model traversals will be delayed until the execution is done. If
37 * there are any outstanding information to be read from the model, a single coalesced model traversal will
38 * initialize the caches and deliver the notifications.
39 *
40 * <p> Calls may be nested. A single coalesced traversal will happen at the end of the outermost call.
41 *
42 * <p> <b>Caution: </b> results returned by the runtime context may be incomplete during the coalescing period, to be corrected by notifications sent during the final coalesced traversal.
43 * For example, if a certain input key is not cached yet, an empty relation may be reported during <code>callable.call()</code>; the cache will be constructed after the call terminates and notifications will deliver the entire content of the relation.
44 * Non-incremental query backends should therefore never enumerate input keys while coalesced (verify using {@link #isCoalescing()}).
45 *
46 * @param callable
47 */
48 public abstract <V> V coalesceTraversals(Callable<V> callable) throws InvocationTargetException;
49 /**
50 * @return true iff currently within a coalescing section (i.e. within the callable of a call to {@link #coalesceTraversals(Callable)}).
51 */
52 public boolean isCoalescing();
53
54 /**
55 * Returns true if index is available for the given key providing the given service.
56 * @throws IllegalArgumentException if key is not enumerable or an unknown type, see {@link IQueryMetaContext#isEnumerable(IInputKey)}.
57 * @since 1.4
58 */
59 public boolean isIndexed(IInputKey key, IndexingService service);
60
61 /**
62 * If the given (enumerable) input key is not yet indexed, the model will be traversed
63 * (after the end of the outermost coalescing block, see {@link IQueryRuntimeContext#coalesceTraversals(Callable)})
64 * so that the index can be built. It is possible that the base indexer will select a higher indexing level merging
65 * multiple indexing requests to an appropriate level.
66 *
67 * <p><b>Postcondition:</b> After invoking this method, {@link #getIndexed(IInputKey, IndexingService)} for the same key
68 * and service will be guaranteed to return the requested or a highing indexing level as soon as {@link #isCoalescing()} first returns false.
69 *
70 * <p><b>Precondition:</b> the given key is enumerable, see {@link IQueryMetaContext#isEnumerable(IInputKey)}.
71 * @throws IllegalArgumentException if key is not enumerable or an unknown type, see {@link IQueryMetaContext#isEnumerable(IInputKey)}.
72 * @since 1.4
73 */
74 public void ensureIndexed(IInputKey key, IndexingService service);
75
76 /**
77 * Returns the number of tuples in the extensional relation identified by the input key seeded with the given mask and tuple.
78 *
79 * @param key an input key
80 * @param seedMask
81 * a mask that extracts those parameters of the input key (from the entire parameter list) that should be
82 * bound to a fixed value; must not be null. <strong>Note</strong>: any given index must occur at most once in seedMask.
83 * @param seed
84 * the tuple of fixed values restricting the match set to be considered, in the same order as given in
85 * parameterSeedMask, so that for each considered match tuple,
86 * projectedParameterSeed.equals(parameterSeedMask.transform(match)) should hold. Must not be null.
87 *
88 * @return the number of tuples in the model for the given key and seed
89 *
90 * <p><b>Precondition:</b> the given key is enumerable, see {@link IQueryMetaContext#isEnumerable(IInputKey)}.
91 * @throws IllegalArgumentException if key is not enumerable, see {@link IQueryMetaContext#isEnumerable(IInputKey)}.
92 * @since 1.7
93 */
94 public int countTuples(IInputKey key, TupleMask seedMask, ITuple seed);
95
96
97 /**
98 * Gives an estimate of the number of different groups the tuples of the given relation are projected into by the given mask
99 * (e.g. for an identity mask, this means the full relation size). The estimate must meet the required accuracy.
100 *
101 * <p> Must accept any input key, even non-enumerables or those not recognized by this runtime context.
102 * If there is insufficient information to provide an answer up to the required precision, {@link Optional#empty()} is returned.
103 *
104 * <p> PRE: {@link TupleMask#isNonrepeating()} must hold for the group mask.
105 *
106 * @return if available, an estimate of the cardinality of the projection of the given extensional relation, with the desired accuracy.
107 *
108 * @since 2.1
109 */
110 public Optional<Long> estimateCardinality(IInputKey key, TupleMask groupMask, Accuracy requiredAccuracy);
111
112
113 /**
114 * Gives an estimate of the average size of different groups the tuples of the given relation are projected into by the given mask
115 * (e.g. for an identity mask, this means 1, while for an empty mask, the result is the full relation size).
116 * The estimate must meet the required accuracy.
117 *
118 * <p> Must accept any input key, even non-enumerables or those not recognized by this runtime context.
119 * If there is insufficient information to provide an answer up to the required precision, {@link Optional#empty()} may be returned.
120 *
121 * <p> For an empty relation, zero is acceptable as an exact answer.
122 *
123 * <p> PRE: {@link TupleMask#isNonrepeating()} must hold for the group mask.
124 *
125 * @return if available, an estimate of the average size of each projection group of the given extensional relation, with the desired accuracy.
126 *
127 * @since 2.1
128 */
129 public default Optional<Double> estimateAverageBucketSize(IInputKey key, TupleMask groupMask, Accuracy requiredAccuracy) {
130 if (key.isEnumerable()) {
131 return StatisticsHelper.estimateAverageBucketSize(groupMask, requiredAccuracy,
132 (mask, accuracy) -> this.estimateCardinality(key, mask, accuracy));
133 } else return groupMask.isIdentity() ? Optional.of(1.0) : Optional.empty();
134 }
135
136
137 /**
138 * Returns the tuples in the extensional relation identified by the input key, optionally seeded with the given tuple.
139 *
140 * @param key an input key
141 * @param seedMask
142 * a mask that extracts those parameters of the input key (from the entire parameter list) that should be
143 * bound to a fixed value; must not be null. <strong>Note</strong>: any given index must occur at most once in seedMask.
144 * @param seed
145 * the tuple of fixed values restricting the match set to be considered, in the same order as given in
146 * parameterSeedMask, so that for each considered match tuple,
147 * projectedParameterSeed.equals(parameterSeedMask.transform(match)) should hold. Must not be null.
148 * @return the tuples in the model for the given key and seed
149 *
150 * <p><b>Precondition:</b> the given key is enumerable, see {@link IQueryMetaContext#isEnumerable(IInputKey)}.
151 * @throws IllegalArgumentException if key is not enumerable, see {@link IQueryMetaContext#isEnumerable(IInputKey)}.
152 * @since 1.7
153 */
154 public Iterable<Tuple> enumerateTuples(IInputKey key, TupleMask seedMask, ITuple seed);
155
156 /**
157 * Simpler form of {@link #enumerateTuples(IInputKey, TupleMask, Tuple)} in the case where all values of the tuples
158 * are bound by the seed except for one.
159 *
160 * <p>
161 * Selects the tuples in the extensional relation identified by the input key, optionally seeded with the given
162 * tuple, and then returns the single value from each tuple which is not bound by the ssed mask.
163 *
164 * @param key
165 * an input key
166 * @param seedMask
167 * a mask that extracts those parameters of the input key (from the entire parameter list) that should be
168 * bound to a fixed value; must not be null. <strong>Note</strong>: any given index must occur at most
169 * once in seedMask, and seedMask must include all parameters in any arbitrary order except one.
170 * @param seed
171 * the tuple of fixed values restricting the match set to be considered, in the same order as given in
172 * parameterSeedMask, so that for each considered match tuple,
173 * projectedParameterSeed.equals(parameterSeedMask.transform(match)) should hold. Must not be null.
174 * @return the objects in the model for the given key and seed
175 *
176 * <p>
177 * <b>Precondition:</b> the given key is enumerable, see {@link IQueryMetaContext#isEnumerable(IInputKey)}.
178 * @throws IllegalArgumentException
179 * if key is not enumerable, see {@link IQueryMetaContext#isEnumerable(IInputKey)}.
180 * @since 1.7
181 */
182 public Iterable<? extends Object> enumerateValues(IInputKey key, TupleMask seedMask, ITuple seed);
183
184 /**
185 * Simpler form of {@link #enumerateTuples(IInputKey, TupleMask, Tuple)} in the case where all values of the tuples
186 * are bound by the seed.
187 *
188 * <p>
189 * Returns whether the given tuple is in the extensional relation identified by the input key.
190 *
191 * <p>
192 * Note: this call works for non-enumerable input keys as well.
193 *
194 * @param key
195 * an input key
196 * @param seed
197 * the tuple of fixed values restricting the match set to be considered, in the same order as given in
198 * parameterSeedMask, so that for each considered match tuple,
199 * projectedParameterSeed.equals(parameterSeedMask.transform(match)) should hold. Must not be null.
200 * @return true iff there is at least a single tuple contained in the relation that corresponds to the seed tuple
201 * @since 2.0
202 */
203 public boolean containsTuple(IInputKey key, ITuple seed);
204
205
206 /**
207 * Subscribes for updates in the extensional relation identified by the input key, optionally seeded with the given tuple.
208 * <p> This should be called after invoking
209 *
210 * @param key an input key
211 * @param seed can be null or a tuple with matching arity;
212 * if non-null, only those updates in the model are notified about
213 * that match the seed at positions where the seed is non-null.
214 * @param listener will be notified of future changes
215 *
216 * <p><b>Precondition:</b> the given key is enumerable, see {@link IQueryMetaContext#isEnumerable(IInputKey)}.
217 * @throws IllegalArgumentException if key is not enumerable, see {@link IQueryMetaContext#isEnumerable(IInputKey)}.
218 */
219 public void addUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener);
220
221 /**
222 * Unsubscribes from updates in the extensional relation identified by the input key, optionally seeded with the given tuple.
223 *
224 * @param key an input key
225 * @param seed can be null or a tuple with matching arity;
226 * if non-null, only those updates in the model are notified about
227 * that match the seed at positions where the seed is non-null.
228 * @param listener will no longer be notified of future changes
229 *
230 * <p><b>Precondition:</b> the given key is enumerable, see {@link IQueryMetaContext#isEnumerable(IInputKey)}.
231 * @throws IllegalArgumentException if key is not enumerable, see {@link IQueryMetaContext#isEnumerable(IInputKey)}.
232 */
233 public void removeUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener);
234 /*
235 TODO: uniqueness
236 */
237
238 /**
239 * Wraps the external element into the internal representation that is to be used by the query backend
240 * <p> model element -> internal object.
241 * <p> null must be mapped to null.
242 */
243 public Object wrapElement(Object externalElement);
244
245 /**
246 * Unwraps the internal representation of the element into its original form
247 * <p> internal object -> model element
248 * <p> null must be mapped to null.
249 */
250 public Object unwrapElement(Object internalElement);
251
252 /**
253 * Unwraps the tuple of elements into the internal representation that is to be used by the query backend
254 * <p> model elements -> internal objects
255 * <p> null must be mapped to null.
256 */
257 public Tuple wrapTuple(Tuple externalElements);
258
259 /**
260 * Unwraps the tuple of internal representations of elements into their original forms
261 * <p> internal objects -> model elements
262 * <p> null must be mapped to null.
263 */
264 public Tuple unwrapTuple(Tuple internalElements);
265
266 /**
267 * Starts wildcard indexing for the given service. After this call, no registration is required for this {@link IndexingService}.
268 * a previously set wildcard level cannot be lowered, only extended.
269 * @since 1.4
270 */
271 public void ensureWildcardIndexing(IndexingService service);
272
273 /**
274 * Execute the given runnable after traversal. It is guaranteed that the runnable is executed as soon as
275 * the indexing is finished. The callback is executed only once, then is removed from the callback queue.
276 * @param traversalCallback
277 * @throws InvocationTargetException
278 * @since 1.4
279 */
280 public void executeAfterTraversal(Runnable runnable) throws InvocationTargetException;
281}