You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ly...@apache.org on 2022/05/20 17:12:23 UTC

[tinkerpop] 01/01: Handling merge conflicts for gremlin-go strategies

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

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

commit 13a1a35be33a5a4e928b78937a5ba4b8df206c55
Merge: 039d409337 c8db98c5f9
Author: Lyndon Bauto <ly...@bitquilltech.com>
AuthorDate: Fri May 20 10:12:05 2022 -0700

    Handling merge conflicts for gremlin-go strategies

 .../traversal/translator/GolangTranslator.java     |  21 +-
 .../traversal/translator/GolangTranslatorTest.java |   4 +-
 gremlin-go/README.md                               |   2 +-
 gremlin-go/driver/connection_test.go               |  76 +++++++
 gremlin-go/driver/cucumber/cucumberWorld.go        |  35 +++-
 gremlin-go/driver/graphBinary.go                   | 218 +++++++++++++++++----
 gremlin-go/driver/graphBinary_test.go              |  32 ++-
 gremlin-go/driver/serializer.go                    |  18 +-
 gremlin-go/driver/strategies.go                    | 206 ++++++++++++-------
 gremlin-go/driver/strategies_test.go               |  39 +++-
 gremlin-go/driver/traversal.go                     |  41 ++++
 11 files changed, 553 insertions(+), 139 deletions(-)

diff --cc gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GolangTranslator.java
index 70107063f5,93c05af325..9c0c6a39a3
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GolangTranslator.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GolangTranslator.java
@@@ -256,33 -245,19 +255,40 @@@ public final class GolangTranslator imp
          @Override
          protected Script produceScript(final TraversalStrategyProxy<?> o) {
              if (o.getConfiguration().isEmpty()) {
-                 return script.append("strategyFactory(\"" + o.getStrategyClass().getSimpleName() + "\", map[string]interface{}{})");
+                 return script.append(GO_PACKAGE_NAME + o.getStrategyClass().getSimpleName() + "()");
              } else {
-                 script.append("strategyFactory(\"" + o.getStrategyClass().getSimpleName() + "\", map[string]interface{}{");
+                 script.append(GO_PACKAGE_NAME + o.getStrategyClass().getSimpleName() + "(");
+                 script.append(GO_PACKAGE_NAME + o.getStrategyClass().getSimpleName() + "Config{");
                  final Iterator<String> keys = IteratorUtils.stream(o.getConfiguration().getKeys()).
-                         filter(e -> !e.equals(TraversalStrategy.STRATEGY)).iterator();
+                     filter(e -> !e.equals(TraversalStrategy.STRATEGY)).iterator();
                  while (keys.hasNext()) {
                      final String k = keys.next();
++<<<<<<< HEAD
 +                    script.append("\"");
 +                    script.append(k);
 +                    script.append("\": ");
 +                    if (o.getConfiguration().getProperty(k) instanceof List) {
 +                        List<Object> list =(List<Object>) o.getConfiguration().getProperty(k);
 +                        Iterator iterator = list.iterator();
 +                        script.append("[]interface{}{");
 +                        while(iterator.hasNext()) {
 +                            convertToScript(iterator.next());
 +                            if (iterator.hasNext())
 +                                script.append(", ");
 +                        }
 +                        script.append("}");
 +                    } else {
 +                        convertToScript(o.getConfiguration().getProperty(k));
 +                    }
 +                    if (keys.hasNext())
 +                        script.append(", ");
++=======
+                     script.append(SymbolHelper.toGolang(k));
+                     script.append(": ");
+                     convertToScript(o.getConfiguration().getProperty(k));
+                     script.append(", ");
++>>>>>>> 3.5-dev
                  }
- 
                  return script.append("})");
              }
          }
