I wonder if the right thing to do here is to determine whether your Traverser already has a legitimate Path, rather than requiring this optimized step to require Path unconditionally (or based on properties of child steps, of which there are none). By "legitimate Path", I mean a Path that is not EmptyPath. That way, you can avoid calling Path.extend unless it is necessary.
The harder question (to me) is how to allow a single step to perform multiple Path.extend calls. As Pieter points out, you can't set the Path of a Traverser. ImmutablePath returns a new Path, but what are you supposed to do with it? Do you need to use TraverserGenerator somehow? Traverser.Admin.split? On Wed, Jul 1, 2015 at 12:40 PM, Marko Rodriguez <[email protected]> wrote: > If you need a Traverser that has path information, then you need to > specify that you step getRequirements() has PATH in it. > > See: > > https://github.com/apache/incubator-tinkerpop/blob/master/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PathStep.java#L95-L97 > > Though, if your Step is not a TraversalParent, then its just > EnumSet.of(PATH). > > Realize that path computations are expensive so if you can be selective > about when to turn them on or off you will be better off. For instance, see: > > > https://github.com/apache/incubator-tinkerpop/blob/master/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStep.java#L114-L118 > > HTH, > Marko. > > http://markorodriguez.com > > On Jul 1, 2015, at 1:19 PM, pieter-gmail <[email protected]> wrote: > > > I got as far as looking at Path.extend(). It returns the extended path > > but I do not know how to set the traverser's path to the new extended > > one. There is no setPath(path). > > > > Looking at split and clone now to see whats possible. > > > > Currently when select() fires there is only a EmptyPath. > > > > However I notice when optimized the traverser is B_O_S_SE_SL_Traverser > > and when un-optimize it is B_O_P_S_SE_SL_Traverser > > > > Not quite sure where this difference is coming from. > > > > Thanks > > Pieter > > > > On 01/07/2015 20:47, Marko Rodriguez wrote: > >> Hi, > >> > >> You then just need to add the edge to the path which is done with > Path.extend(). > >> > >> Is it not working as you expect? > >> > >> Marko. > >> > >> http://markorodriguez.com > >> > >> On Jul 1, 2015, at 12:39 PM, pieter-gmail <[email protected]> > wrote: > >> > >>> To explain what I am doing from a sql point of view is as follows. > >>> > >>> If un-optimized, I first execute a query to return the "outB" edges, > >>> then for each edge I execute another query the retrieve the inV(). > >>> > >>> The optimization is to makes this happen in one query. Reducing round > >>> trips has order of magnitude performance benefits for sqlg. > >>> > >>> When I do not collapse the steps into one I see that the .select("e", > >>> "B") part happens in SelectStep.map where the labeled object is > >>> retrieved from Path.objects() where the object was saved as it was > >>> touched by the traverser. > >>> > >>> Now that I have collapsed the steps there is no place where the edge is > >>> traversed and stored on the path. > >>> Instead I retrieve the labeled edges and the vertices all in one step. > >>> > >>> At the "//what to do" part I have all the information (The final inV() > >>> vertex and a map of the labeled edges) but I need to make it such that > >>> the select step will be able to find the labeled edges on the path. In > >>> this example the labeled map contains only the edge with "e" as the > key. > >>> > >>> Hope it makes some sense. > >>> > >>> Thanks > >>> Pieter > >>> > >>> On 01/07/2015 20:02, Marko Rodriguez wrote: > >>>> Hi, > >>>> > >>>> I don't quite understand what you are trying to accomplish (attention > span of a tootsie fly), but here are some notes: > >>>> > >>>> 1. Look at AbstractStep.prepareTraveserForNextStep() > >>>> 2. B_O_…Traverser specify the requirements that the Traverser > satisfies: > >>>> B_O_P_S_SE_SL_Traverser = > Bulk+Object+Path+Sack+SideEffect+SingleLoop. In other words, a very meaty > traverser, indeed. > >>>> > >>>> What do you want "// What to do?" to do? > >>>> > >>>> Marko. > >>>> > >>>> http://markorodriguez.com > >>>> > >>>> On Jul 1, 2015, at 11:32 AM, pieter-gmail <[email protected]> > wrote: > >>>> > >>>>> Hi, > >>>>> > >>>>> I am trying to optimize queries with 'as' in it. > >>>>> > >>>>> Currently I can optimize consecutive VertexStep and EdgeVertexStep > >>>>> (without labels) by combining them into one step. > >>>>> > >>>>> Now I am trying to achieve the same but with 'as' in the traversal. > >>>>> > >>>>> e.g. > >>>>> > >>>>> Vertex a1 = g.addVertex(T.label, "A", "name", "a1"); > >>>>> Vertex b1 = g.addVertex(T.label, "B", "name", "b1"); > >>>>> Vertex b2 = g.addVertex(T.label, "B", "name", "b2"); > >>>>> Edge e1 = a1.addEdge("outB", b1); > >>>>> Edge e2 = a1.addEdge("outB", b2); > >>>>> > >>>>> g.tx().commit(); > >>>>> > >>>>> GraphTraversal<Vertex, Map<String, Element>> traversal = > g.traversal() > >>>>> .V(a1) > >>>>> .outE("outB") > >>>>> .as("e") > >>>>> .inV() > >>>>> .as("B") > >>>>> .select("e", "B"); > >>>>> > >>>>> I combine all consecutive VertexStep, EdgeVertexStep into one step, > >>>>> execute one query and with the result I can construct the labeled > edge > >>>>> ("e") and vertices ("B"). > >>>>> > >>>>> So far in the combined step I have all the information, but alas > what now? > >>>>> > >>>>> public class SqlgVertexStepCompiled<S extends SqlgElement, E extends > >>>>> SqlgElement> extends FlatMapStep<S, E> { > >>>>> > >>>>> ... > >>>>> > >>>>> @Override > >>>>> protected Traverser<E> processNextStart() { > >>>>> while (true) { > >>>>> if (this.iterator.hasNext()) { > >>>>> Pair<E, Map<String, Object>> next = this.iterator.next(); > >>>>> E e = next.getLeft(); > >>>>> Map<String, Object> labeledObjects = next.getRight(); > >>>>> for (String label : labeledObjects.keySet()) { > >>>>> //What to do > >>>>> this.head.path().extend(labeledObjects.get(label), > label); > >>>>> } > >>>>> return this.head.split(e, this); > >>>>> } else { > >>>>> this.head = this.starts.next(); > >>>>> this.iterator = this.flatMapCustom(this.head); > >>>>> } > >>>>> } > >>>>> } > >>>>> > >>>>> ... > >>>>> > >>>>> Any pointers? > >>>>> > >>>>> btw, what does all those strange traverser names mean, > >>>>> B_O_P_S_SE_SL_Traverser... > >>>>> > >>>>> Thanks > >>>>> Pieter > >> > > > >
