aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchHints.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchHints.java')
-rw-r--r--subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchHints.java306
1 files changed, 306 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchHints.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchHints.java
new file mode 100644
index 00000000..5f3895be
--- /dev/null
+++ b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchHints.java
@@ -0,0 +1,306 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Grill Balázs, IncQuery Labs Ltd.
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.localsearch.matcher.integration;
10
11import tools.refinery.viatra.runtime.localsearch.planner.cost.ICostFunction;
12import tools.refinery.viatra.runtime.localsearch.planner.cost.impl.IndexerBasedConstraintCostFunction;
13import tools.refinery.viatra.runtime.localsearch.planner.cost.impl.StatisticsBasedConstraintCostFunction;
14import tools.refinery.viatra.runtime.matchers.backend.*;
15import tools.refinery.viatra.runtime.matchers.psystem.rewriters.IFlattenCallPredicate;
16import tools.refinery.viatra.runtime.matchers.psystem.rewriters.IRewriterTraceCollector;
17import tools.refinery.viatra.runtime.matchers.psystem.rewriters.NopTraceCollector;
18
19import java.util.HashMap;
20import java.util.Map;
21import java.util.Objects;
22
23import static tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchHintOptions.*;
24import static tools.refinery.viatra.runtime.matchers.backend.CommonQueryHintOptions.normalizationTraceCollector;
25
26/**
27 * Type safe builder and extractor for Local search specific hints
28 *
29 * @author Grill Balázs
30 * @since 1.4
31 *
32 */
33public final class LocalSearchHints implements IMatcherCapability {
34
35 private Boolean useBase = null;
36
37 private Integer rowCount = null;
38
39 private ICostFunction costFunction = null;
40
41 private IFlattenCallPredicate flattenCallPredicate = null;
42
43 private ICallDelegationStrategy callDelegationStrategy = null;
44
45 private IAdornmentProvider adornmentProvider = null;
46
47 private IRewriterTraceCollector traceCollector = NopTraceCollector.INSTANCE;
48
49 private IQueryBackendFactory backendFactory = null;
50
51 private LocalSearchHints() {}
52
53 /**
54 * Return the default settings overridden by the given hints
55 */
56 public static LocalSearchHints getDefaultOverriddenBy(QueryEvaluationHint overridingHint){
57 return parse(getDefault().build(overridingHint));
58 }
59
60 /**
61 * Default settings which are considered the most safe, providing a reasonable performance for most of the cases. Assumes the availability of the base indexer.
62 */
63 public static LocalSearchHints getDefault(){
64 return getDefaultGeneric();
65 }
66
67 /**
68 * Initializes the generic (not EMF specific) search backend with the default settings
69 * @since 1.7
70 */
71 public static LocalSearchHints getDefaultGeneric(){
72 LocalSearchHints result = new LocalSearchHints();
73 result.useBase = true; // Should be unused; but a false value might cause surprises as an engine-default hint
74 result.rowCount = 4;
75 result.costFunction = new IndexerBasedConstraintCostFunction(StatisticsBasedConstraintCostFunction.INVERSE_NAVIGATION_PENALTY_GENERIC);
76 result.flattenCallPredicate = FLATTEN_CALL_PREDICATE.getDefaultValue();
77 result.callDelegationStrategy = ICallDelegationStrategy.FULL_BACKEND_ADHESION;
78 result.adornmentProvider = new LazyPlanningAdornments();
79 result.backendFactory = LocalSearchGenericBackendFactory.INSTANCE;
80 return result;
81 }
82
83 /**
84 * Initializes the default search backend with hybrid-enabled settings
85 * @since 2.1
86 */
87 public static LocalSearchHints getDefaultHybrid(){
88 LocalSearchHints result = getDefault();
89 result.callDelegationStrategy = ICallDelegationStrategy.PARTIAL_BACKEND_ADHESION;
90 result.flattenCallPredicate = new IFlattenCallPredicate.And(
91 new DontFlattenIncrementalPredicate(), new DontFlattenDisjunctive());
92 return result;
93 }
94
95 /**
96 * Initializes the generic (not EMF specific) search backend with hybrid-enabled settings
97 * @since 2.1
98 */
99 public static LocalSearchHints getDefaultGenericHybrid(){
100 LocalSearchHints result = getDefaultGeneric();
101 result.callDelegationStrategy = ICallDelegationStrategy.PARTIAL_BACKEND_ADHESION;
102 result.flattenCallPredicate = new IFlattenCallPredicate.And(
103 new DontFlattenIncrementalPredicate(), new DontFlattenDisjunctive());
104 return result;
105 }
106
107 public static LocalSearchHints parse(QueryEvaluationHint hint){
108 LocalSearchHints result = new LocalSearchHints();
109
110 result.useBase = USE_BASE_INDEX.getValueOrNull(hint);
111 result.rowCount = PLANNER_TABLE_ROW_COUNT.getValueOrNull(hint);
112 result.flattenCallPredicate = FLATTEN_CALL_PREDICATE.getValueOrNull(hint);
113 result.callDelegationStrategy = CALL_DELEGATION_STRATEGY.getValueOrNull(hint);
114 result.costFunction = PLANNER_COST_FUNCTION.getValueOrNull(hint);
115 result.adornmentProvider = ADORNMENT_PROVIDER.getValueOrNull(hint);
116 result.traceCollector = normalizationTraceCollector.getValueOrDefault(hint);
117
118 return result;
119 }
120
121
122 private Map<QueryHintOption<?>, Object> calculateHintMap() {
123 Map<QueryHintOption<?>, Object> map = new HashMap<>();
124 if (useBase != null){
125 USE_BASE_INDEX.insertOverridingValue(map, useBase);
126 }
127 if (rowCount != null){
128 PLANNER_TABLE_ROW_COUNT.insertOverridingValue(map, rowCount);
129 }
130 if (costFunction != null){
131 PLANNER_COST_FUNCTION.insertOverridingValue(map, costFunction);
132 }
133 if (flattenCallPredicate != null){
134 FLATTEN_CALL_PREDICATE.insertOverridingValue(map, flattenCallPredicate);
135 }
136 if (callDelegationStrategy != null){
137 CALL_DELEGATION_STRATEGY.insertOverridingValue(map, callDelegationStrategy);
138 }
139 if (adornmentProvider != null){
140 ADORNMENT_PROVIDER.insertOverridingValue(map, adornmentProvider);
141 }
142 if (traceCollector != null){
143 normalizationTraceCollector.insertOverridingValue(map, traceCollector);
144 }
145 return map;
146 }
147
148 public QueryEvaluationHint build(){
149 Map<QueryHintOption<?>, Object> map = calculateHintMap();
150 return new QueryEvaluationHint(map, backendFactory);
151 }
152
153 /**
154 * @since 1.7
155 */
156 public QueryEvaluationHint build(QueryEvaluationHint overridingHint) {
157 if (overridingHint == null)
158 return build();
159
160 IQueryBackendFactory factory = (overridingHint.getQueryBackendFactory() == null)
161 ? this.backendFactory
162 : overridingHint.getQueryBackendFactory();
163
164 Map<QueryHintOption<?>, Object> hints = calculateHintMap();
165 if (overridingHint.getBackendHintSettings() != null) {
166 hints.putAll(overridingHint.getBackendHintSettings());
167 }
168
169 return new QueryEvaluationHint(hints, factory);
170 }
171
172 public boolean isUseBase() {
173 return useBase;
174 }
175
176 public ICostFunction getCostFunction() {
177 return costFunction;
178 }
179
180 public IFlattenCallPredicate getFlattenCallPredicate() {
181 return flattenCallPredicate;
182 }
183
184 /**
185 * @since 2.1
186 */
187 public ICallDelegationStrategy getCallDelegationStrategy() {
188 return callDelegationStrategy;
189 }
190
191 public Integer getRowCount() {
192 return rowCount;
193 }
194
195 /**
196 * @since 1.5
197 */
198 public IAdornmentProvider getAdornmentProvider() {
199 return adornmentProvider;
200 }
201
202 /**
203 * @since 1.6
204 */
205 public IRewriterTraceCollector getTraceCollector() {
206 return traceCollector == null ? normalizationTraceCollector.getDefaultValue() : traceCollector;
207 }
208
209 public LocalSearchHints setUseBase(boolean useBase) {
210 this.useBase = useBase;
211 return this;
212 }
213
214 public LocalSearchHints setRowCount(int rowCount) {
215 this.rowCount = rowCount;
216 return this;
217 }
218
219 public LocalSearchHints setCostFunction(ICostFunction costFunction) {
220 this.costFunction = costFunction;
221 return this;
222 }
223
224 public LocalSearchHints setFlattenCallPredicate(IFlattenCallPredicate flattenCallPredicate) {
225 this.flattenCallPredicate = flattenCallPredicate;
226 return this;
227 }
228
229
230 /**
231 * @since 2.1
232 */
233 public LocalSearchHints setCallDelegationStrategy(ICallDelegationStrategy callDelegationStrategy) {
234 this.callDelegationStrategy = callDelegationStrategy;
235 return this;
236 }
237
238 /**
239 * @since 1.6
240 */
241 public LocalSearchHints setTraceCollector(IRewriterTraceCollector traceCollector) {
242 this.traceCollector = traceCollector;
243 return this;
244 }
245
246 /**
247 * @since 1.5
248 */
249 public LocalSearchHints setAdornmentProvider(IAdornmentProvider adornmentProvider) {
250 this.adornmentProvider = adornmentProvider;
251 return this;
252 }
253
254 public static LocalSearchHints customizeUseBase(boolean useBase){
255 return new LocalSearchHints().setUseBase(useBase);
256 }
257
258 public static LocalSearchHints customizeRowCount(int rowCount){
259 return new LocalSearchHints().setRowCount(rowCount);
260 }
261
262 public static LocalSearchHints customizeCostFunction(ICostFunction costFunction){
263 return new LocalSearchHints().setCostFunction(costFunction);
264 }
265
266 public static LocalSearchHints customizeFlattenCallPredicate(IFlattenCallPredicate predicate){
267 return new LocalSearchHints().setFlattenCallPredicate(predicate);
268 }
269
270 /**
271 * @since 2.1
272 */
273 public static LocalSearchHints customizeCallDelegationStrategy(ICallDelegationStrategy strategy){
274 return new LocalSearchHints().setCallDelegationStrategy(strategy);
275 }
276
277 /**
278 * @since 1.5
279 */
280 public static LocalSearchHints customizeAdornmentProvider(IAdornmentProvider adornmentProvider){
281 return new LocalSearchHints().setAdornmentProvider(adornmentProvider);
282 }
283
284 /**
285 * @since 1.6
286 */
287 public static LocalSearchHints customizeTraceCollector(IRewriterTraceCollector traceCollector){
288 return new LocalSearchHints().setTraceCollector(traceCollector);
289 }
290
291 @Override
292 public boolean canBeSubstitute(IMatcherCapability capability) {
293 if (capability instanceof LocalSearchHints){
294 LocalSearchHints other = (LocalSearchHints)capability;
295 /*
296 * We allow substitution of matchers if their functionally relevant settings are equal.
297 */
298 return Objects.equals(other.useBase, useBase);
299 }
300 /*
301 * For any other cases (e.g. for Rete), we cannot assume
302 * that matchers created by LS are functionally equivalent.
303 */
304 return false;
305 }
306}