You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ok...@apache.org on 2016/02/19 17:26:42 UTC

[11/27] incubator-tinkerpop git commit: Through hell and back. You can now go TraversalVertexProgram->PageRankVertexProgramStep->TraversalVertexPrograph->OLTP. I had to create the concept of 'reving and old view.' VertexProgramStrategy is much more flexi

Through hell and back. You can now go TraversalVertexProgram->PageRankVertexProgramStep->TraversalVertexPrograph->OLTP. I had to create the concept of 'reving and old view.' VertexProgramStrategy is much more flexible. Still needs alot of work, but we are getting there.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/88f24c7f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/88f24c7f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/88f24c7f

Branch: refs/heads/master
Commit: 88f24c7f5a889520655fb645010eead3e2815078
Parents: 010c9f3
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Tue Feb 16 15:15:50 2016 -0700
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue Feb 16 15:15:50 2016 -0700

----------------------------------------------------------------------
 .../traversal/TraversalVertexProgram.java       | 79 +++++++++++---------
 .../step/map/TraversalVertexProgramStep.java    | 11 ++-
 .../decoration/VertexProgramStrategy.java       | 67 ++++++++++-------
 .../step/map/GroovyPageRankTest.groovy          |  5 ++
 .../traversal/step/map/PageRankTest.java        | 30 ++++++++
 .../spark/process/computer/SparkExecutor.java   |  9 ++-
 .../computer/TinkerGraphComputerView.java       |  5 +-
 .../structure/TinkerGraphPlayTest.java          |  3 +-
 8 files changed, 140 insertions(+), 69 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/88f24c7f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/TraversalVertexProgram.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/TraversalVertexProgram.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/TraversalVertexProgram.java
index a2b0c65..74081dd 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/TraversalVertexProgram.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/TraversalVertexProgram.java
@@ -38,7 +38,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.GraphStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.SideEffectCapStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierStep;
 import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
