use of org.apache.tinkerpop.gremlin.process.traversal.Traversal in project titan by thinkaurelius.
the class TitanLocalQueryOptimizerStrategy method apply.
@Override
public void apply(final Traversal.Admin<?, ?> traversal) {
if (!traversal.getGraph().isPresent())
return;
Graph graph = traversal.getGraph().get();
//If this is a compute graph then we can't apply local traversal optimisation at this stage.
StandardTitanGraph titanGraph = graph instanceof StandardTitanTx ? ((StandardTitanTx) graph).getGraph() : (StandardTitanGraph) graph;
final boolean useMultiQuery = traversal.getEngine().isStandard() && titanGraph.getConfiguration().useMultiQuery();
/*
====== VERTEX STEP ======
*/
TraversalHelper.getStepsOfClass(VertexStep.class, traversal).forEach(originalStep -> {
TitanVertexStep vstep = new TitanVertexStep(originalStep);
TraversalHelper.replaceStep(originalStep, vstep, traversal);
if (TitanTraversalUtil.isEdgeReturnStep(vstep)) {
HasStepFolder.foldInHasContainer(vstep, traversal);
}
assert TitanTraversalUtil.isEdgeReturnStep(vstep) || TitanTraversalUtil.isVertexReturnStep(vstep);
Step nextStep = TitanTraversalUtil.getNextNonIdentityStep(vstep);
if (nextStep instanceof RangeGlobalStep) {
int limit = QueryUtil.convertLimit(((RangeGlobalStep) nextStep).getHighRange());
vstep.setLimit(QueryUtil.mergeLimits(limit, vstep.getLimit()));
}
if (useMultiQuery) {
vstep.setUseMultiQuery(true);
}
});
/*
====== PROPERTIES STEP ======
*/
TraversalHelper.getStepsOfClass(PropertiesStep.class, traversal).forEach(originalStep -> {
TitanPropertiesStep vstep = new TitanPropertiesStep(originalStep);
TraversalHelper.replaceStep(originalStep, vstep, traversal);
if (vstep.getReturnType().forProperties()) {
HasStepFolder.foldInHasContainer(vstep, traversal);
}
if (useMultiQuery) {
vstep.setUseMultiQuery(true);
}
});
/*
====== EITHER INSIDE LOCAL ======
*/
TraversalHelper.getStepsOfClass(LocalStep.class, traversal).forEach(localStep -> {
Traversal.Admin localTraversal = ((LocalStep<?, ?>) localStep).getLocalChildren().get(0);
Step localStart = localTraversal.getStartStep();
if (localStart instanceof VertexStep) {
TitanVertexStep vstep = new TitanVertexStep((VertexStep) localStart);
TraversalHelper.replaceStep(localStart, vstep, localTraversal);
if (TitanTraversalUtil.isEdgeReturnStep(vstep)) {
HasStepFolder.foldInHasContainer(vstep, localTraversal);
HasStepFolder.foldInOrder(vstep, localTraversal, traversal, false);
}
HasStepFolder.foldInRange(vstep, localTraversal);
unfoldLocalTraversal(traversal, localStep, localTraversal, vstep, useMultiQuery);
}
if (localStart instanceof PropertiesStep) {
TitanPropertiesStep vstep = new TitanPropertiesStep((PropertiesStep) localStart);
TraversalHelper.replaceStep(localStart, vstep, localTraversal);
if (vstep.getReturnType().forProperties()) {
HasStepFolder.foldInHasContainer(vstep, localTraversal);
HasStepFolder.foldInOrder(vstep, localTraversal, traversal, false);
}
HasStepFolder.foldInRange(vstep, localTraversal);
unfoldLocalTraversal(traversal, localStep, localTraversal, vstep, useMultiQuery);
}
});
}
use of org.apache.tinkerpop.gremlin.process.traversal.Traversal in project titan by thinkaurelius.
the class TitanGraphTest method testTinkerPopOptimizationStrategies.
@Test
public void testTinkerPopOptimizationStrategies() {
PropertyKey id = mgmt.makePropertyKey("id").cardinality(Cardinality.SINGLE).dataType(Integer.class).make();
PropertyKey weight = mgmt.makePropertyKey("weight").cardinality(Cardinality.SINGLE).dataType(Integer.class).make();
mgmt.buildIndex("byId", Vertex.class).addKey(id).buildCompositeIndex();
mgmt.buildIndex("byWeight", Vertex.class).addKey(weight).buildCompositeIndex();
mgmt.buildIndex("byIdWeight", Vertex.class).addKey(id).addKey(weight).buildCompositeIndex();
EdgeLabel knows = mgmt.makeEdgeLabel("knows").make();
mgmt.buildEdgeIndex(knows, "byWeightDecr", Direction.OUT, decr, weight);
mgmt.buildEdgeIndex(knows, "byWeightIncr", Direction.OUT, incr, weight);
PropertyKey names = mgmt.makePropertyKey("names").cardinality(Cardinality.LIST).dataType(String.class).make();
mgmt.buildPropertyIndex(names, "namesByWeight", decr, weight);
finishSchema();
int numV = 100;
TitanVertex[] vs = new TitanVertex[numV];
for (int i = 0; i < numV; i++) {
vs[i] = graph.addVertex("id", i, "weight", i % 5);
}
int superV = 10;
int sid = -1;
TitanVertex[] sv = new TitanVertex[superV];
for (int i = 0; i < superV; i++) {
sv[i] = graph.addVertex("id", sid);
for (int j = 0; j < numV; j++) {
sv[i].addEdge("knows", vs[j], "weight", j % 5);
sv[i].property(VertexProperty.Cardinality.list, "names", "n" + j, "weight", j % 5);
}
}
Traversal t;
TraversalMetrics metrics;
GraphTraversalSource gts = graph.traversal();
//Edge
assertNumStep(numV / 5, 1, gts.V(sv[0]).outE("knows").has("weight", 1), TitanVertexStep.class);
assertNumStep(numV, 1, gts.V(sv[0]).outE("knows"), TitanVertexStep.class);
assertNumStep(numV, 1, gts.V(sv[0]).out("knows"), TitanVertexStep.class);
assertNumStep(10, 1, gts.V(sv[0]).local(__.outE("knows").limit(10)), TitanVertexStep.class);
assertNumStep(10, 1, gts.V(sv[0]).local(__.outE("knows").range(10, 20)), LocalStep.class);
assertNumStep(numV, 2, gts.V(sv[0]).outE("knows").order().by("weight", decr), TitanVertexStep.class, OrderGlobalStep.class);
assertNumStep(10, 1, gts.V(sv[0]).local(__.outE("knows").order().by("weight", decr).limit(10)), TitanVertexStep.class);
assertNumStep(numV / 5, 2, gts.V(sv[0]).outE("knows").has("weight", 1).order().by("weight", incr), TitanVertexStep.class, OrderGlobalStep.class);
assertNumStep(10, 1, gts.V(sv[0]).local(__.outE("knows").has("weight", 1).order().by("weight", incr).limit(10)), TitanVertexStep.class);
assertNumStep(5, 1, gts.V(sv[0]).local(__.outE("knows").has("weight", 1).has("weight", 1).order().by("weight", incr).range(10, 15)), LocalStep.class);
assertNumStep(1, 1, gts.V(sv[0]).outE("knows").filter(__.inV().is(vs[50])), TitanVertexStep.class);
assertNumStep(1, 1, gts.V(sv[0]).outE("knows").filter(__.otherV().is(vs[50])), TitanVertexStep.class);
assertNumStep(1, 1, gts.V(sv[0]).bothE("knows").filter(__.otherV().is(vs[50])), TitanVertexStep.class);
assertNumStep(1, 2, gts.V(sv[0]).bothE("knows").filter(__.inV().is(vs[50])), TitanVertexStep.class, TraversalFilterStep.class);
//Property
assertNumStep(numV / 5, 1, gts.V(sv[0]).properties("names").has("weight", 1), TitanPropertiesStep.class);
assertNumStep(numV, 1, gts.V(sv[0]).properties("names"), TitanPropertiesStep.class);
assertNumStep(10, 1, gts.V(sv[0]).local(__.properties("names").order().by("weight", decr).limit(10)), TitanPropertiesStep.class);
assertNumStep(numV, 2, gts.V(sv[0]).outE("knows").values("weight"), TitanVertexStep.class, TitanPropertiesStep.class);
//Global graph queries
assertNumStep(1, 1, gts.V().has("id", numV / 5), TitanGraphStep.class);
assertNumStep(1, 1, gts.V().has("id", numV / 5).has("weight", (numV / 5) % 5), TitanGraphStep.class);
assertNumStep(numV / 5, 1, gts.V().has("weight", 1), TitanGraphStep.class);
assertNumStep(10, 1, gts.V().has("weight", 1).range(0, 10), TitanGraphStep.class);
assertNumStep(superV, 1, gts.V().has("id", sid), TitanGraphStep.class);
//Ensure that as steps don't interfere
assertNumStep(1, 1, gts.V().has("id", numV / 5).as("x"), TitanGraphStep.class);
assertNumStep(1, 1, gts.V().has("id", numV / 5).has("weight", (numV / 5) % 5).as("x"), TitanGraphStep.class);
assertNumStep(superV * (numV / 5), 2, gts.V().has("id", sid).outE("knows").has("weight", 1), TitanGraphStep.class, TitanVertexStep.class);
assertNumStep(superV * (numV / 5 * 2), 2, gts.V().has("id", sid).outE("knows").has("weight", P.gte(1)).has("weight", P.lt(3)), TitanGraphStep.class, TitanVertexStep.class);
assertNumStep(superV * (numV / 5 * 2), 2, gts.V().has("id", sid).outE("knows").has("weight", P.between(1, 3)), TitanGraphStep.class, TitanVertexStep.class);
assertNumStep(superV * 10, 2, gts.V().has("id", sid).local(__.outE("knows").has("weight", P.gte(1)).has("weight", P.lt(3)).limit(10)), TitanGraphStep.class, TitanVertexStep.class);
assertNumStep(superV * 10, 2, gts.V().has("id", sid).local(__.outE("knows").has("weight", P.between(1, 3)).order().by("weight", decr).limit(10)), TitanGraphStep.class, TitanVertexStep.class);
clopen(option(USE_MULTIQUERY), true);
gts = graph.traversal();
assertNumStep(superV * (numV / 5), 2, gts.V().has("id", sid).outE("knows").has("weight", 1), TitanGraphStep.class, TitanVertexStep.class);
assertNumStep(superV * (numV / 5 * 2), 2, gts.V().has("id", sid).outE("knows").has("weight", P.between(1, 3)), TitanGraphStep.class, TitanVertexStep.class);
assertNumStep(superV * 10, 2, gts.V().has("id", sid).local(__.outE("knows").has("weight", P.gte(1)).has("weight", P.lt(3)).limit(10)), TitanGraphStep.class, TitanVertexStep.class);
assertNumStep(superV * 10, 2, gts.V().has("id", sid).local(__.outE("knows").has("weight", P.between(1, 3)).order().by("weight", decr).limit(10)), TitanGraphStep.class, TitanVertexStep.class);
assertNumStep(superV * numV, 2, gts.V().has("id", sid).values("names"), TitanGraphStep.class, TitanPropertiesStep.class);
//Verify traversal metrics when all reads are from cache (i.e. no backend queries)
t = gts.V().has("id", sid).local(__.outE("knows").has("weight", P.between(1, 3)).order().by("weight", decr).limit(10)).profile();
assertCount(superV * 10, t);
metrics = (TraversalMetrics) t.asAdmin().getSideEffects().get("~metrics").get();
verifyMetrics(metrics.getMetrics(0), true, false);
verifyMetrics(metrics.getMetrics(1), true, true);
//Verify that properties also use multi query
t = gts.V().has("id", sid).values("names").profile();
assertCount(superV * numV, t);
metrics = (TraversalMetrics) t.asAdmin().getSideEffects().get("~metrics").get();
verifyMetrics(metrics.getMetrics(0), true, false);
verifyMetrics(metrics.getMetrics(1), true, true);
clopen(option(USE_MULTIQUERY), true);
gts = graph.traversal();
//Verify traversal metrics when having to read from backend [same query as above]
t = gts.V().has("id", sid).local(__.outE("knows").has("weight", P.gte(1)).has("weight", P.lt(3)).order().by("weight", decr).limit(10)).profile();
assertCount(superV * 10, t);
metrics = (TraversalMetrics) t.asAdmin().getSideEffects().get("~metrics").get();
// System.out.println(metrics);
verifyMetrics(metrics.getMetrics(0), false, false);
verifyMetrics(metrics.getMetrics(1), false, true);
//Verify that properties also use multi query [same query as above]
t = gts.V().has("id", sid).values("names").profile();
assertCount(superV * numV, t);
metrics = (TraversalMetrics) t.asAdmin().getSideEffects().get("~metrics").get();
// System.out.println(metrics);
verifyMetrics(metrics.getMetrics(0), false, false);
verifyMetrics(metrics.getMetrics(1), false, true);
}
Aggregations