diff --cc gremlin-go/driver/cucumber/cucumberWorld.go
index bfe21e26a0,7b8c569b55..2e70be6c19
--- a/gremlin-go/driver/cucumber/cucumberWorld.go
+++ b/gremlin-go/driver/cucumber/cucumberWorld.go
@@@ -252,27 -213,16 +252,48 @@@ func strategyFactory(strategyName strin
  	switch strategyName {
  	case "VertexProgramStrategy":
  		graphComputer, _ := params["graphComputer"].(string)
- 		return gremlingo.VertexProgramStrategy(graphComputer, "", "", 0, nil, nil, nil)
+ 		config := gremlingo.VertexProgramStrategyConfig{
+ 			GraphComputer: graphComputer,
+ 			Workers:       0,
+ 			Persist:       "",
+ 			Result:        "",
+ 			Vertices:      nil,
+ 			Edges:         nil,
+ 			Configuration: nil,
+ 		}
+ 		return gremlingo.VertexProgramStrategy(config)
 +	case "ProductiveByStrategy":
 +		productiveKeys, _ := params["productiveKeys"]
 +		productiveKeysInterface := productiveKeys.([]interface{})
 +		var productiveKeysStrings = make([]string, len(productiveKeysInterface))
 +		for i := range productiveKeysInterface {
 +			productiveKeysStrings[i] = productiveKeysInterface[i].(string)
 +		}
- 		return gremlingo.ProductiveByStrategy(productiveKeysStrings)
++		config := gremlingo.ProductiveByStrategyConfig{
++			ProductiveKeys: productiveKeysStrings,
++		}
++		return gremlingo.ProductiveByStrategy(config)
 +	case "ReadOnlyStrategy":
 +		return gremlingo.ReadOnlyStrategy()
 +	case "SubgraphStrategy":
++		edges, _ := params["edges"].(*gremlingo.GraphTraversal)
++		vertices, _ := params["vertices"].(*gremlingo.GraphTraversal)
++		vertexProperties, _ := params["vertexProperties"].(*gremlingo.GraphTraversal)
 +		checkAdjacentVertices, _ := params["checkAdjacentVertices"]
- 		edges, _ := params["edges"]
- 		vertices, _ := params["vertices"]
- 		vertexProperties, _ := params["vertexProperties"]
- 		return gremlingo.SubgraphStrategy(vertices, edges, vertexProperties, checkAdjacentVertices)
++		config := gremlingo.SubgraphStrategyConfig{
++			Edges:                 edges,
++			Vertices:              vertices,
++			VertexProperties:      vertexProperties,
++			CheckAdjacentVertices: checkAdjacentVertices,
++		}
++		return gremlingo.SubgraphStrategy(config)
 +	case "SeedStrategy":
 +		seed, _ := params["seed"]
- 		return gremlingo.SeedStrategy(int64(seed.(int)))
++		config := gremlingo.SeedStrategyConfig{
++			Seed: int64(seed.(int)),
++		}
++		return gremlingo.SeedStrategy(config)
  	}
  	return nil
 +
  }
diff --cc gremlin-go/driver/graphBinary.go
index f67bfa8e71,dedd19bc3f..4f07a03eb6
--- a/gremlin-go/driver/graphBinary.go
+++ b/gremlin-go/driver/graphBinary.go
@@@ -76,7 -78,8 +78,9 @@@ const 
  	textPType             dataType = 0x28
  	traversalStrategyType dataType = 0x29
  	bulkSetType           dataType = 0x2a
 +	mergeType             dataType = 0x2e
+ 	metricsType           dataType = 0x2c
+ 	traversalMetricsType  dataType = 0x2d
  	durationType          dataType = 0x81
  	nullType              dataType = 0xFE
  )
diff --cc gremlin-go/driver/strategies.go
index ac3ba68cec,b7d25c9f1f..c6b751907b
--- a/gremlin-go/driver/strategies.go
+++ b/gremlin-go/driver/strategies.go
@@@ -53,14 -53,21 +53,20 @@@ func ElementIdStrategy() TraversalStrat
  	return &traversalStrategy{name: decorationNamespace + "ElementIdStrategy"}
  }
  
