Ok, a quick update,
@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();
//split before setting the path.
//This is because the labels must be set on a unique
path for every iteration.
B_O_P_S_SE_SL_Traverser split =
(B_O_P_S_SE_SL_Traverser) this.head.split(e, this);
for (String label : labeledObjects.keySet()) {
split.setPath(split.path().extend(labeledObjects.get(label), new
HashSet<>(Arrays.asList(label))));
}
return split;
} else {
this.head = (B_O_P_S_SE_SL_Traverser) this.starts.next();
this.iterator = this.flatMapCustom(this.head);
}
}
}
This works, but only tested for one particular case so far.
Cheers
Pieter
On 02/07/2015 16:17, Marko Rodriguez wrote:
> 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
>