-import org.apache.tinkerpop.gremlin.process.traversal.util.EmptyTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.util.PureTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.util.ScriptTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
@@ -136,49 +135,55 @@ public final class TraversalVertexProgram implements VertexProgram<TraverserSet<
     public void execute(final Vertex vertex, final Messenger<TraverserSet<?>> messenger, final Memory memory) {
         this.traversal.getSideEffects().setLocalVertex(vertex);
         if (memory.isInitialIteration()) {    // ITERATION 1
-            final TraverserSet<Object> haltedTraversers = new TraverserSet<>();
-            vertex.property(VertexProperty.Cardinality.single, HALTED_TRAVERSERS, haltedTraversers);
-
-            /*if (!(this.traversal.getStartStep() instanceof GraphStep)) {  // TODO: support reactivating halted traversers
-                final TraverserSet<Object> aliveTraverses = new TraverserSet<>();
-                aliveTraverses.addAll(haltedTraversers);
-                haltedTraversers.clear();
-                if (!haltedTraversers.isEmpty())
-                    messenger.sendMessage(MessageScope.Global.of(vertex), aliveTraverses);
-            }*/
-            final GraphStep<Element, Element> graphStep = (this.traversal.getStartStep() instanceof GraphStep) ?
-                    (GraphStep<Element, Element>) this.traversal.getStartStep() :
-                    new GraphStep((Traversal.Admin) EmptyTraversal.instance(), Vertex.class, true); // if no start vertices, then do all vertices
-            final String future = (this.traversal.getStartStep() instanceof GraphStep) ? graphStep.getNextStep().getId() : this.traversal.getStartStep().getId();
-            final TraverserGenerator traverserGenerator = this.traversal.getTraverserGenerator();
-            if (graphStep.returnsVertex()) {  // VERTICES (process the first step locally)
-                if (ElementHelper.idExists(vertex.id(), graphStep.getIds())) {
-                    final Traverser.Admin<Element> traverser = traverserGenerator.generate(vertex, graphStep, 1l);
-                    traverser.setStepId(future);
-                    traverser.detach();
-                    if (traverser.isHalted())
-                        haltedTraversers.add((Traverser.Admin) traverser);
-                    else
-                        memory.and(VOTE_TO_HALT, TraverserExecutor.execute(vertex, new SingleMessenger<>(messenger, new TraverserSet<>(traverser)), this.traversalMatrix));
+            if (!(this.traversal.getStartStep() instanceof GraphStep)) {  // NOT A GRAPH-STEP TRAVERSAL
+                final TraverserSet<Object> haltedTraversers = vertex.<TraverserSet<Object>>property(HALTED_TRAVERSERS).orElse(new TraverserSet<>());
+                if (haltedTraversers.isEmpty()) {
+                    memory.and(VOTE_TO_HALT, true);
+                } else {
+                    vertex.property(VertexProperty.Cardinality.single, HALTED_TRAVERSERS, haltedTraversers);
+                    final TraverserSet<Object> aliveTraverses = new TraverserSet<>();
+                    haltedTraversers.forEach(traverser -> {
+                        traverser.setStepId(this.traversal.getStartStep().getId());
+                        aliveTraverses.add(traverser);
+                    });
+                    haltedTraversers.clear();
+                    memory.and(VOTE_TO_HALT, TraverserExecutor.execute(vertex, new SingleMessenger<>(messenger, aliveTraverses), this.traversalMatrix));
                 }
-            } else {  // EDGES (process the first step via a message pass)
-                boolean voteToHalt = true;
-                final Iterator<Edge> starts = vertex.edges(Direction.OUT);
-                while (starts.hasNext()) {
-                    final Edge start = starts.next();
-                    if (ElementHelper.idExists(start.id(), graphStep.getIds())) {
-                        final Traverser.Admin<Element> traverser = traverserGenerator.generate(start, graphStep, 1l);
+            } else {                                                     // A GRAPH-STEP TRAVERSAL
+                final TraverserSet<Object> haltedTraversers = new TraverserSet<>();
+                vertex.property(VertexProperty.Cardinality.single, HALTED_TRAVERSERS, haltedTraversers);
+                final GraphStep<Element, Element> graphStep = (GraphStep<Element, Element>) this.traversal.getStartStep();
+                final String future = (this.traversal.getStartStep() instanceof GraphStep) ? graphStep.getNextStep().getId() : this.traversal.getStartStep().getId();
+                final TraverserGenerator traverserGenerator = this.traversal.getTraverserGenerator();
+                if (graphStep.returnsVertex()) {  // VERTICES (process the first step locally)
+                    if (ElementHelper.idExists(vertex.id(), graphStep.getIds())) {
+                        final Traverser.Admin<Element> traverser = traverserGenerator.generate(vertex, graphStep, 1l);
                         traverser.setStepId(future);
-                        traverser.detach(); // TODO: bad
+                        traverser.detach();  // TODO: bad?
                         if (traverser.isHalted())
                             haltedTraversers.add((Traverser.Admin) traverser);
-                        else {
-                            voteToHalt = false;
-                            messenger.sendMessage(MessageScope.Global.of(vertex), new TraverserSet<>(traverser));
+                        else
+                            memory.and(VOTE_TO_HALT, TraverserExecutor.execute(vertex, new SingleMessenger<>(messenger, new TraverserSet<>(traverser)), this.traversalMatrix));
+                    }
+                } else {  // EDGES (process the first step via a message pass)
+                    boolean voteToHalt = true;
+                    final Iterator<Edge> starts = vertex.edges(Direction.OUT);
+                    while (starts.hasNext()) {
+                        final Edge start = starts.next();
+                        if (ElementHelper.idExists(start.id(), graphStep.getIds())) {
+                            final Traverser.Admin<Element> traverser = traverserGenerator.generate(start, graphStep, 1l);
+                            traverser.setStepId(future);
+                            traverser.detach(); // TODO: bad?
+                            if (traverser.isHalted())
+                                haltedTraversers.add((Traverser.Admin) traverser);
+                            else {
+                                voteToHalt = false;
+                                messenger.sendMessage(MessageScope.Global.of(vertex), new TraverserSet<>(traverser));
+                            }
                         }
                     }
+                    memory.and(VOTE_TO_HALT, voteToHalt);
                 }
-                memory.and(VOTE_TO_HALT, voteToHalt);
             }
         } else {  // ITERATION 1+
             memory.and(VOTE_TO_HALT, TraverserExecutor.execute(vertex, messenger, this.traversalMatrix));

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/88f24c7f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/TraversalVertexProgramStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/TraversalVertexProgramStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/TraversalVertexProgramStep.java
index 7dde14c..7704347 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/TraversalVertexProgramStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/TraversalVertexProgramStep.java
@@ -67,13 +67,13 @@ public final class TraversalVertexProgramStep extends AbstractStep<ComputerResul
             if (this.first && this.getPreviousStep() instanceof EmptyStep) {
                 this.first = false;
                 final Graph graph = this.getTraversal().getGraph().get();
-                final GraphComputer graphComputer = this.graphComputerFunction.apply(graph);
+                final GraphComputer graphComputer = this.getComputer(graph);
                 final ComputerResult result = graphComputer.program(TraversalVertexProgram.build().traversal(this.compileTraversal(graph)).create(graph)).submit().get();
                 return this.getTraversal().getTraverserGenerator().generate(result, (Step) this, 1l);
             } else {
                 final Traverser.Admin<ComputerResult> traverser = this.starts.next();
                 final Graph graph = traverser.get().graph();
-                final GraphComputer graphComputer = this.graphComputerFunction.apply(graph);
+                final GraphComputer graphComputer = this.getComputer(graph);
                 final ComputerResult result = graphComputer.program(TraversalVertexProgram.build().traversal(this.compileTraversal(graph)).create(graph)).submit().get();
                 return traverser.split(result, this);
             }
@@ -100,6 +100,13 @@ public final class TraversalVertexProgramStep extends AbstractStep<ComputerResul
         return TraversalParent.super.getSelfAndChildRequirements(TraverserRequirement.BULK);
     }
 
+    private final GraphComputer getComputer(final Graph graph) {
+        final GraphComputer graphComputer = this.graphComputerFunction.apply(graph);
+        if (!(this.getNextStep() instanceof ComputerResultStep))
+            graphComputer.persist(GraphComputer.Persist.EDGES).result(GraphComputer.ResultGraph.NEW);
+        return graphComputer;
+    }
+
     private final Traversal.Admin<?, ?> compileTraversal(final Graph graph) {
         final Traversal.Admin<?, ?> compiledComputerTraversal = this.pureComputerTraversal.clone();
         compiledComputerTraversal.setStrategies(TraversalStrategies.GlobalCache.getStrategies(graph.getClass()).clone());

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/88f24c7f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/VertexProgramStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/VertexProgramStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/VertexProgramStrategy.java
index 53ffcff..ba9dec3 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/VertexProgramStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/VertexProgramStrategy.java
@@ -28,12 +28,10 @@ import org.apache.tinkerpop.gremlin.process.traversal.Step;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
-import org.apache.tinkerpop.gremlin.process.traversal.step.map.GraphStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.IdentityStep;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyStep;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ComputerVerificationStrategy;
-import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.VerificationException;
 import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
 import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.util.EmptyTraversal;
@@ -65,38 +63,45 @@ public final class VertexProgramStrategy extends AbstractTraversalStrategy<Trave
 
         traversal.addTraverserRequirement(TraverserRequirement.BULK); // all graph computations require bulk
 
-        if (traversal.getStartStep() instanceof GraphStep && (traversal.getStartStep().getNextStep() instanceof PageRankVertexProgramStep)) {
-            final GraphStep<?, ?> graphStep = (GraphStep) traversal.getStartStep();
-            final PageRankVertexProgramStep pageRankVertexProgramStep = (PageRankVertexProgramStep) traversal.getStartStep().getNextStep();
-            if (!graphStep.returnsVertex())
-                throw new VerificationException("The GraphStep previous to PageRankVertexStep must emit vertices: " + graphStep, traversal);
-            pageRankVertexProgramStep.setGraphComputerFunction(this.graphComputerFunction);
-            graphStep.getLabels().forEach(pageRankVertexProgramStep::addLabel);
-            traversal.removeStep(0);  // remove the graph step
-            if (traversal.getSteps().size() == 1) // todo: in the future, this should just be a mapreduce job added to the PageRankVertexProgram step
-                traversal.addStep(new IdentityStep<>(traversal));
+        if (null == this.graphComputerFunction) { // TOTAL HACK!
+            traversal.setParent(new TraversalVertexProgramStep(EmptyTraversal.instance(), EmptyTraversal.instance()));
+            ComputerVerificationStrategy.instance().apply(traversal);
+            traversal.setParent(EmptyStep.instance());
+            return;
         }
-        if (null != this.graphComputerFunction) {   // if the function is null, then its been serialized and thus, already in a graph computer
+
+        Step<?, ?> currentStep = traversal.getStartStep();
+        while (!(currentStep instanceof EmptyStep)) {
             Traversal.Admin<?, ?> computerTraversal = new DefaultTraversal<>();
-            Step<?, ?> firstLegalOLAPStep = getFirstLegalOLAPStep(traversal.getStartStep());
-            Step<?, ?> lastLegalOLAPStep = getLastLegalOLAPStep(traversal.getStartStep());
+            Step<?, ?> firstLegalOLAPStep = getFirstLegalOLAPStep(currentStep);
+            Step<?, ?> lastLegalOLAPStep = getLastLegalOLAPStep(currentStep);
             if (!(firstLegalOLAPStep instanceof EmptyStep)) {
                 int index = TraversalHelper.stepIndex(firstLegalOLAPStep, traversal);
                 TraversalHelper.removeToTraversal(firstLegalOLAPStep, lastLegalOLAPStep.getNextStep(), (Traversal.Admin) computerTraversal);
                 final TraversalVertexProgramStep traversalVertexProgramStep = new TraversalVertexProgramStep(traversal, computerTraversal);
-                traversalVertexProgramStep.setGraphComputerFunction(this.graphComputerFunction);
-                final ComputerResultStep computerResultStep = new ComputerResultStep(traversal, true);
-                if (!lastLegalOLAPStep.getLabels().isEmpty())
-                    lastLegalOLAPStep.getLabels().forEach(computerResultStep::addLabel);
                 traversal.addStep(index, traversalVertexProgramStep);
-                traversal.addStep(index + 1, computerResultStep);
             }
-        } else {  // this is a total hack to trick the difference between TraversalVertexProgram via GraphComputer and via TraversalSource. :|
-            traversal.setParent(new TraversalVertexProgramStep(EmptyTraversal.instance(), EmptyTraversal.instance()));
-            ComputerVerificationStrategy.instance().apply(traversal);
-            traversal.setParent(EmptyStep.instance());
+            currentStep = traversal.getStartStep();
+            while (!(currentStep instanceof EmptyStep)) {
+                if (!(currentStep instanceof VertexComputing) && !lastTraversalVertexProgramDone(traversal))
+                    break;
+                currentStep = currentStep.getNextStep();
+            }
         }
-
+        TraversalHelper.getLastStepOfAssignableClass(VertexComputing.class, traversal).ifPresent(step -> {
+            if (step instanceof TraversalVertexProgramStep) {
+                final ComputerResultStep computerResultStep = new ComputerResultStep<>(traversal, true);
+                ((TraversalVertexProgramStep) step).getGlobalChildren().get(0).getEndStep().getLabels().forEach(computerResultStep::addLabel);
+                // labeling should happen in TraversalVertexProgram (perhaps MapReduce)
+                TraversalHelper.insertAfterStep(computerResultStep, (Step) step, traversal);
+            }
+        });
+        if (traversal.getEndStep() instanceof PageRankVertexProgramStep) {
+            final TraversalVertexProgramStep traversalVertexProgramStep = new TraversalVertexProgramStep(traversal, __.identity().asAdmin());
+            traversal.addStep(traversalVertexProgramStep);
+            traversal.addStep(new ComputerResultStep<>(traversal, true));
+        }
+        traversal.getSteps().stream().filter(step -> step instanceof VertexComputing).forEach(step -> ((VertexComputing) step).setGraphComputerFunction(this.graphComputerFunction));
     }
 
     private static Step<?, ?> getFirstLegalOLAPStep(Step<?, ?> currentStep) {
@@ -112,11 +117,21 @@ public final class VertexProgramStrategy extends AbstractTraversalStrategy<Trave
         while (!(currentStep instanceof EmptyStep)) {
             if (ComputerVerificationStrategy.isStepInstanceOfEndStep(currentStep))
                 return currentStep;
+            if (currentStep instanceof VertexComputing)
+                return currentStep.getPreviousStep();
             currentStep = currentStep.getNextStep();
         }
         return EmptyStep.instance();
     }
 
+    private static boolean lastTraversalVertexProgramDone(final Traversal.Admin<?, ?> traversal) {
+        Optional<TraversalVertexProgramStep> optional = TraversalHelper.getLastStepOfAssignableClass(TraversalVertexProgramStep.class, traversal);
+        if (!optional.isPresent())
+            return false;
+        else
+            return ComputerVerificationStrategy.isStepInstanceOfEndStep(optional.get().getGlobalChildren().get(0).getEndStep());
+    }
+
     public static Optional<GraphComputer> getGraphComputer(final Graph graph, final TraversalStrategies strategies) {
         final Optional<TraversalStrategy<?>> optional = strategies.toList().stream().filter(strategy -> strategy instanceof VertexProgramStrategy).findAny();
         return optional.isPresent() ? Optional.of(((VertexProgramStrategy) optional.get()).graphComputerFunction.apply(graph)) : Optional.empty();

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/88f24c7f/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy
----------------------------------------------------------------------
diff --git a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy
index 438f2f7..963846f 100644
--- a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy
+++ b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyPageRankTest.groovy
@@ -49,5 +49,10 @@ public abstract class GroovyPageRankTest {
         public Traversal<Vertex, String> get_g_V_pageRank_order_byXpageRank_decrX_name_limitX2X() {
             new ScriptTraversal<>(g, "gremlin-groovy", "g.V.pageRank.order.by(PageRankVertexProgram.PAGE_RANK, decr).name.limit(2)")
         }
+
+        @Override
+        public Traversal<Vertex, Map<String, List<Object>>> get_g_V_hasLabelXpersonX_pageRank_byXpageRankX_order_byXpageRankX_valueMapXname_pageRankX() {
+            new ScriptTraversal<>(g, "gremlin-groovy", "g.V.hasLabel('person').pageRank.by('pageRank').order.by('pageRank').valueMap('name', 'pageRank')")
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/88f24c7f/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
index 8f4bb0e..b0cd252 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
@@ -35,6 +35,7 @@ import java.util.Map;
 
 import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.MODERN;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 /**
@@ -51,6 +52,8 @@ public abstract class PageRankTest extends AbstractGremlinProcessTest {
 
     public abstract Traversal<Vertex, Map<String, List<Object>>> get_g_V_pageRank_byXoutEXknowsXX_byXfriendRankX_valueMapXname_friendRankX();
 
+    public abstract Traversal<Vertex, Map<String, List<Object>>> get_g_V_hasLabelXpersonX_pageRank_byXpageRankX_order_byXpageRankX_valueMapXname_pageRankX();
+
     @Test
     @LoadGraphWith(MODERN)
     public void g_V_pageRank() {
@@ -114,6 +117,28 @@ public abstract class PageRankTest extends AbstractGremlinProcessTest {
         assertEquals("ripple", names.get(1));
     }
 
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_hasLabelXpersonX_pageRank_byXpageRankX_order_byXpageRankX_valueMapXname_pageRankX() {
+        final Traversal<Vertex, Map<String, List<Object>>> traversal = get_g_V_hasLabelXpersonX_pageRank_byXpageRankX_order_byXpageRankX_valueMapXname_pageRankX();
+        printTraversalForm(traversal);
+        int counter = 0;
+        double lastPageRank = Double.MIN_VALUE;
+        while (traversal.hasNext()) {
+            final Map<String, List<Object>> map = traversal.next();
+            assertEquals(2, map.size());
+            assertEquals(1, map.get("name").size());
+            assertEquals(1, map.get("pageRank").size());
+            String name = (String) map.get("name").get(0);
+            double pageRank = (Double) map.get("pageRank").get(0);
+            assertTrue(pageRank >= lastPageRank);
+            lastPageRank = pageRank;
+            assertFalse(name.equals("lop") || name.equals("ripple"));
+            counter++;
+        }
+        assertEquals(4, counter);
+    }
+
     public static class Traversals extends PageRankTest {
 
         @Override
@@ -135,5 +160,10 @@ public abstract class PageRankTest extends AbstractGremlinProcessTest {
         public Traversal<Vertex, String> get_g_V_pageRank_order_byXpageRank_decrX_name_limitX2X() {
             return g.V().pageRank().order().by(PageRankVertexProgram.PAGE_RANK, Order.decr).<String>values("name").limit(2);
         }
+
+        @Override
+        public Traversal<Vertex, Map<String, List<Object>>> get_g_V_hasLabelXpersonX_pageRank_byXpageRankX_order_byXpageRankX_valueMapXname_pageRankX() {
+            return g.V().hasLabel("person").pageRank().by("pageRank").order().by("pageRank").valueMap("name", "pageRank");
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/88f24c7f/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/process/computer/SparkExecutor.java
----------------------------------------------------------------------
diff --git a/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/process/computer/SparkExecutor.java b/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/process/computer/SparkExecutor.java
index 9b62eb6..fd3de43 100644
--- a/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/process/computer/SparkExecutor.java
+++ b/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/process/computer/SparkExecutor.java
@@ -41,6 +41,7 @@ import org.apache.tinkerpop.gremlin.structure.util.star.StarGraph;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 import scala.Tuple2;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
@@ -92,11 +93,15 @@ public final class SparkExecutor {
                     workerVertexProgram.workerIterationStart(memory.asImmutable()); // start the worker
                     return () -> IteratorUtils.map(partitionIterator, vertexViewIncoming -> {
                         final StarGraph.StarVertex vertex = vertexViewIncoming._2()._1().get(); // get the vertex from the vertex writable
+                        final boolean hasViewAndMessages = vertexViewIncoming._2()._2().isPresent(); // if this is the first iteration, then there are no views or messages
+                        final List<DetachedVertexProperty<Object>> previousView = hasViewAndMessages ? vertexViewIncoming._2()._2().get().getView() : memory.isInitialIteration() ? new ArrayList<>() : Collections.emptyList();
+                        // revive compute properties if they already exist
+                        if (memory.isInitialIteration() && elementComputeKeysArray.length > 0) {
+                            vertex.properties(elementComputeKeysArray).forEachRemaining(vertexProperty -> previousView.add(DetachedFactory.detach(vertexProperty, true)));
+                        }
                         // drop any computed properties that are cached in memory
                         if (elementComputeKeysArray.length > 0)
                             vertex.dropVertexProperties(elementComputeKeysArray);
-                        final boolean hasViewAndMessages = vertexViewIncoming._2()._2().isPresent(); // if this is the first iteration, then there are no views or messages
-                        final List<DetachedVertexProperty<Object>> previousView = hasViewAndMessages ? vertexViewIncoming._2()._2().get().getView() : Collections.emptyList();
                         final List<M> incomingMessages = hasViewAndMessages ? vertexViewIncoming._2()._2().get().getIncomingMessages() : Collections.emptyList();
                         previousView.forEach(property -> property.attach(Attachable.Method.create(vertex)));  // attach the view to the vertex
                         // previousView.clear(); // no longer needed so kill it from memory

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/88f24c7f/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/computer/TinkerGraphComputerView.java
----------------------------------------------------------------------
diff --git a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/computer/TinkerGraphComputerView.java b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/computer/TinkerGraphComputerView.java
index 0854d3e..8d2681d 100644
--- a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/computer/TinkerGraphComputerView.java
+++ b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/computer/TinkerGraphComputerView.java
@@ -95,7 +95,10 @@ public final class TinkerGraphComputerView {
     }
 
     public List<VertexProperty<?>> getProperty(final TinkerVertex vertex, final String key) {
-        return isComputeKey(key) ? this.getValue(vertex, key) : (List) TinkerHelper.getProperties(vertex).getOrDefault(key, Collections.emptyList());
+        // if the vertex property is already on the vertex, use that.
+        final List<VertexProperty<?>> vertexProperty = this.getValue(vertex, key);
+        return vertexProperty.isEmpty() ? (List) TinkerHelper.getProperties(vertex).getOrDefault(key, Collections.emptyList()) : vertexProperty;
+        //return isComputeKey(key) ? this.getValue(vertex, key) : (List) TinkerHelper.getProperties(vertex).getOrDefault(key, Collections.emptyList());
     }
 
     public List<Property> getProperties(final TinkerVertex vertex) {

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/88f24c7f/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
----------------------------------------------------------------------
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
index 88a52f6..5def976 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
@@ -77,7 +77,8 @@ public class TinkerGraphPlayTest {
         GraphTraversalSource g = graph.traversal().withComputer(); //GraphTraversalSource.computer());
         //System.out.println(g.V().outE("knows").identity().inV().count().is(P.eq(5)).explain());
         //System.out.println(g.V().hasLabel("person").fold().order(Scope.local).by("age").toList());
-        System.out.println(g.V().pageRank().order().by(PageRankVertexProgram.PAGE_RANK, Order.decr).values("name").toList());
+        System.out.println(g.V().hasLabel("person").pageRank().by("pageRank").order().by("pageRank").valueMap("name", "pageRank").iterate().toString());
+        System.out.println(g.V().hasLabel("person").pageRank().by("pageRank").order().by("pageRank").valueMap("name", "pageRank").toList());
         //System.out.println(g.V().pageRank().order().by(PageRankVertexProgram.PAGE_RANK).valueMap().toList());
 
     }