- func HaltedTraverserStrategy(haltedTraverserFactoryName string) *traversalStrategy {
- 	config := make(map[string]interface{})
- 	if haltedTraverserFactoryName != "" {
- 		config["haltedTraverserFactory"] = haltedTraverserFactoryName
+ func HaltedTraverserStrategy(config HaltedTraverserStrategyConfig) TraversalStrategy {
+ 	configMap := make(map[string]interface{})
+ 	if config.HaltedTraverserFactoryName != "" {
+ 		configMap["haltedTraverserFactory"] = config.HaltedTraverserFactoryName
  	}
- 	return &traversalStrategy{name: decorationNamespace + "HaltedTraverserStrategy", configuration: config}
+ 	return &traversalStrategy{name: decorationNamespace + "HaltedTraverserStrategy", configuration: configMap}
+ }
+ 
+ // HaltedTraverserStrategyConfig provides configuration options for HaltedTraverserStrategy.
+ // Zeroed (unset) values are ignored.
+ type HaltedTraverserStrategyConfig struct {
+ 	HaltedTraverserFactoryName string
  }
  
 -
  // OptionsStrategy will not alter the Traversal. It is only a holder for configuration options associated with the
  // Traversal meant to be accessed by steps or other classes that might have some interaction with it. It is
  // essentially a way for users to provide Traversal level configuration options that can be used in various ways
@@@ -70,20 -77,29 +76,29 @@@ func OptionsStrategy(options map[string
  }
  
  // PartitionStrategy partitions the Vertices, Edges and Vertex properties of a Graph into String named
- // partitions (i.e. buckets, subgraphs, etc.).  It blinds a Traversal from "seeing" specified areas of
+ // partitions (i.e. buckets, subgraphs, etc.). It blinds a Traversal from "seeing" specified areas of
  // the graph. The Traversal will ignore all Graph elements not in those "read" partitions.
- func PartitionStrategy(partitionKey, writePartition string, readPartitions []string, includeMetaProperties bool) *traversalStrategy {
- 	config := map[string]interface{}{"includeMetaProperties": includeMetaProperties}
- 	if partitionKey != "" {
- 		config["partitionKey"] = partitionKey
+ func PartitionStrategy(config PartitionStrategyConfig) TraversalStrategy {
+ 	configMap := map[string]interface{}{"includeMetaProperties": config.IncludeMetaProperties}
+ 	if config.PartitionKey != "" {
+ 		configMap["partitionKey"] = config.PartitionKey
  	}
- 	if writePartition != "" {
- 		config["writePartition"] = writePartition
+ 	if config.WritePartition != "" {
+ 		configMap["writePartition"] = config.WritePartition
  	}
- 	if len(readPartitions) != 0 {
- 		config["readPartitions"] = readPartitions
+ 	if len(config.ReadPartitions) != 0 {
+ 		configMap["readPartitions"] = config.ReadPartitions
  	}
- 	return &traversalStrategy{name: decorationNamespace + "PartitionStrategy", configuration: config}
+ 	return &traversalStrategy{name: decorationNamespace + "PartitionStrategy", configuration: configMap}
+ }
+ 
+ // PartitionStrategyConfig provides configuration options for PartitionStrategy.
+ // Zeroed (unset) values are ignored except IncludeMetaProperties.
+ type PartitionStrategyConfig struct {
 -	PartitionKey string
 -	WritePartition string
 -	ReadPartitions []string
++	PartitionKey          string
++	WritePartition        string
++	ReadPartitions        []string
+ 	IncludeMetaProperties bool
  }
  
  // SeedStrategy resets the specified Seed value for Seedable steps, which in turn will produce deterministic
@@@ -101,48 -122,63 +121,67 @@@ type SeedStrategyConfig struct 
  // SubgraphStrategy provides a way to limit the view of a Traversal. By providing Traversal representations that
  // represent a form of filtering criterion for Vertices and/or Edges, this strategy will inject that criterion into
  // the appropriate places of a Traversal thus restricting what it Traverses and returns.
- func SubgraphStrategy(vertices, edges, vertexProperties interface{}, checkAdjacentVertices interface{}) *traversalStrategy { // all vars can be Traversal or null
- 	config := make(map[string]interface{})
- 	if vertices != nil {
- 		config["vertices"] = vertices
+ func SubgraphStrategy(config SubgraphStrategyConfig) TraversalStrategy {
+ 	configMap := make(map[string]interface{})
+ 	if config.Vertices != nil {
+ 		configMap["vertices"] = config.Vertices
  	}
- 	if edges != nil {
- 		config["edges"] = edges
+ 	if config.Edges != nil {
+ 		configMap["edges"] = config.Edges
  	}
- 	if vertexProperties != nil {
- 		config["vertexProperties"] = vertexProperties
+ 	if config.VertexProperties != nil {
+ 		configMap["vertexProperties"] = config.VertexProperties
  	}
- 	if checkAdjacentVertices != nil {
- 		config["checkAdjacentVertices"] = checkAdjacentVertices.(bool)
++	if config.CheckAdjacentVertices != nil {
++		configMap["checkAdjacentVertices"] = config.CheckAdjacentVertices.(bool)
 +	}
- 	return &traversalStrategy{name: decorationNamespace + "SubgraphStrategy", configuration: config}
+ 	return &traversalStrategy{name: decorationNamespace + "SubgraphStrategy", configuration: configMap}
+ }
+ 
+ // SubgraphStrategyConfig provides configuration options for SubgraphStrategy. Zeroed (unset) values are ignored.
+ type SubgraphStrategyConfig struct {
 -	Vertices *GraphTraversal
 -	Edges *GraphTraversal
 -	VertexProperties *GraphTraversal
++	Vertices              *GraphTraversal
++	Edges                 *GraphTraversal
++	VertexProperties      *GraphTraversal
++	CheckAdjacentVertices interface{}
  }
  
- func VertexProgramStrategy(graphComputer, persist, result string, workers int,
- 	vertices, edges interface{}, configuration map[string]interface{}) *traversalStrategy {
- 	config := make(map[string]interface{})
- 	if graphComputer != "" {
- 		config["graphComputer"] = graphComputer
+ func VertexProgramStrategy(config VertexProgramStrategyConfig) TraversalStrategy {
+ 	configMap := make(map[string]interface{})
+ 	if config.GraphComputer != "" {
+ 		configMap["graphComputer"] = config.GraphComputer
  	}
- 	if persist != "" {
- 		config["persist"] = persist
+ 	if config.Workers != 0 {
+ 		configMap["workers"] = config.Workers
  	}
- 	if result != "" {
- 		config["result"] = result
+ 	if config.Persist != "" {
+ 		configMap["persist"] = config.Persist
  	}
- 	if workers != 0 {
- 		config["workers"] = workers
+ 	if config.Result != "" {
+ 		configMap["result"] = config.Result
  	}
- 	if vertices != nil {
- 		config["vertices"] = vertices
+ 	if config.Vertices != nil {
+ 		configMap["vertices"] = config.Vertices
  	}
- 	if edges != nil {
- 		config["edges"] = edges
+ 	if config.Edges != nil {
+ 		configMap["edges"] = config.Edges
  	}
- 	for k, v := range configuration {
- 		config[k] = v
+ 	for k, v := range config.Configuration {
+ 		configMap[k] = v
  	}
- 	return &traversalStrategy{name: computerDecorationNamespace + "VertexProgramStrategy", configuration: config}
+ 	return &traversalStrategy{name: computerDecorationNamespace + "VertexProgramStrategy", configuration: configMap}
+ }
+ 
+ // VertexProgramStrategyConfig provides configuration options for VertexProgramStrategy.
+ // Zeroed (unset) values are ignored.
+ type VertexProgramStrategyConfig struct {
+ 	GraphComputer string
 -	Workers int
 -	Persist string
 -	Result string
 -	Vertices *GraphTraversal
 -	Edges *GraphTraversal
++	Workers       int
++	Persist       string
++	Result        string
++	Vertices      *GraphTraversal
++	Edges         *GraphTraversal
+ 	Configuration map[string]interface{}
  }
  
  // Finalization strategies
@@@ -160,13 -202,20 +205,20 @@@ type MatchAlgorithmStrategyConfig struc
  // EdgeLabelVerificationStrategy does not allow Edge traversal steps to have no label specified.
  // Providing one or more labels is considered to be a best practice, however, TinkerPop will not force
  // the specification of Edge labels; instead, providers or users will have to enable this strategy explicitly.
- func EdgeLabelVerificationStrategy(logWarning, throwException bool) *traversalStrategy {
- 	config := map[string]interface{}{
- 		"logWarning":     logWarning,
- 		"throwException": throwException,
+ func EdgeLabelVerificationStrategy(config EdgeLabelVerificationStrategyConfig) TraversalStrategy {
+ 	configMap := map[string]interface{}{
+ 		"logWarning":     config.LogWarning,
+ 		"throwException": config.ThrowExcecption,
  	}
  
- 	return &traversalStrategy{name: verificationNamespace + "EdgeLabelVerificationStrategy", configuration: config}
+ 	return &traversalStrategy{name: verificationNamespace + "EdgeLabelVerificationStrategy", configuration: configMap}
+ }
+ 
+ // EdgeLabelVerificationStrategyConfig provides configuration options for EdgeLabelVerificationStrategy.
+ // Zeroed (unset) values are used.
+ type EdgeLabelVerificationStrategyConfig struct {
 -	LogWarning bool
++	LogWarning      bool
+ 	ThrowExcecption bool
  }
  
  // LambdaRestrictionStrategy does not allow lambdas to be used in a Traversal. The contents of a lambda
@@@ -184,15 -233,23 +236,23 @@@ func ReadOnlyStrategy() TraversalStrate
  
  // ReservedKeysVerificationStrategy detects property keys that should not be used by the traversal.
  // A term may be reserved by a particular graph implementation or as a convention given best practices.
- func ReservedKeysVerificationStrategy(logWarning, throwException bool, keys []string) *traversalStrategy {
- 	config := map[string]interface{}{
- 		"logWarning":     logWarning,
- 		"throwException": throwException,
+ func ReservedKeysVerificationStrategy(config ReservedKeysVerificationStrategyConfig) TraversalStrategy {
+ 	configMap := map[string]interface{}{
+ 		"logWarning":     config.LogWarning,
+ 		"throwException": config.ThrowException,
  	}
- 	if keys != nil {
- 		config["keys"] = keys
+ 	if len(config.Keys) != 0 {
+ 		configMap["keys"] = config.Keys
  	}
- 	return &traversalStrategy{name: verificationNamespace + "ReservedKeysVerificationStrategy", configuration: config}
+ 	return &traversalStrategy{name: verificationNamespace + "ReservedKeysVerificationStrategy", configuration: configMap}
+ }
+ 
+ // ReservedKeysVerificationStrategyConfig provides configuration options for ReservedKeysVerificationStrategy.
+ // Zeroed (unset) values are used except Keys.
+ type ReservedKeysVerificationStrategyConfig struct {
 -	LogWarning bool
++	LogWarning     bool
+ 	ThrowException bool
 -	Keys []string
++	Keys           []string
  }
  
  // Optimization strategies
diff --cc gremlin-go/driver/strategies_test.go
index 763d46a16b,f8a3d37f41..9052ac6cd2
--- a/gremlin-go/driver/strategies_test.go
+++ b/gremlin-go/driver/strategies_test.go
@@@ -97,8 -104,13 +104,13 @@@ func TestStrategy(t *testing.T) 
  	t.Run("Test read with SubgraphStrategy", func(t *testing.T) {
  		g := getModernGraph(t, testNoAuthUrl, &AuthInfo{}, &tls.Config{})
  		defer g.remoteConnection.Close()
--
- 		count, err := g.WithStrategies(SubgraphStrategy(T__.HasLabel(testLabel), nil, nil, nil)).V().Count().ToList()
+ 		config := SubgraphStrategyConfig{
 -			Vertices:         T__.HasLabel(testLabel),
 -			Edges:            nil,
 -			VertexProperties: nil,
++			Vertices:              T__.HasLabel(testLabel),
++			Edges:                 nil,
++			VertexProperties:      nil,
++			CheckAdjacentVertices: nil,
+ 		}
+ 		count, err := g.WithStrategies(SubgraphStrategy(config)).V().Count().ToList()
  		assert.Nil(t, err)
  		assert.NotNil(t, count)
  		assert.Equal(t, 1, len(count))