Does it make sense? Any ideas? Cheers Pieter
On 23/01/2017 19:00, pieter-gmail wrote: > Hi, > > Ran some more tests, seems all is not well. > > So the previous example always works (on TinkerPop and Neo4j) because > bothE is not seen as two queries but rather one and all is well. > > Running the same test with a union instead has the same issue as Sqlg. > > @Test > public void testLazy() { > final TinkerGraph graph = TinkerGraph.open(); > final Vertex a1 = graph.addVertex(T.label, "A"); > final Vertex b1 = graph.addVertex(T.label, "B"); > final Vertex c1 = graph.addVertex(T.label, "C"); > a1.addEdge("ab", b1); > a1.addEdge("ac", c1); > > AtomicInteger count = new AtomicInteger(0); > graph.traversal().V(a1).union(outE(), inE()).forEachRemaining(edge -> { > a1.addEdge("ab", b1); #1 > c1.addEdge("ac", a1); #2 > count.getAndIncrement(); > }); > Assert.assertEquals(2, count.get()); > } > > If only #1 is executed the test passes as the outE() is first traversed > and the subsequent inE() is unchanged. > However is #2 is executed by the time inE() executes its sees 2 new in > edges and the count == 4. > > I tested on Neo4j and it has the same behavior. > > As far as I can tell all is actually behaving as expected with lazy > iteration assumed. > > The unspecified semantics is with bothE(), both sides done immediately > like Neo4j and TinkerPop, or out and in done lazily as with Sqlg. > If lazily which side first as if affects the semantics. > > Another caveat is if barrier steps are injected and then the semantics > is not the same as without the barrier step. > > Cheers > Pieter > > On 23/01/2017 14:38, Stephen Mallette wrote: >> I'd say TinkerGraph demonstrates the expected behavior - I guess we don't >> have a test that enforces that? >> >> On Sat, Jan 21, 2017 at 3:23 PM, pieter-gmail <pieter.mar...@gmail.com> >> wrote: >> >>> Ok, thanks. >>> >>> Its tricky as it messes with the laziness and visibility of the queries. >>> Can really think of a solution though. >>> >>> Cheers >>> Pieter >>> >>> On 21/01/2017 21:14, Daniel Kuppitz wrote: >>>> Hi Pieter, >>>> >>>> forEachRemaining iterates over the result and hence I would expect the >>>> result to be 2. Otherwise you would / should end up with an endless loop. >>>> However, the same behavior is seen when you replace forEachRemaining >>> with a >>>> sideEffect lambda step. Not sure what the expected behavior is / should >>> be, >>>> but I think I prefer the way it's done now. >>>> >>>> Cheers, >>>> Daniel >>>> >>>> >>>> On Sat, Jan 21, 2017 at 7:30 PM, pieter-gmail <pieter.mar...@gmail.com> >>>> wrote: >>>> >>>>> Hi, >>>>> >>>>> I need to clarify the expected semantics of gremlin's lazy iteration >>>>> semantics. >>>>> The following gremlin is what highlighted it. >>>>> >>>>> ``` >>>>> @Test >>>>> public void testLazy() { >>>>> final TinkerGraph graph = TinkerGraph.open(); >>>>> final Vertex a1 = graph.addVertex(T.label, "A"); >>>>> final Vertex b1 = graph.addVertex(T.label, "B"); >>>>> final Vertex c1 = graph.addVertex(T.label, "C"); >>>>> a1.addEdge("ab", b1); >>>>> a1.addEdge("ac", c1); >>>>> >>>>> AtomicInteger count = new AtomicInteger(0); >>>>> graph.traversal().V(a1).bothE().forEachRemaining(edge -> { >>>>> a1.addEdge("ab", b1); >>>>> //a1.addEdge("ac", c1); >>>>> count.getAndIncrement(); >>>>> }); >>>>> Assert.assertEquals(2, count.get()); >>>>> } >>>>> >>>>> ``` >>>>> >>>>> On TinkerGraph the count is always 2. >>>>> >>>>> On Sqlg's Postgresql dialect the `bothE` first traverses the 'ac' edges >>>>> adds in a 'ab' edge and then traverses the 'ab' edges and ends up with a >>>>> count of 3. >>>>> >>>>> On Sqlg's HSQLDB and H2 dialects the `bothE` first traverses the 'ab' >>>>> edges adds in a 'ab' edge then traverses the 'ac' edges and ends up with >>>>> a count of 2. >>>>> >>>>> So for Sqlg the added edge will be seen by subsequent traversals due to >>>>> the lazy nature but the order affects the result. >>>>> >>>>> TinkerGraph seems to get both 'ab' and 'ac' edges upfront and does not >>>>> subsequently see the added edge. A bit like it has a hidden barrier step >>>>> before the `forEachRemaining`. >>>>> >>>>> What is the expected semantics in this situation? >>>>> Is a traversal that traverses an element that has been modified earlier >>>>> in the same traversal suppose to see the change? >>>>> >>>>> Thanks >>>>> Pieter >>>>> >>>>>