diff options
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.java | 281 |
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 | *******************************************************************************/ | ||
9 | package tools.refinery.viatra.runtime.matchers.context; | ||
10 | |||
11 | import java.lang.reflect.InvocationTargetException; | ||
12 | import java.util.Optional; | ||
13 | import java.util.concurrent.Callable; | ||
14 | |||
15 | import tools.refinery.viatra.runtime.matchers.planning.helpers.StatisticsHelper; | ||
16 | import tools.refinery.viatra.runtime.matchers.tuple.ITuple; | ||
17 | import tools.refinery.viatra.runtime.matchers.tuple.Tuple; | ||
18 | import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; | ||
19 | import 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 | */ | ||
28 | public 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 | } | ||