This is an automated email from the ASF dual-hosted git repository.

colegreer pushed a commit to branch 3.6-dev
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit d98357ceac9134f8989989ace3f4b5f24b6ead2d
Author: Boxuan Li <[email protected]>
AuthorDate: Thu Jul 27 16:14:41 2023 -0700

    [TINKERPOP-2973] Enable vertex properties filtering for GraphComputer 
(#2164)
    
    GraphComputer has vertexFilter and edgeFilter, but not yet a filter for 
vertex properties. Many vertex programs don't need many if not all vertex 
properties. PageRank, for example, does not need any vertex properties at all. 
Having a vertex property filter can greatly reduce memory/disk usage.
    Also related to TINKERPOP-1403
---
 .../gremlin/process/computer/GraphComputer.java    | 11 +++
 .../gremlin/process/computer/GraphFilter.java      | 99 ++++++++++++++++++----
 .../gremlin/structure/util/star/StarGraph.java     |  8 ++
 .../gremlin/process/TraversalStrategiesTest.java   |  6 ++
 .../process/computer/GraphComputerTest.java        | 29 ++++++-
 .../pagerank/PageRankVertexProgramTest.java        |  6 +-
 .../computer/AbstractHadoopGraphComputer.java      |  8 +-
 .../gremlin/spark/structure/SparkTest.java         |  6 +-
 .../process/computer/TinkerGraphComputer.java      |  7 ++
 .../process/computer/TinkerGraphComputerView.java  | 23 ++++-
 10 files changed, 176 insertions(+), 27 deletions(-)

diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphComputer.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphComputer.java
index 5e8fdab5cd..2baba4cb78 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphComputer.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphComputer.java
@@ -22,6 +22,7 @@ import 
org.apache.tinkerpop.gremlin.process.computer.util.DefaultComputerResult;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Property;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 
 import java.util.concurrent.Future;
@@ -135,6 +136,16 @@ public interface GraphComputer {
      */
     public GraphComputer edges(final Traversal<Vertex, Edge> edgeFilter) 
throws IllegalArgumentException;
 
+    /**
+     * Add a filter that will limit which vertex properties are loaded from 
the graph source. The loaded vertices
+     * will only have those properties that pass through the provided filter. 
To drop all vertex properties,
+     * provide a traversal like __.properties("dummy") where "dummy" is not a 
valid vertex property.
+     *
+     * @param vertexPropertyFilter the traversal that determines which vertex 
properties are loaded for each vertex
+     * @return the updated GraphComputer with newly set vertex property filter
+     */
+    public GraphComputer vertexProperties(final Traversal<Vertex, ? extends 
Property<?>> vertexPropertyFilter);
+
     /**
      * Set an arbitrary configuration key/value for the underlying {@code 
Configuration} in the {@link GraphComputer}.
      * Typically, the other fluent methods in {@link GraphComputer} should be 
used to configure the computation.
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphFilter.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphFilter.java
index 2f01dcf28a..6daa95278b 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphFilter.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphFilter.java
@@ -27,6 +27,7 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
 import org.apache.tinkerpop.gremlin.structure.Direction;
 import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Property;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 
 import java.io.Serializable;
@@ -35,6 +36,7 @@ import java.util.EnumMap;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -81,6 +83,7 @@ public final class GraphFilter implements Cloneable, 
Serializable {
 
     private Traversal.Admin<Vertex, Vertex> vertexFilter = null;
     private Traversal.Admin<Vertex, Edge> edgeFilter = null;
+    private Traversal.Admin<Vertex, ? extends Property<?>> 
vertexPropertyFilter = null;
     private Map<Direction, Map<String, Legal>> edgeLegality = new 
EnumMap<>(Direction.class);
     private boolean allowNoEdges = false;
 
@@ -182,6 +185,16 @@ public final class GraphFilter implements Cloneable, 
Serializable {
         }
     }
 
+    /**
+     * Set the filter for selecting vertex properties from the vertices.
+     *
+     * @param vertexPropertyFilter The {@link Traversal} that will either let 
the vertex property pass or not.
+     */
+    public void setVertexPropertyFilter(final Traversal<Vertex, ? extends 
Property<?>> vertexPropertyFilter) {
+        this.vertexPropertyFilter = vertexPropertyFilter.asAdmin().clone();
+    }
+
+
     /**
      * Returns true if the provided vertex meets the vertex-filter criteria.
      * If no vertex filter is provided, then the vertex is considered legal.
@@ -206,6 +219,19 @@ public final class GraphFilter implements Cloneable, 
Serializable {
                 TraversalUtil.applyAll(vertex, this.edgeFilter);
     }
 
+    /**
+     * Returns an iterator of legal vertex properties. If no vertex property
+     * filter is provided, then all vertex properties are returned.
+     *
+     * @param vertex the vertex whose legal vertex properties are to be 
accessed.
+     * @return an iterator of vertex properties that are {@link Legal#YES}.
+     */
+    public Iterator<? extends Property<?>> legalVertexProperties(final Vertex 
vertex) {
+        return null == this.vertexPropertyFilter ?
+            vertex.properties() :
+            TraversalUtil.applyAll(vertex, this.vertexPropertyFilter);
+    }
+
     /**
      * Get the vertex filter associated with this graph filter.
      *
@@ -224,13 +250,22 @@ public final class GraphFilter implements Cloneable, 
Serializable {
         return this.edgeFilter;
     }
 
+    /**
+     * Get the vertex property filter associated with this graph filter.
+     *
+     * @return the vertex property filter or null if not provided.
+     */
+    public Traversal.Admin<Vertex, ? extends Property<?>> 
getVertexPropertyFilter() {
+        return this.vertexPropertyFilter;
+    }
+
     /**
      * Whether filters have been defined.
      *
-     * @return true if either a vertex or edge filter has been provided.
+     * @return true if either a vertex, edge filter, or vertex property filter 
has been provided.
      */
     public boolean hasFilter() {
-        return this.vertexFilter != null || this.edgeFilter != null;
+        return this.vertexFilter != null || this.edgeFilter != null || 
this.vertexPropertyFilter != null;
     }
 
     /**
@@ -251,6 +286,15 @@ public final class GraphFilter implements Cloneable, 
Serializable {
         return this.vertexFilter != null;
     }
 
+    /**
+     * Whether a vertex property filter has been defined.
+     *
+     * @return true if a vertex property filter was provided.
+     */
+    public boolean hasVertexPropertyFilter() {
+        return this.vertexPropertyFilter != null;
+    }
+
     /**
      * For a particular edge directionality, get all the {@link Legal#YES} or 
{@link Legal#MAYBE} edge labels.
      * If the label set contains {@code null}, then all edge labels for that 
direction are positively legal.
@@ -312,19 +356,22 @@ public final class GraphFilter implements Cloneable, 
Serializable {
 
     @Override
     public int hashCode() {
-        return (null == this.edgeFilter ? 111 : this.edgeFilter.hashCode()) ^ 
(null == this.vertexFilter ? 222 : this.vertexFilter.hashCode());
+        int result = vertexFilter != null ? vertexFilter.hashCode() : 0;
+        result = 31 * result + (edgeFilter != null ? edgeFilter.hashCode() : 
0);
+        result = 31 * result + (vertexPropertyFilter != null ? 
vertexPropertyFilter.hashCode() : 0);
+        return result;
     }
 
     @Override
-    public boolean equals(final Object object) {
-        if (!(object instanceof GraphFilter))
-            return false;
-        else if (((GraphFilter) object).hasVertexFilter() && !((GraphFilter) 
object).vertexFilter.equals(this.vertexFilter))
-            return false;
-        else if (((GraphFilter) object).hasEdgeFilter() && !((GraphFilter) 
object).edgeFilter.equals(this.edgeFilter))
-            return false;
-        else
-            return true;
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        GraphFilter that = (GraphFilter) o;
+
+        if (!Objects.equals(vertexFilter, that.vertexFilter)) return false;
+        if (!Objects.equals(edgeFilter, that.edgeFilter)) return false;
+        return Objects.equals(vertexPropertyFilter, that.vertexPropertyFilter);
     }
 
     @Override
@@ -335,6 +382,8 @@ public final class GraphFilter implements Cloneable, 
Serializable {
                 clone.vertexFilter = this.vertexFilter.clone();
             if (null != this.edgeFilter)
                 clone.edgeFilter = this.edgeFilter.clone();
+            if (null != this.vertexPropertyFilter)
+                clone.vertexPropertyFilter = this.vertexPropertyFilter.clone();
             return clone;
         } catch (final CloneNotSupportedException e) {
             throw new IllegalStateException(e.getMessage(), e);
@@ -345,11 +394,25 @@ public final class GraphFilter implements Cloneable, 
Serializable {
     public String toString() {
         if (!this.hasFilter())
             return "graphfilter[none]";
-        else if (this.hasVertexFilter() && this.hasEdgeFilter())
-            return "graphfilter[" + this.vertexFilter + "," + this.edgeFilter 
+ "]";
-        else if (this.hasVertexFilter())
-            return "graphfilter[" + this.vertexFilter + "]";
-        else
-            return "graphfilter[" + this.edgeFilter + "]";
+        StringBuilder builder = new StringBuilder("graphfilter[");
+        boolean needDelimiter = false;
+        if (this.hasVertexFilter()) {
+            builder.append(this.vertexFilter);
+            needDelimiter = true;
+        }
+        if (this.hasEdgeFilter()) {
+            if (needDelimiter) {
+                builder.append(",");
+            }
+            builder.append(this.edgeFilter);
+            needDelimiter = true;
+        }
+        if (this.hasVertexPropertyFilter()) {
+            if (needDelimiter) {
+                builder.append(",");
+            }
+            builder.append(this.vertexPropertyFilter);
+        }
+        return builder.append("]").toString();
     }
 }
\ No newline at end of file
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraph.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraph.java
index 3bcdb7db39..0c47d78caa 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraph.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraph.java
@@ -47,6 +47,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Optional;
+import java.util.Set;
 import java.util.stream.Stream;
 
 /**
@@ -575,6 +576,13 @@ public final class StarGraph implements Graph, 
Serializable {
                             this.inEdges = inEdges;
                     }
                 }
+                if (graphFilter.hasVertexPropertyFilter()) {
+                    Set<String> retainSet = new HashSet<>();
+                    
graphFilter.legalVertexProperties(this).forEachRemaining(property -> {
+                        retainSet.add(property.key());
+                    });
+                    this.vertexProperties.keySet().removeIf(key -> 
!retainSet.contains(key));
+                }
                 return Optional.of(this);
             } else {
                 return Optional.empty();
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/TraversalStrategiesTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/TraversalStrategiesTest.java
index 1247986361..07abfa8da4 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/TraversalStrategiesTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/TraversalStrategiesTest.java
@@ -30,6 +30,7 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
 import 
org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Property;
 import org.apache.tinkerpop.gremlin.structure.Transaction;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.junit.Test;
@@ -168,6 +169,11 @@ public class TraversalStrategiesTest {
             return this;
         }
 
+        @Override
+        public GraphComputer vertexProperties(Traversal<Vertex, ? extends 
Property<?>> vertexPropertyFilter) {
+            return this;
+        }
+
         @Override
         public Future<ComputerResult> submit() {
             return new CompletableFuture<>();
diff --git 
a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphComputerTest.java
 
b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphComputerTest.java
index ce039e8ea0..d489a434d1 100644
--- 
a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphComputerTest.java
+++ 
b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphComputerTest.java
@@ -155,6 +155,12 @@ public class GraphComputerTest extends 
AbstractGremlinProcessTest {
             } catch (final UnsupportedOperationException e) {
                 
assertEquals(GraphComputer.Exceptions.graphFilterNotSupported().getMessage(), 
e.getMessage());
             }
+            try {
+                new BadGraphComputer().vertexProperties(__.properties("type"));
+                fail("Should throw an unsupported operation exception");
+            } catch (final UnsupportedOperationException e) {
+                
assertEquals(GraphComputer.Exceptions.graphFilterNotSupported().getMessage(), 
e.getMessage());
+            }
         } else {
             fail("Should not support graph filter: " + BadGraphComputer.class);
         }
@@ -197,6 +203,11 @@ public class GraphComputerTest extends 
AbstractGremlinProcessTest {
             throw GraphComputer.Exceptions.graphFilterNotSupported();
         }
 
+        @Override
+        public GraphComputer vertexProperties(Traversal<Vertex, ? extends 
Property<?>> vertexPropertyFilter) {
+            throw GraphComputer.Exceptions.graphFilterNotSupported();
+        }
+
         @Override
         public GraphComputer configure(final String key, final Object value) {
             return null;
@@ -1756,13 +1767,19 @@ public class GraphComputerTest extends 
AbstractGremlinProcessTest {
             } catch (final UnsupportedOperationException e) {
                 
assertEquals(GraphComputer.Exceptions.graphFilterNotSupported().getMessage(), 
e.getMessage());
             }
+            try {
+                
graphProvider.getGraphComputer(graph).vertexProperties(__.properties("prop1", 
"prop2"));
+                fail("Should throw an unsupported operation exception");
+            } catch (final UnsupportedOperationException e) {
+                
assertEquals(GraphComputer.Exceptions.graphFilterNotSupported().getMessage(), 
e.getMessage());
+            }
             return;
         }
         /// VERTEX PROGRAM
-        
graphProvider.getGraphComputer(graph).vertices(__.hasLabel("software")).program(new
 VertexProgramM(VertexProgramM.SOFTWARE_ONLY)).submit().get();
+        
graphProvider.getGraphComputer(graph).vertices(__.hasLabel("software")).vertexProperties(__.properties("dummy")).program(new
 VertexProgramM(VertexProgramM.SOFTWARE_ONLY)).submit().get();
         
graphProvider.getGraphComputer(graph).vertices(__.hasLabel("person")).program(new
 VertexProgramM(VertexProgramM.PEOPLE_ONLY)).submit().get();
         
graphProvider.getGraphComputer(graph).edges(__.bothE("knows")).program(new 
VertexProgramM(VertexProgramM.KNOWS_ONLY)).submit().get();
-        
graphProvider.getGraphComputer(graph).vertices(__.hasLabel("person")).edges(__.bothE("knows")).program(new
 VertexProgramM(VertexProgramM.PEOPLE_KNOWS_ONLY)).submit().get();
+        
graphProvider.getGraphComputer(graph).vertices(__.hasLabel("person")).vertexProperties(__.properties("name")).edges(__.bothE("knows")).program(new
 VertexProgramM(VertexProgramM.PEOPLE_KNOWS_ONLY)).submit().get();
         
graphProvider.getGraphComputer(graph).vertices(__.hasLabel("person")).edges(__.<Vertex>bothE("knows").has("weight",
 P.gt(0.5f))).program(new 
VertexProgramM(VertexProgramM.PEOPLE_KNOWS_WELL_ONLY)).submit().get();
         
graphProvider.getGraphComputer(graph).edges(__.<Vertex>bothE().limit(0)).program(new
 VertexProgramM(VertexProgramM.VERTICES_ONLY)).submit().get();
         
graphProvider.getGraphComputer(graph).edges(__.<Vertex>outE().limit(1)).program(new
 VertexProgramM(VertexProgramM.ONE_OUT_EDGE_ONLY)).submit().get();
@@ -1801,6 +1818,14 @@ public class GraphComputerTest extends 
AbstractGremlinProcessTest {
         } catch (final IllegalArgumentException e) {
             assertEquals(e.getMessage(), 
GraphComputer.Exceptions.edgeFilterAccessesAdjacentVertices(__.<Vertex>out().outE()).getMessage());
         }
+        try {
+            // VertexProgramM.PEOPLE_KNOWS_ONLY needs name property
+            graphProvider.getGraphComputer(graph)
+                
.vertices(__.hasLabel("person")).edges(__.bothE("knows")).vertexProperties(__.properties("dummy"))
+                .program(new 
VertexProgramM(VertexProgramM.PEOPLE_KNOWS_ONLY)).submit().get();
+        } catch (final ExecutionException e) {
+            assertTrue(e.getMessage().contains("The property does not exist as 
the key has no associated value for the provided element"));
+        }
     }
 
     public static class VertexProgramM implements VertexProgram {
diff --git 
a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/ranking/pagerank/PageRankVertexProgramTest.java
 
b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/ranking/pagerank/PageRankVertexProgramTest.java
index 6550a325b6..5c6087f9e8 100644
--- 
a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/ranking/pagerank/PageRankVertexProgramTest.java
+++ 
b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/ranking/pagerank/PageRankVertexProgramTest.java
@@ -22,6 +22,7 @@ import org.apache.tinkerpop.gremlin.LoadGraphWith;
 import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
 import org.apache.tinkerpop.gremlin.process.computer.ComputerResult;
 import org.apache.tinkerpop.gremlin.process.computer.GraphComputer;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 import org.junit.Test;
 
@@ -73,8 +74,9 @@ public class PageRankVertexProgramTest extends 
AbstractGremlinProcessTest {
     @LoadGraphWith(MODERN)
     public void shouldExecutePageRankWithEpsilonBreak() throws Exception {
         if 
(graphProvider.getGraphComputer(graph).features().supportsResultGraphPersistCombination(GraphComputer.ResultGraph.NEW,
 GraphComputer.Persist.VERTEX_PROPERTIES)) {
-            final ComputerResult result = 
graph.compute(graphProvider.getGraphComputer(graph).getClass()).
-                    
program(PageRankVertexProgram.build().epsilon(0.00001d).iterations(30).create(graph)).submit().get();
 // by using epsilon 0.00001, we should get iterations 11
+            final ComputerResult result = 
graph.compute(graphProvider.getGraphComputer(graph).getClass())
+                .vertexProperties(__.properties("name", "age", "lang"))
+                
.program(PageRankVertexProgram.build().epsilon(0.00001d).iterations(30).create(graph)).submit().get();
 // by using epsilon 0.00001, we should get iterations 11
             result.graph().traversal().V().forEachRemaining(v -> {
                 assertEquals(3, v.keys().size()); // name, age/lang, pageRank
                 assertTrue(v.keys().contains("name"));
diff --git 
a/hadoop-gremlin/src/main/java/org/apache/tinkerpop/gremlin/hadoop/process/computer/AbstractHadoopGraphComputer.java
 
b/hadoop-gremlin/src/main/java/org/apache/tinkerpop/gremlin/hadoop/process/computer/AbstractHadoopGraphComputer.java
index 278fc507b7..6c37def4d7 100644
--- 
a/hadoop-gremlin/src/main/java/org/apache/tinkerpop/gremlin/hadoop/process/computer/AbstractHadoopGraphComputer.java
+++ 
b/hadoop-gremlin/src/main/java/org/apache/tinkerpop/gremlin/hadoop/process/computer/AbstractHadoopGraphComputer.java
@@ -34,8 +34,8 @@ import 
org.apache.tinkerpop.gremlin.process.computer.VertexProgram;
 import org.apache.tinkerpop.gremlin.process.computer.util.GraphComputerHelper;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Property;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
-import org.apache.tinkerpop.gremlin.structure.io.Storage;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 import org.apache.tinkerpop.gremlin.util.Gremlin;
 import org.slf4j.Logger;
@@ -88,6 +88,12 @@ public abstract class AbstractHadoopGraphComputer implements 
GraphComputer {
         return this;
     }
 
+    @Override
+    public GraphComputer vertexProperties(final Traversal<Vertex, ? extends 
Property<?>> vertexPropertyFilter) {
+        this.graphFilter.setVertexPropertyFilter(vertexPropertyFilter);
+        return this;
+    }
+
     @Override
     public GraphComputer result(final ResultGraph resultGraph) {
         this.resultGraph = resultGraph;
diff --git 
a/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/structure/SparkTest.java
 
b/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/structure/SparkTest.java
index 17ef28811b..57857b3b49 100644
--- 
a/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/structure/SparkTest.java
+++ 
b/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/structure/SparkTest.java
@@ -29,6 +29,7 @@ import 
org.apache.tinkerpop.gremlin.hadoop.structure.HadoopGraph;
 import org.apache.tinkerpop.gremlin.hadoop.structure.io.gryo.GryoInputFormat;
 import org.apache.tinkerpop.gremlin.process.computer.GraphComputer;
 import 
org.apache.tinkerpop.gremlin.process.computer.ranking.pagerank.PageRankVertexProgram;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.spark.AbstractSparkTest;
 import org.apache.tinkerpop.gremlin.spark.process.computer.SparkGraphComputer;
 import 
org.apache.tinkerpop.gremlin.spark.process.computer.SparkHadoopGraphProvider;
@@ -71,7 +72,10 @@ public class SparkTest extends AbstractSparkTest {
             assertEquals(i, Spark.getRDDs().size());
             
configuration.setProperty(Constants.GREMLIN_HADOOP_OUTPUT_LOCATION, prefix + i);
             Graph graph = GraphFactory.open(configuration);
-            
graph.compute(SparkGraphComputer.class).persist(GraphComputer.Persist.VERTEX_PROPERTIES).program(PageRankVertexProgram.build().iterations(1).create(graph)).submit().get();
+            graph.compute(SparkGraphComputer.class)
+                .persist(GraphComputer.Persist.VERTEX_PROPERTIES)
+                .vertexProperties(__.properties("dummy"))
+                
.program(PageRankVertexProgram.build().iterations(1).create(graph)).submit().get();
             assertNotNull(Spark.getRDD(graphRDDName));
             assertEquals(i + 1, Spark.getRDDs().size());
         }
diff --git 
a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/computer/TinkerGraphComputer.java
 
b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/computer/TinkerGraphComputer.java
index bf6f594166..f406847c10 100644
--- 
a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/computer/TinkerGraphComputer.java
+++ 
b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/computer/TinkerGraphComputer.java
@@ -33,6 +33,7 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
 import 
org.apache.tinkerpop.gremlin.process.traversal.util.TraversalInterruptedException;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Property;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
@@ -128,6 +129,12 @@ public final class TinkerGraphComputer implements 
GraphComputer {
         return this;
     }
 
+    @Override
+    public GraphComputer vertexProperties(Traversal<Vertex, ? extends 
Property<?>> vertexPropertyFilter) {
+        this.graphFilter.setVertexPropertyFilter(vertexPropertyFilter);
+        return this;
+    }
+
     @Override
     public Future<ComputerResult> submit() {
         // a graph computer can only be executed once
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 43998fb292..40a497ba03 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
@@ -21,6 +21,8 @@ package 
org.apache.tinkerpop.gremlin.tinkergraph.process.computer;
 import org.apache.tinkerpop.gremlin.process.computer.GraphComputer;
 import org.apache.tinkerpop.gremlin.process.computer.GraphFilter;
 import org.apache.tinkerpop.gremlin.process.computer.VertexComputeKey;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertiesStep;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Element;
 import org.apache.tinkerpop.gremlin.structure.Graph;
@@ -36,9 +38,11 @@ import 
org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertex;
 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertexProperty;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -55,6 +59,7 @@ public final class TinkerGraphComputerView {
     private final Set<Object> legalVertices = new HashSet<>();
     private final Map<Object, Set<Object>> legalEdges = new HashMap<>();
     private final GraphFilter graphFilter;
+    private final Set<String> retainVertexProperties;
 
     public TinkerGraphComputerView(final TinkerGraph graph, final GraphFilter 
graphFilter, final Set<VertexComputeKey> computeKeys) {
         this.graph = graph;
@@ -76,6 +81,11 @@ public final class TinkerGraphComputerView {
                 }
             });
         }
+        if (this.graphFilter.hasVertexPropertyFilter()) {
+            retainVertexProperties = new 
HashSet<>(Arrays.asList(((PropertiesStep) 
graphFilter.getVertexPropertyFilter().getStartStep()).getPropertyKeys()));
+        } else {
+            retainVertexProperties = null;
+        }
     }
 
     public <V> Property<V> addProperty(final TinkerVertex vertex, final String 
key, final V value) {
@@ -97,13 +107,12 @@ public final class TinkerGraphComputerView {
     public List<VertexProperty<?>> getProperty(final TinkerVertex vertex, 
final String key) {
         // 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());
+        return vertexProperty.isEmpty() ? (List) 
getPropertiesMap(vertex).getOrDefault(key, Collections.emptyList()) : 
vertexProperty;
     }
 
     public List<Property> getProperties(final TinkerVertex vertex) {
         final List<Property> list = new ArrayList<>();
-        for (final List<VertexProperty> properties : 
TinkerHelper.getProperties(vertex).values()) {
+        for (final List<VertexProperty> properties : 
getPropertiesMap(vertex).values()) {
             list.addAll(properties);
         }
         for (final List<VertexProperty<?>> properties : 
this.computeProperties.getOrDefault(vertex, Collections.emptyMap()).values()) {
@@ -112,6 +121,14 @@ public final class TinkerGraphComputerView {
         return list;
     }
 
+    private Map<String, List<VertexProperty>> getPropertiesMap(final 
TinkerVertex vertex) {
+        Map<String, List<VertexProperty>> propertiesMap = 
TinkerHelper.getProperties(vertex);
+        if (retainVertexProperties != null) {
+            propertiesMap.keySet().retainAll(retainVertexProperties);
+        }
+        return propertiesMap;
+    }
+
     public void removeProperty(final TinkerVertex vertex, final String key, 
final VertexProperty property) {
         if (isComputeKey(key)) {
             this.removeValue(vertex, key, property);

Reply via email to