Skip to content

Commit

Permalink
[GIE-IR] support SimplePath and AllV in path expand operator (#2005)
Browse files Browse the repository at this point in the history
* [GIE Proto] add ExpandOption in PathExpand op
* [GIE Runtime] support simple_path() in runtime
* [IR Compiler] support Simple and AllV of path expand in grammar
* [GIE/IR] Supporting `PathOpt` and `ResultOpt` in ffi functions.

Co-authored-by: BingqingLyu <lv_bingqing@163.com>
Co-authored-by: longbin.lailb <longbin.lailb@alibaba-inc.com>
  • Loading branch information
3 people authored Sep 8, 2022
1 parent 1f98021 commit 159a27b
Show file tree
Hide file tree
Showing 24 changed files with 567 additions and 142 deletions.
8 changes: 8 additions & 0 deletions interactive_engine/compiler/src/main/antlr4/GremlinGS.g4
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ traversalMethod
| traversalMethod_aggregate_func
| traversalMethod_hasNot // hasNot()
| traversalMethod_coin // coin()
| traversalMethod_with // with()
;

traversalSourceSpawnMethod_V
Expand Down Expand Up @@ -156,6 +157,13 @@ traversalMethod_bothE
: 'bothE' LPAREN stringLiteralList RPAREN (DOT traversalMethod_otherV)?
;

// case-insensitive
// with('PATH_OPT', 'SIMPLE' | 'ARBITRARY')
// with('RESULT_OPT', 'ALL_V' | 'END_V')
traversalMethod_with
: 'with' LPAREN stringLiteral COMMA stringLiteral RPAREN
;

// outV()
traversalMethod_outV
: 'outV' LPAREN RPAREN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,9 @@ public Pointer apply(InterOpBase baseOp) {

Pointer expand = EXPAND_OP.apply(baseOp);
// todo: make isWholePath configurable
Pointer pathExpand = irCoreLib.initPathxpdOperator(expand, false);
Pointer pathExpand =
irCoreLib.initPathxpdOperator(
expand, pathOp.getPathOpt(), pathOp.getResultOpt());
irCoreLib.setPathxpdHops(pathExpand, lower, upper);

Optional<OpArg> aliasOpt = baseOp.getAlias();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,26 @@

package com.alibaba.graphscope.common.intermediate.operator;

import com.alibaba.graphscope.common.jna.type.PathOpt;
import com.alibaba.graphscope.common.jna.type.ResultOpt;

import java.util.Optional;

public class PathExpandOp extends ExpandOp {
private Optional<OpArg> lower;

private Optional<OpArg> upper;

private PathOpt pathOpt;

private ResultOpt resultOpt;

public PathExpandOp() {
super();
lower = Optional.empty();
upper = Optional.empty();
this.lower = Optional.empty();
this.upper = Optional.empty();
this.pathOpt = PathOpt.Arbitrary;
this.resultOpt = ResultOpt.EndV;
}

public PathExpandOp(ExpandOp other) {
Expand Down Expand Up @@ -60,4 +69,20 @@ public void setLower(OpArg lower) {
public void setUpper(OpArg upper) {
this.upper = Optional.of(upper);
}

public PathOpt getPathOpt() {
return pathOpt;
}

public ResultOpt getResultOpt() {
return resultOpt;
}

public void setPathOpt(PathOpt pathOpt) {
this.pathOpt = pathOpt;
}

public void setResultOpt(ResultOpt resultOpt) {
this.resultOpt = resultOpt;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ FfiResult.ByValue appendGetvOperator(
FfiResult.ByValue appendApplyOperator(
Pointer plan, Pointer apply, int parent, IntByReference oprIdx);

Pointer initPathxpdOperator(Pointer expand, boolean isWholePath);
Pointer initPathxpdOperator(Pointer expand, PathOpt pathOpt, ResultOpt resultOpt);

FfiResult.ByValue setPathxpdAlias(Pointer pathXpd, FfiAlias.ByValue alias);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,25 @@
* limitations under the License.
*/

package com.alibaba.graphscope.gremlin.antlr4;
package com.alibaba.graphscope.common.jna.type;

import org.apache.tinkerpop.gremlin.process.traversal.P;
import com.alibaba.graphscope.common.jna.IntEnum;

public class ExprP extends P<String> {
public ExprP(String expr) {
super(null, expr);
public enum PathOpt implements IntEnum<PathOpt> {
Arbitrary,
Simple;

@Override
public int getInt() {
return this.ordinal();
}

@Override
public PathOpt getEnum(int i) {
PathOpt opts[] = values();
if (i < opts.length && i >= 0) {
return opts[i];
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2020 Alibaba Group Holding Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.alibaba.graphscope.common.jna.type;

import com.alibaba.graphscope.common.jna.IntEnum;

public enum ResultOpt implements IntEnum<ResultOpt> {
EndV,
AllV;

@Override
public int getInt() {
return this.ordinal();
}

@Override
public ResultOpt getEnum(int i) {
ResultOpt opts[] = values();
if (i < opts.length && i >= 0) {
return opts[i];
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,6 @@ public InterOpCollection build() throws OpArgIllegalException, UnsupportedStepEx
opList.add(StepTransformFactory.SUBGRAPH_STEP.apply(step));
} else if (Utils.equalClass(step, IdentityStep.class)) {
opList.add(StepTransformFactory.IDENTITY_STEP.apply(step));
} else if (Utils.equalClass(step, CoinStep.class)) {
throw new UnsupportedStepException(
step.getClass(), "coin() should follow V() or E()");
} else {
throw new UnsupportedStepException(step.getClass(), "unimplemented yet");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,21 @@
import com.alibaba.graphscope.gremlin.Utils;
import com.alibaba.graphscope.gremlin.exception.UnsupportedEvalException;
import com.alibaba.graphscope.gremlin.plugin.step.ExprStep;
import com.alibaba.graphscope.gremlin.plugin.step.PathExpandStep;
import com.alibaba.graphscope.gremlin.plugin.traversal.IrCustomizedTraversal;

import org.apache.tinkerpop.gremlin.language.grammar.GremlinGSBaseVisitor;
import org.apache.tinkerpop.gremlin.language.grammar.GremlinGSParser;
import org.apache.tinkerpop.gremlin.process.traversal.Order;
import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.DedupGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.RangeGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.GraphStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderGlobalStep;
import org.apache.tinkerpop.gremlin.structure.Column;
import org.apache.tinkerpop.gremlin.structure.T;
Expand Down Expand Up @@ -696,24 +699,41 @@ public Traversal visitTraversalMethod_match(GremlinGSParser.TraversalMethod_matc
}

@Override
public GraphTraversal visitTraversalMethod_subgraph(
public Traversal visitTraversalMethod_subgraph(
final GremlinGSParser.TraversalMethod_subgraphContext ctx) {
return graphTraversal.subgraph(GenericLiteralVisitor.getStringLiteral(ctx.stringLiteral()));
}

@Override
public GraphTraversal visitTraversalMethod_bothV(
public Traversal visitTraversalMethod_bothV(
final GremlinGSParser.TraversalMethod_bothVContext ctx) {
return graphTraversal.bothV();
}

@Override
public GraphTraversal visitTraversalMethod_coin(
public Traversal visitTraversalMethod_coin(
final GremlinGSParser.TraversalMethod_coinContext ctx) {
Step endStep = graphTraversal.asAdmin().getEndStep();
if (!(endStep instanceof GraphStep)) {
throw new UnsupportedEvalException(
ctx.getClass(), "coin should follow source step, i.e. V().coin(0.2)");
}
return graphTraversal.coin(Double.valueOf(ctx.floatLiteral().getText()));
}

public Traversal visitExpr(
@Override
public Traversal visitTraversalMethod_with(GremlinGSParser.TraversalMethod_withContext ctx) {
Step endStep = graphTraversal.asAdmin().getEndStep();
if (!(endStep instanceof PathExpandStep)) {
throw new UnsupportedEvalException(
ctx.getClass(), "with should follow path expand, i.e. out('1..2').with(..)");
}
String optKey = GenericLiteralVisitor.getStringLiteral(ctx.stringLiteral(0));
String optValue = GenericLiteralVisitor.getStringLiteral(ctx.stringLiteral(1));
return graphTraversal.with(optKey, optValue);
}

private Traversal visitExpr(
GremlinGSParser.TraversalMethod_exprContext ctx, ExprStep.Type type) {
if (ctx.stringLiteral() != null) {
IrCustomizedTraversal traversal = (IrCustomizedTraversal) graphTraversal;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.alibaba.graphscope.gremlin.plugin.step;

import com.alibaba.graphscope.common.jna.type.FfiExpandOpt;
import com.google.common.base.Objects;

import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
Expand Down Expand Up @@ -75,4 +76,28 @@ public void setExpandOpt(FfiExpandOpt opt) {
public FfiExpandOpt getExpandOpt() {
return this.expandOpt;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
ExpandFusionStep<?> that = (ExpandFusionStep<?>) o;
return Objects.equal(hasContainers, that.hasContainers) && expandOpt == that.expandOpt;
}

@Override
public String toString() {
return "ExpandFusionStep{"
+ "hasContainers="
+ hasContainers
+ ", expandOpt="
+ expandOpt
+ '}';
}

@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), hasContainers, expandOpt);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@

package com.alibaba.graphscope.gremlin.plugin.step;

import com.alibaba.graphscope.common.jna.type.PathOpt;
import com.alibaba.graphscope.common.jna.type.ResultOpt;
import com.alibaba.graphscope.gremlin.exception.ExtendGremlinStepException;
import com.google.common.base.Objects;

import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.RangeGlobalStep;
Expand All @@ -25,6 +28,8 @@

public class PathExpandStep extends ExpandFusionStep<Vertex> {
private Traversal rangeTraversal;
private PathOpt pathOpt;
private ResultOpt resultOpt;

public PathExpandStep(
final Traversal.Admin traversal,
Expand All @@ -33,6 +38,9 @@ public PathExpandStep(
final String... edgeLabels) {
super(traversal, Vertex.class, direction, edgeLabels);
this.rangeTraversal = rangeTraversal;
// default value
this.pathOpt = PathOpt.Arbitrary;
this.resultOpt = ResultOpt.EndV;
}

public int getLower() {
Expand All @@ -56,4 +64,88 @@ public int getUpper() {
"rangeTraversal should only have one RangeGlobalStep");
}
}

public PathOpt getPathOpt() {
return pathOpt;
}

public ResultOpt getResultOpt() {
return resultOpt;
}

@Override
public void configure(final Object... keyValues) {
String originalKey = (String) keyValues[0];
String originalVal = (String) keyValues[1];
String key = toCamelCaseInsensitive(originalKey);
String value = toCamelCaseInsensitive(originalVal);
if (key.equals("PathOpt")) {
if (value.equals("Arbitrary") || value.equals("Simple")) {
this.pathOpt = PathOpt.valueOf(value);
} else {
throw new ExtendGremlinStepException(
"value "
+ originalVal
+ " is invalid, use ARBITRARY or SIMPLE instead (case"
+ " insensitive)");
}
} else if (key.equals("ResultOpt")) {
if (value.equals("AllV") || value.equals("EndV")) {
this.resultOpt = ResultOpt.valueOf(value);
} else {
throw new ExtendGremlinStepException(
"value "
+ originalVal
+ " is invalid, use ALL_V or END_V instead (case insensitive)");
}
} else {
throw new ExtendGremlinStepException(
"key "
+ originalKey
+ " is invalid, use PATH_OPT or RESULT_OPT instead (case insensitive)");
}
}

// convert string of underscore format to camel case in a case-insensitive way
private String toCamelCaseInsensitive(String underscore) {
String[] splits = underscore.split("_");
String camelCase = "";
for (int i = 0; i < splits.length; ++i) {
String split = splits[i];
camelCase +=
split.isEmpty()
? split
: Character.toUpperCase(split.charAt(0))
+ split.substring(1).toLowerCase();
}
return camelCase;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
PathExpandStep that = (PathExpandStep) o;
return Objects.equal(rangeTraversal, that.rangeTraversal)
&& pathOpt == that.pathOpt
&& resultOpt == that.resultOpt;
}

@Override
public String toString() {
return "PathExpandStep{"
+ "rangeTraversal="
+ rangeTraversal
+ ", pathOpt="
+ pathOpt
+ ", resultOpt="
+ resultOpt
+ '}';
}

@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), rangeTraversal, pathOpt, resultOpt);
}
}
Loading

0 comments on commit 159a27b

Please sign in to comment.