tinkerpop/gremlin — Issue #272: loop pipe sematics
Author: i000
Created: 2011-12-21 20:38:11+00:00
State: open

Hi,

I think it would reasonable if the existence of an emitClosure in a loop pipe would suppress the default emission of elements at loop ends.

Given this graph:

0 -> 1 -> 2 -> 3 -> 4 -> 5 ...
gremlin> x0 = g.addVertex()
gremlin> x1 = g.addVertex()
gremlin> x2 = g.addVertex()
gremlin> x3 = g.addVertex()
gremlin> x4 = g.addVertex()
gremlin> x5 = g.addVertex()
gremlin> g.addEdge(x0, x1, 'link')
gremlin> g.addEdge(x1, x2, 'link')
gremlin> g.addEdge(x2, x3, 'link')
gremlin> g.addEdge(x3, x4, 'link')
gremlin> g.addEdge(x4, y5, 'link')

currently the semantics of this query that returns filter uneven vertices:

g.v(0).out.loop(1){it.loops < 5}{(it.object.id.toInteger() % 2) == 1}

are:

==>v[1] (emitClosure is true, loopClosure is true)
==>v[3] (emitClosure is true, loopClosure is true)
==>v[4] (emitClosure is false, loopClosure is false) ** EVEN **

for it.loops < 4

==>v[1] (emitClosure is true, loopClosure is true)
==>v[3] (emitClosure is true, loopClosure is false)

for it.loops < 6

==>v[1] (emitClosure is true, loopClosure is true)
==>v[3] (emitClosure is true, loopClosure is true)
==>v[5] (emitClosure is true, loopClosure is false)

To "fix" this it is necessary to repeat the filter at the end:

g.v(0).out.loop(1){it.loops < 5}{(it.object.id.toInteger() % 2) == 1}.filter{(it.id.toInteger() % 2) == 1}

If the emission of loop ends is suppressed, the old behaviour could be easily simulated:

g.v(0).out.loop(1){it.loops < 5}{(it.object.id.toInteger() % 2) == 1 || it.loops == 5}