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