Marko A. Rodriguez created TINKERPOP3-693:
---------------------------------------------

             Summary: [Proposal] Local Nested Traversals Beyond the Star Graph 
in OLAP
                 Key: TINKERPOP3-693
                 URL: https://issues.apache.org/jira/browse/TINKERPOP3-693
             Project: TinkerPop 3
          Issue Type: Brainstorming
          Components: process
            Reporter: Marko A. Rodriguez
            Assignee: Marko A. Rodriguez


Here is a half-baked solution to the "local star graph"-problem in Gremlin OLAP.

A {{Traverser}} not only maintains a pointer to its current object, but also to 
its "local traversal spawn object." For instance:

{code}
g.V.where(out('knows').has('name','bob')).name
{code}

The {{Traverser}} going into the {{where()}} step will, lets say, be at 
{{v[1]}}. Thus:

{code}
Traverser.get() == v[1]
Traverser.spawn() == v[1]
Traverser.stepId() == "out('knows')"-stepId
{code}

At the next step, the {{Traverser[v[1]]}} hits up the {{out("knows")}}-step. 
This will trigger a message pass. Lets say {{v[1]--knows-->v[2]}}.

{code}
Traverser.get() == v[2]
Traverser.spawn() == v[1]
Traverser.stepId() == "has('name','bob')"-stepId
{code}

At this point, the {{Traverser[v[2]]}} is shoved into {{has("name","bob")}} and 
lets say that {{v[2]}} is "bob." What is the next step? There is none because 
its at the end of the local traversal. So, {{TraverserExecutor}} looks up 
{{step.getTraversal().getTraversalParent()}} and executes the local 
{{where()}}-step with a behavior of "v[1] went into , and v[2] came out." Thus, 
a "simulated local traversal" is "v[1] --> v[2]" and {{where()}}-step simply 
says "ah, v[2], then let me emit v[1]". This yields a {{Traverser}} of:

{code}
Traverser.get() == v[1]
Traverser.spawn() == null
Traverser.stepId() == {{values('name')}}-stepId
{code}

The {{Traverser}} is sent back to {{v[1]}} to solve the {{values('name')}}-step 
function.

This notion of a "simulated local traversal" is that the {{where()-step}} local 
traversal can be "wrapped" on the fly by {{TraverserExecutor}} such that:

{code}
out('knows').has('name','bob') --> directMap(v[1],v[2])
{code}

So this is doable for a single local traversal. What about parallel local 
traversals like {{and(a,b,c)}}. In this situation, {{a}}, {{b}}, and {{c}} must 
all come back before {{and()}} is complete. I think it might work something 
like this:

{code}
Traverser.get() == v[1]
Traverser.spawn() == v[1]
Traverser.sessionId() == uuid:123-456-789(3)
{code}

In this way, before the {{spawn}} is "released" by {{and()}}, three 
uuid:123-456-789 session ids must be returned with {{Traverser.get() != null}}. 
If that happens, the {{and()}} released {{v[1]}} to the next step.

Note that in this model all the state is in the {{Traverser}}. There is no step 
state required. Given that {{Traversers}} are stored at the local vertex during 
iterations, looking up a {{Traverser}} by {{sessionId}} can be just as easy as 
looking it up by {{Traverser.get()}}. In this way, a placeholder {{Traverser}} 
exists at the {{and()}}-ing vertex waiting for its {{sessionId}} to complete.

.......................... a little sketchy and involved. But I think with some 
more mulling we can come up with a simple "ah, that is just a that which makes 
this just that and I can delete the entire codebase because there never was a 
problem to begin with. I can die yielding no intent. Finally."




--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to