diff options
| author | Zoltan Ujhelyi | 2017-06-29 09:00:51 +0000 |
|---|---|---|
| committer | Zoltan Ujhelyi | 2017-07-11 09:45:55 +0000 |
| commit | 93b8b9243c74b6c1e67fb58cec27813295f9dded (patch) | |
| tree | ebd88da9d6596402397570b33b12af63e6f6cfff | |
| parent | aee1e492e61a238edd804dba7becd53af5a6f664 (diff) | |
| download | org.eclipse.viatra-93b8b9243c74b6c1e67fb58cec27813295f9dded.tar.gz org.eclipse.viatra-93b8b9243c74b6c1e67fb58cec27813295f9dded.tar.xz org.eclipse.viatra-93b8b9243c74b6c1e67fb58cec27813295f9dded.zip | |
[469149] Provided generic search operations
Change-Id: I4dfbc4f1b7e44ece2697a75b31a09c6c6ea1fee2
4 files changed, 245 insertions, 11 deletions
diff --git a/query/plugins/org.eclipse.viatra.query.runtime.localsearch/src/org/eclipse/viatra/query/runtime/localsearch/matcher/ISearchContext.java b/query/plugins/org.eclipse.viatra.query.runtime.localsearch/src/org/eclipse/viatra/query/runtime/localsearch/matcher/ISearchContext.java index 9863fae52..d3e767b09 100644 --- a/query/plugins/org.eclipse.viatra.query.runtime.localsearch/src/org/eclipse/viatra/query/runtime/localsearch/matcher/ISearchContext.java +++ b/query/plugins/org.eclipse.viatra.query.runtime.localsearch/src/org/eclipse/viatra/query/runtime/localsearch/matcher/ISearchContext.java @@ -13,7 +13,6 @@ package org.eclipse.viatra.query.runtime.localsearch.matcher; import java.util.Collections; import java.util.Set; -import org.apache.log4j.Logger; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EDataType; import org.eclipse.emf.ecore.EStructuralFeature; @@ -21,6 +20,7 @@ import org.eclipse.viatra.query.runtime.api.scope.IBaseIndex; import org.eclipse.viatra.query.runtime.base.api.IndexingLevel; import org.eclipse.viatra.query.runtime.base.api.NavigationHelper; import org.eclipse.viatra.query.runtime.emf.EMFBaseIndexWrapper; +import org.eclipse.viatra.query.runtime.emf.EMFQueryRuntimeContext; import org.eclipse.viatra.query.runtime.exception.ViatraQueryException; import org.eclipse.viatra.query.runtime.localsearch.exceptions.LocalSearchException; import org.eclipse.viatra.query.runtime.localsearch.matcher.integration.IAdornmentProvider; @@ -28,13 +28,17 @@ import org.eclipse.viatra.query.runtime.localsearch.matcher.integration.LocalSea import org.eclipse.viatra.query.runtime.matchers.backend.IQueryResultProvider; import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; import org.eclipse.viatra.query.runtime.matchers.backend.QueryHintOption; +import org.eclipse.viatra.query.runtime.matchers.context.IQueryBackendContext; import org.eclipse.viatra.query.runtime.matchers.context.IQueryResultProviderAccess; +import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext; import org.eclipse.viatra.query.runtime.matchers.planning.QueryProcessingException; import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery; import org.eclipse.viatra.query.runtime.matchers.util.ICache; import org.eclipse.viatra.query.runtime.matchers.util.IProvider; +import com.google.common.base.Preconditions; + /** * The {@link ISearchContext} interface allows search operations to reuse platform services such as the indexer. * @@ -44,14 +48,21 @@ import org.eclipse.viatra.query.runtime.matchers.util.IProvider; * @noextend This interface is not intended to be extended by clients. * */ -public interface ISearchContext{ +public interface ISearchContext { /** * Provides access to the EMF-specific base index for search operation; do not use if not on EMF Scope + * @throws IllegalStateException if called on a non-EMF backend */ NavigationHelper getBaseIndex(); /** + * Provides access to the generic query runtime context of the current engine + * @since 1.7 + */ + IQueryRuntimeContext getRuntimeContext(); + + /** * @param classes * @param dataTypes * @param features @@ -82,18 +93,34 @@ public interface ISearchContext{ */ public class SearchContext implements ISearchContext { - final NavigationHelper navigationHelper; - final IQueryResultProviderAccess resultProviderAccess; - final QueryEvaluationHint overrideHints; + private final NavigationHelper navigationHelper; + private final IQueryResultProviderAccess resultProviderAccess; + private final QueryEvaluationHint overrideHints; + private final IQueryRuntimeContext runtimeContext; - final ICache backendLevelCache; - - final Logger logger = Logger.getLogger(getClass()); + private final ICache backendLevelCache; + /** + * Initializes a search context using an EMF context + */ + public SearchContext(IQueryBackendContext backendContext, IBaseIndex baseIndex, QueryEvaluationHint overrideHints, ICache backendLevelCache) throws ViatraQueryException { + this.runtimeContext = backendContext.getRuntimeContext(); + Preconditions.checkArgument(runtimeContext instanceof EMFQueryRuntimeContext, "EMF-specific context only works with EMF runtime context"); //XXX this is a problematic (and in long-term unsupported) solution, see bug 456815 - public SearchContext(IBaseIndex baseIndex, IQueryResultProviderAccess resultProviderAccess, QueryEvaluationHint overrideHints, ICache backendLevelCache) throws ViatraQueryException { this.navigationHelper = ((EMFBaseIndexWrapper)baseIndex).getNavigationHelper(); - this.resultProviderAccess = resultProviderAccess; + this.resultProviderAccess = backendContext.getResultProviderAccess(); + this.overrideHints = overrideHints; + + this.backendLevelCache = backendLevelCache; + } + + /** + * Initializes a search context using an arbitrary backend context + */ + public SearchContext(IQueryBackendContext backendContext, QueryEvaluationHint overrideHints, ICache backendLevelCache) throws ViatraQueryException { + this.runtimeContext = backendContext.getRuntimeContext(); + this.navigationHelper = null; + this.resultProviderAccess = backendContext.getResultProviderAccess(); this.overrideHints = overrideHints; this.backendLevelCache = backendLevelCache; @@ -109,6 +136,9 @@ public interface ISearchContext{ @Override public NavigationHelper getBaseIndex() { + if (navigationHelper == null) { + throw new IllegalStateException("The EMF API of the Base index is not available"); + } return navigationHelper; } @@ -146,6 +176,10 @@ public interface ISearchContext{ public <T> T accessBackendLevelCache(Object key, Class<? extends T> clazz, IProvider<T> valueProvider) { return backendLevelCache.getValue(key, clazz, valueProvider); } + + public IQueryRuntimeContext getRuntimeContext() { + return runtimeContext; + } } } diff --git a/query/plugins/org.eclipse.viatra.query.runtime.localsearch/src/org/eclipse/viatra/query/runtime/localsearch/matcher/integration/LocalSearchResultProvider.java b/query/plugins/org.eclipse.viatra.query.runtime.localsearch/src/org/eclipse/viatra/query/runtime/localsearch/matcher/integration/LocalSearchResultProvider.java index 18116860c..4d42d5933 100644 --- a/query/plugins/org.eclipse.viatra.query.runtime.localsearch/src/org/eclipse/viatra/query/runtime/localsearch/matcher/integration/LocalSearchResultProvider.java +++ b/query/plugins/org.eclipse.viatra.query.runtime.localsearch/src/org/eclipse/viatra/query/runtime/localsearch/matcher/integration/LocalSearchResultProvider.java @@ -166,7 +166,7 @@ public class LocalSearchResultProvider implements IQueryResultProvider { this.runtimeContext = context.getRuntimeContext(); try { - searchContext = new ISearchContext.SearchContext(engine.getBaseIndex(), resultProviderAccess, userHints, backend.getCache()); + searchContext = new ISearchContext.SearchContext(context, engine.getBaseIndex(), userHints, backend.getCache()); } catch (ViatraQueryException e) { throw new QueryProcessingException("Could not create search context for {1}", new String[]{query.getFullyQualifiedName()}, e.getMessage(), query, e); } diff --git a/query/plugins/org.eclipse.viatra.query.runtime.localsearch/src/org/eclipse/viatra/query/runtime/localsearch/operations/generic/GenericTypeCheck.java b/query/plugins/org.eclipse.viatra.query.runtime.localsearch/src/org/eclipse/viatra/query/runtime/localsearch/operations/generic/GenericTypeCheck.java new file mode 100644 index 000000000..f0140d3e2 --- /dev/null +++ b/query/plugins/org.eclipse.viatra.query.runtime.localsearch/src/org/eclipse/viatra/query/runtime/localsearch/operations/generic/GenericTypeCheck.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2010-2017, Zoltan Ujhelyi, IncQuery Labs Ltd. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Zoltan Ujhelyi - initial API and implementation + *******************************************************************************/ +package org.eclipse.viatra.query.runtime.localsearch.operations.generic; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.viatra.query.runtime.localsearch.MatchingFrame; +import org.eclipse.viatra.query.runtime.localsearch.exceptions.LocalSearchException; +import org.eclipse.viatra.query.runtime.localsearch.matcher.ISearchContext; +import org.eclipse.viatra.query.runtime.localsearch.operations.IIteratingSearchOperation; +import org.eclipse.viatra.query.runtime.localsearch.operations.check.CheckOperation; +import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; +import org.eclipse.viatra.query.runtime.matchers.tuple.FlatTuple; + +import com.google.common.base.Function; +import com.google.common.base.Joiner; +import com.google.common.base.Preconditions; +import com.google.common.collect.Iterators; + +/** + * @author Zoltan Ujhelyi + * @since 1.7 + * @noextend This class is not intended to be subclassed by clients. + */ +public class GenericTypeCheck extends CheckOperation implements IIteratingSearchOperation { + + private final IInputKey type; + private final Integer[] positions; + + public GenericTypeCheck(IInputKey type, Integer[] positions) { + Preconditions.checkArgument(positions.length == type.getArity(), + "The type %s requires %s parameters, but %s positions are provided", type.getPrettyPrintableName(), + type.getArity(), positions.length); + this.positions = positions; + this.type = type; + } + + @Override + public List<Integer> getVariablePositions() { + return Arrays.asList(positions); + } + + @Override + protected boolean check(MatchingFrame frame, ISearchContext context) throws LocalSearchException { + Object[] seed = new Object[positions.length]; + for (int i = 0; i < positions.length; i++) { + seed[i] = frame.get(positions[i]); + } + return context.getRuntimeContext().containsTuple(type, new FlatTuple(seed)); + } + + @Override + public String toString() { + Iterator<String> parameterIndexii = Iterators.transform(Iterators.forArray(positions), + new Function<Integer, String>() { + + @Override + public String apply(Integer input) { + return String.format("+%d", input); + } + }); + return "check " + type.getPrettyPrintableName() + "(" + Joiner.on(", ").join(parameterIndexii) + ")"; + } + + @Override + public IInputKey getIteratedInputKey() { + return type; + } +} diff --git a/query/plugins/org.eclipse.viatra.query.runtime.localsearch/src/org/eclipse/viatra/query/runtime/localsearch/operations/generic/GenericTypeExtend.java b/query/plugins/org.eclipse.viatra.query.runtime.localsearch/src/org/eclipse/viatra/query/runtime/localsearch/operations/generic/GenericTypeExtend.java new file mode 100644 index 000000000..94cf0674f --- /dev/null +++ b/query/plugins/org.eclipse.viatra.query.runtime.localsearch/src/org/eclipse/viatra/query/runtime/localsearch/operations/generic/GenericTypeExtend.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (c) 2010-2017, Zoltan Ujhelyi, IncQuery Labs Ltd. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Zoltan Ujhelyi - initial API and implementation + *******************************************************************************/ +package org.eclipse.viatra.query.runtime.localsearch.operations.generic; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.eclipse.viatra.query.runtime.localsearch.MatchingFrame; +import org.eclipse.viatra.query.runtime.localsearch.exceptions.LocalSearchException; +import org.eclipse.viatra.query.runtime.localsearch.matcher.ISearchContext; +import org.eclipse.viatra.query.runtime.localsearch.operations.IIteratingSearchOperation; +import org.eclipse.viatra.query.runtime.localsearch.operations.ISearchOperation; +import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; +import org.eclipse.viatra.query.runtime.matchers.tuple.FlatTuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; + +import com.google.common.base.Function; +import com.google.common.base.Joiner; +import com.google.common.base.Preconditions; +import com.google.common.collect.Iterators; + +/** + * @author Zoltan Ujhelyi + * @since 1.7 + * @noextend This class is not intended to be subclassed by clients. + */ +public class GenericTypeExtend implements ISearchOperation, IIteratingSearchOperation { + + private final IInputKey type; + private final Integer[] positions; + private final Set<Integer> unboundVariableIndex; + private Iterator<Tuple> it; + + /** + * + * @param type + * the type to execute the extend operation on + * @param positions + * the parameter positions that represent the variables of the input key + * @param adornment + * the set of positions that are bound at the start of the operation + */ + public GenericTypeExtend(IInputKey type, Integer[] positions, Set<Integer> adornment) { + Preconditions.checkArgument(positions.length == type.getArity(), + "The type %s requires %s parameters, but %s positions are provided", type.getPrettyPrintableName(), + type.getArity(), positions.length); + this.positions = positions; + this.type = type; + + this.unboundVariableIndex = new HashSet<Integer>(); + for (Integer position : positions) { + if (!adornment.contains(position)) { + unboundVariableIndex.add(position); + } + } + } + + @Override + public IInputKey getIteratedInputKey() { + return type; + } + + @Override + public void onBacktrack(MatchingFrame frame, ISearchContext context) throws LocalSearchException { + for (Integer position : unboundVariableIndex) { + frame.setValue(position, null); + } + } + + @Override + public void onInitialize(MatchingFrame frame, ISearchContext context) throws LocalSearchException { + Object[] seed = new Object[positions.length]; + for (int i = 0; i < positions.length; i++) { + seed[i] = frame.get(positions[i]); + } + it = context.getRuntimeContext().enumerateTuples(type, new FlatTuple(seed)).iterator(); + + } + + @Override + public boolean execute(MatchingFrame frame, ISearchContext context) throws LocalSearchException { + if (it.hasNext()) { + final Tuple next = it.next(); + for (int i : unboundVariableIndex) { + frame.setValue(positions[i], next.get(i)); + } + return true; + } else { + return false; + } + } + + @Override + public List<Integer> getVariablePositions() { + return Arrays.asList(positions); + } + + @Override + public String toString() { + Iterator<String> parameterNames = Iterators.transform(Iterators.forArray(positions), + new Function<Integer, String>() { + + @Override + public String apply(Integer input) { + return String.format("%s%d", unboundVariableIndex.contains(input) ? "-" : "+", input); + } + }); + return "extend " + type.getPrettyPrintableName() + "(" + Joiner.on(", ").join(parameterNames) + ")"; + } +} |
