Hi, Would a traverser.setPath() operation help then?
Its funny, I was reading this morning on relational algebra equivalence relationships, and I was like: "huh, we could do X if we could traverser.setPath()." :) If this will make life easy, then can you please make a ticket? Marko. http://markorodriguez.com On Jul 2, 2015, at 12:23 AM, pieter-gmail <[email protected]> wrote: > Ok, afraid I have not had any success yet. > > Added the requirement and am working with a B_O_P_S_SE_SL_Traverser now. > > This is what I have tried, > > @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(); > this.labels.clear(); > this.labels.addAll(labeledObjects.keySet()); > for (String label : labeledObjects.keySet()) { > this.head = > this.head.split(labeledObjects.get(label), this); > } > this.labels.clear(); > return this.head.split(e, this); > } else { > this.head = this.starts.next(); > this.iterator = this.flatMapCustom(this.head); > } > } > } > > Calling head.split seems to be the only way to manipulate the path. > I needed to override the getLabels() method return the correct label for > every head.split(...) > > This does not work however as the path is never cleared and thus the > edges accumulate. i.e. the second iteration will have the labeled edge > from the first iteration still in the path, the third iteration the > labels from first and second... > > Going to see what happens if I make the path mutable for now, and get a > better understanding of how it all fits together. > > Thanks > Pieter > > > > On 02/07/2015 01:15, Matt Frantz wrote: >> 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 >>> >
