Rename sort keys to batch keys.
This commit is contained in:
@@ -31,12 +31,12 @@ type MatchKeysProvider interface {
|
|||||||
GetKeys(label string) ([]string, bool)
|
GetKeys(label string) ([]string, bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MatchKeys is a simple implementation of the MatchKeysProvider interface.
|
// SimpleMatchKeys is a simple implementation of the MatchKeysProvider interface.
|
||||||
type MatchKeys struct {
|
type SimpleMatchKeys struct {
|
||||||
Keys map[string][]string
|
Keys map[string][]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *MatchKeys) GetLabels() []string {
|
func (p *SimpleMatchKeys) GetLabels() []string {
|
||||||
labels := []string{}
|
labels := []string{}
|
||||||
for l := range p.Keys {
|
for l := range p.Keys {
|
||||||
labels = append(labels, l)
|
labels = append(labels, l)
|
||||||
@@ -44,7 +44,7 @@ func (p *MatchKeys) GetLabels() []string {
|
|||||||
return labels
|
return labels
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *MatchKeys) GetKeys(label string) ([]string, bool) {
|
func (p *SimpleMatchKeys) GetKeys(label string) ([]string, bool) {
|
||||||
if keys, exists := p.Keys[label]; exists {
|
if keys, exists := p.Keys[label]; exists {
|
||||||
return keys, exists
|
return keys, exists
|
||||||
} else {
|
} else {
|
||||||
@@ -216,9 +216,9 @@ func (s *Subgraph) NodesByLabel(label string) []*Node {
|
|||||||
// StructuredSubgraph is a structured collection of nodes and relationships for
|
// StructuredSubgraph is a structured collection of nodes and relationships for
|
||||||
// the purpose of conducting batch operations.
|
// the purpose of conducting batch operations.
|
||||||
type StructuredSubgraph struct {
|
type StructuredSubgraph struct {
|
||||||
// A map of grouped nodes, sorted by their label combinations.
|
// A map of grouped nodes, batched by their label combinations.
|
||||||
nodes map[string][]*Node
|
nodes map[string][]*Node
|
||||||
// A map of grouped relationships, sorted by their type and related node
|
// A map of grouped relationships, batched by their type and related node
|
||||||
// labels.
|
// labels.
|
||||||
rels map[string][]*Relationship
|
rels map[string][]*Relationship
|
||||||
// Provides node property keys used to match nodes with given labels in the
|
// Provides node property keys used to match nodes with given labels in the
|
||||||
@@ -236,7 +236,7 @@ func NewStructuredSubgraph(matchProvider MatchKeysProvider) *StructuredSubgraph
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddNode sorts a node into the subgraph.
|
// AddNode adds a node into the subgraph.
|
||||||
func (s *StructuredSubgraph) AddNode(node *Node) error {
|
func (s *StructuredSubgraph) AddNode(node *Node) error {
|
||||||
|
|
||||||
// Verify that the node has defined match property values.
|
// Verify that the node has defined match property values.
|
||||||
@@ -245,20 +245,20 @@ func (s *StructuredSubgraph) AddNode(node *Node) error {
|
|||||||
return fmt.Errorf("invalid node: %s", err)
|
return fmt.Errorf("invalid node: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the node's sort key.
|
// Determine the node's batch key.
|
||||||
sortKey := createNodeSortKey(matchLabel, node.Labels.ToArray())
|
batchKey := createNodeBatchKey(matchLabel, node.Labels.ToArray())
|
||||||
|
|
||||||
if _, exists := s.nodes[sortKey]; !exists {
|
if _, exists := s.nodes[batchKey]; !exists {
|
||||||
s.nodes[sortKey] = []*Node{}
|
s.nodes[batchKey] = []*Node{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the node to the subgraph.
|
// Add the node to the subgraph.
|
||||||
s.nodes[sortKey] = append(s.nodes[sortKey], node)
|
s.nodes[batchKey] = append(s.nodes[batchKey], node)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddRel sorts a relationship into the subgraph.
|
// AddRel adds a relationship into the subgraph.
|
||||||
func (s *StructuredSubgraph) AddRel(rel *Relationship) error {
|
func (s *StructuredSubgraph) AddRel(rel *Relationship) error {
|
||||||
|
|
||||||
// Verify that the start node has defined match property values.
|
// Verify that the start node has defined match property values.
|
||||||
@@ -273,25 +273,25 @@ func (s *StructuredSubgraph) AddRel(rel *Relationship) error {
|
|||||||
return fmt.Errorf("invalid end node: %s", err)
|
return fmt.Errorf("invalid end node: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the relationship's sort key.
|
// Determine the relationship's batch key.
|
||||||
sortKey := createRelSortKey(rel.Type, startLabel, endLabel)
|
batchKey := createRelBatchKey(rel.Type, startLabel, endLabel)
|
||||||
|
|
||||||
if _, exists := s.rels[sortKey]; !exists {
|
if _, exists := s.rels[batchKey]; !exists {
|
||||||
s.rels[sortKey] = []*Relationship{}
|
s.rels[batchKey] = []*Relationship{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the relationship to the subgraph.
|
// Add the relationship to the subgraph.
|
||||||
s.rels[sortKey] = append(s.rels[sortKey], rel)
|
s.rels[batchKey] = append(s.rels[batchKey], rel)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNodes returns the nodes grouped under the given sort key.
|
// GetNodes returns the nodes grouped under the given batch key.
|
||||||
func (s *StructuredSubgraph) GetNodes(nodeKey string) []*Node {
|
func (s *StructuredSubgraph) GetNodes(nodeKey string) []*Node {
|
||||||
return s.nodes[nodeKey]
|
return s.nodes[nodeKey]
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRels returns the rels grouped under the given sort key.
|
// GetRels returns the rels grouped under the given batch key.
|
||||||
func (s *StructuredSubgraph) GetRels(relKey string) []*Relationship {
|
func (s *StructuredSubgraph) GetRels(relKey string) []*Relationship {
|
||||||
return s.rels[relKey]
|
return s.rels[relKey]
|
||||||
}
|
}
|
||||||
@@ -318,7 +318,7 @@ func (s *StructuredSubgraph) RelCount() int {
|
|||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeKeys returns the list of node sort keys in the subgraph.
|
// NodeKeys returns the list of node batch keys in the subgraph.
|
||||||
func (s *StructuredSubgraph) NodeKeys() []string {
|
func (s *StructuredSubgraph) NodeKeys() []string {
|
||||||
keys := []string{}
|
keys := []string{}
|
||||||
for l := range s.nodes {
|
for l := range s.nodes {
|
||||||
@@ -327,7 +327,7 @@ func (s *StructuredSubgraph) NodeKeys() []string {
|
|||||||
return keys
|
return keys
|
||||||
}
|
}
|
||||||
|
|
||||||
// RelKeys returns the list of relationship sort keys in the subgraph.
|
// RelKeys returns the list of relationship batch keys in the subgraph.
|
||||||
func (s *StructuredSubgraph) RelKeys() []string {
|
func (s *StructuredSubgraph) RelKeys() []string {
|
||||||
keys := []string{}
|
keys := []string{}
|
||||||
for t := range s.rels {
|
for t := range s.rels {
|
||||||
@@ -336,38 +336,38 @@ func (s *StructuredSubgraph) RelKeys() []string {
|
|||||||
return keys
|
return keys
|
||||||
}
|
}
|
||||||
|
|
||||||
// createNodeSortKey returns the serialized node labels for sorting.
|
// createNodeBatchKey returns the serialized node labels for batching.
|
||||||
func createNodeSortKey(matchLabel string, labels []string) string {
|
func createNodeBatchKey(matchLabel string, labels []string) string {
|
||||||
sort.Strings(labels)
|
sort.Strings(labels)
|
||||||
serializedLabels := strings.Join(labels, ",")
|
serializedLabels := strings.Join(labels, ",")
|
||||||
return fmt.Sprintf("%s:%s", matchLabel, serializedLabels)
|
return fmt.Sprintf("%s:%s", matchLabel, serializedLabels)
|
||||||
}
|
}
|
||||||
|
|
||||||
// createRelSortKey returns the serialized relationship type and start/end node
|
// createRelBatchKey returns the serialized relationship type and start/end node
|
||||||
// labels for sorting.
|
// labels for batching.
|
||||||
func createRelSortKey(
|
func createRelBatchKey(
|
||||||
rtype string, startLabel string, endLabel string) string {
|
rtype string, startLabel string, endLabel string) string {
|
||||||
return strings.Join([]string{rtype, startLabel, endLabel}, ",")
|
return strings.Join([]string{rtype, startLabel, endLabel}, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeserializeNodeKey returns the list of node labels from the serialized sort
|
// DeserializeNodeBatchKey returns the list of node labels from the serialized batch
|
||||||
// key.
|
// key.
|
||||||
func DeserializeNodeKey(sortKey string) (string, []string, error) {
|
func DeserializeNodeBatchKey(batchKey string) (string, []string, error) {
|
||||||
parts := strings.Split(sortKey, ":")
|
parts := strings.Split(batchKey, ":")
|
||||||
if len(parts) != 2 {
|
if len(parts) != 2 {
|
||||||
return "", nil, fmt.Errorf("invalid node sort key: %s", sortKey)
|
return "", nil, fmt.Errorf("invalid node batch key: %s", batchKey)
|
||||||
}
|
}
|
||||||
matchLabel, serializedLabels := parts[0], parts[1]
|
matchLabel, serializedLabels := parts[0], parts[1]
|
||||||
labels := strings.Split(serializedLabels, ",")
|
labels := strings.Split(serializedLabels, ",")
|
||||||
return matchLabel, labels, nil
|
return matchLabel, labels, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeserializeRelKey returns the relationship type, start node label, and end
|
// DeserializeRelBatchKey returns the relationship type, start node label, and end
|
||||||
// node label from the serialized sort key. Panics if the sort key is invalid.
|
// node label from the serialized batch key. Panics if the batch key is invalid.
|
||||||
func DeserializeRelKey(sortKey string) (string, string, string, error) {
|
func DeserializeRelBatchKey(batchKey string) (string, string, string, error) {
|
||||||
parts := strings.Split(sortKey, ",")
|
parts := strings.Split(batchKey, ",")
|
||||||
if len(parts) != 3 {
|
if len(parts) != 3 {
|
||||||
return "", "", "", fmt.Errorf("invalid relationship sort key: %s", sortKey)
|
return "", "", "", fmt.Errorf("invalid relationship batch key: %s", batchKey)
|
||||||
}
|
}
|
||||||
rtype, startLabel, endLabel := parts[0], parts[1], parts[2]
|
rtype, startLabel, endLabel := parts[0], parts[1], parts[2]
|
||||||
return rtype, startLabel, endLabel, nil
|
return rtype, startLabel, endLabel, nil
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMatchKeys(t *testing.T) {
|
func TestMatchKeys(t *testing.T) {
|
||||||
matchKeys := &MatchKeys{
|
matchKeys := &SimpleMatchKeys{
|
||||||
Keys: map[string][]string{
|
Keys: map[string][]string{
|
||||||
"User": {"pubkey"},
|
"User": {"pubkey"},
|
||||||
"Event": {"id"},
|
"Event": {"id"},
|
||||||
@@ -34,34 +34,34 @@ func TestMatchKeys(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNodeSortKey(t *testing.T) {
|
func TestNodeBatchKey(t *testing.T) {
|
||||||
matchLabel := "Event"
|
matchLabel := "Event"
|
||||||
labels := []string{"Event", "AddressableEvent"}
|
labels := []string{"Event", "AddressableEvent"}
|
||||||
|
|
||||||
// labels should be sorted by key generator
|
// labels should be batched by key generator
|
||||||
expectedKey := "Event:AddressableEvent,Event"
|
expectedKey := "Event:AddressableEvent,Event"
|
||||||
|
|
||||||
// Test Serialization
|
// Test Serialization
|
||||||
sortKey := createNodeSortKey(matchLabel, labels)
|
batchKey := createNodeBatchKey(matchLabel, labels)
|
||||||
assert.Equal(t, expectedKey, sortKey)
|
assert.Equal(t, expectedKey, batchKey)
|
||||||
|
|
||||||
// Test Deserialization
|
// Test Deserialization
|
||||||
returnedMatchLabel, returnedLabels, err := DeserializeNodeKey(sortKey)
|
returnedMatchLabel, returnedLabels, err := DeserializeNodeBatchKey(batchKey)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, matchLabel, returnedMatchLabel)
|
assert.Equal(t, matchLabel, returnedMatchLabel)
|
||||||
assert.ElementsMatch(t, labels, returnedLabels)
|
assert.ElementsMatch(t, labels, returnedLabels)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRelSortKey(t *testing.T) {
|
func TestRelBatchKey(t *testing.T) {
|
||||||
rtype, startLabel, endLabel := "SIGNED", "User", "Event"
|
rtype, startLabel, endLabel := "SIGNED", "User", "Event"
|
||||||
expectedKey := "SIGNED,User,Event"
|
expectedKey := "SIGNED,User,Event"
|
||||||
|
|
||||||
// Test Serialization
|
// Test Serialization
|
||||||
sortKey := createRelSortKey(rtype, startLabel, endLabel)
|
batchKey := createRelBatchKey(rtype, startLabel, endLabel)
|
||||||
assert.Equal(t, expectedKey, sortKey)
|
assert.Equal(t, expectedKey, batchKey)
|
||||||
|
|
||||||
// Test Deserialization
|
// Test Deserialization
|
||||||
returnedRtype, returnedStartLabel, returnedEndLabel, err := DeserializeRelKey(sortKey)
|
returnedRtype, returnedStartLabel, returnedEndLabel, err := DeserializeRelBatchKey(batchKey)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, rtype, returnedRtype)
|
assert.Equal(t, rtype, returnedRtype)
|
||||||
assert.Equal(t, startLabel, returnedStartLabel)
|
assert.Equal(t, startLabel, returnedStartLabel)
|
||||||
@@ -69,7 +69,7 @@ func TestRelSortKey(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMatchProps(t *testing.T) {
|
func TestMatchProps(t *testing.T) {
|
||||||
matchKeys := &MatchKeys{
|
matchKeys := &SimpleMatchKeys{
|
||||||
Keys: map[string][]string{
|
Keys: map[string][]string{
|
||||||
"User": {"pubkey"},
|
"User": {"pubkey"},
|
||||||
"Event": {"id"},
|
"Event": {"id"},
|
||||||
@@ -133,7 +133,7 @@ func TestMatchProps(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStructuredSubgraphAddNode(t *testing.T) {
|
func TestStructuredSubgraphAddNode(t *testing.T) {
|
||||||
matchKeys := NewMatchKeys()
|
matchKeys := NewSimpleMatchKeys()
|
||||||
subgraph := NewStructuredSubgraph(matchKeys)
|
subgraph := NewStructuredSubgraph(matchKeys)
|
||||||
node := NewEventNode("abc123")
|
node := NewEventNode("abc123")
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ func TestStructuredSubgraphAddNode(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStructuredSubgraphAddNodeInvalid(t *testing.T) {
|
func TestStructuredSubgraphAddNodeInvalid(t *testing.T) {
|
||||||
matchKeys := NewMatchKeys()
|
matchKeys := NewSimpleMatchKeys()
|
||||||
subgraph := NewStructuredSubgraph(matchKeys)
|
subgraph := NewStructuredSubgraph(matchKeys)
|
||||||
node := NewNode("Event", Properties{})
|
node := NewNode("Event", Properties{})
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ func TestStructuredSubgraphAddNodeInvalid(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStructuredSubgraphAddRel(t *testing.T) {
|
func TestStructuredSubgraphAddRel(t *testing.T) {
|
||||||
matchKeys := NewMatchKeys()
|
matchKeys := NewSimpleMatchKeys()
|
||||||
subgraph := NewStructuredSubgraph(matchKeys)
|
subgraph := NewStructuredSubgraph(matchKeys)
|
||||||
|
|
||||||
userNode := NewUserNode("pubkey1")
|
userNode := NewUserNode("pubkey1")
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import (
|
|||||||
// Schema Match Keys
|
// Schema Match Keys
|
||||||
// ========================================
|
// ========================================
|
||||||
|
|
||||||
func NewMatchKeys() *MatchKeys {
|
func NewSimpleMatchKeys() *SimpleMatchKeys {
|
||||||
return &MatchKeys{
|
return &SimpleMatchKeys{
|
||||||
Keys: map[string][]string{
|
Keys: map[string][]string{
|
||||||
"User": {"pubkey"},
|
"User": {"pubkey"},
|
||||||
"Relay": {"url"},
|
"Relay": {"url"},
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ func MergeSubgraph(
|
|||||||
) ([]neo4j.ResultSummary, error) {
|
) ([]neo4j.ResultSummary, error) {
|
||||||
// Validate subgraph
|
// Validate subgraph
|
||||||
for _, nodeKey := range subgraph.NodeKeys() {
|
for _, nodeKey := range subgraph.NodeKeys() {
|
||||||
matchLabel, _, err := graph.DeserializeNodeKey(nodeKey)
|
matchLabel, _, err := graph.DeserializeNodeBatchKey(nodeKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -27,7 +27,7 @@ func MergeSubgraph(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, relKey := range subgraph.RelKeys() {
|
for _, relKey := range subgraph.RelKeys() {
|
||||||
_, startLabel, endLabel, err := graph.DeserializeRelKey(relKey)
|
_, startLabel, endLabel, err := graph.DeserializeRelBatchKey(relKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@ func MergeSubgraph(
|
|||||||
var resultSummaries []neo4j.ResultSummary
|
var resultSummaries []neo4j.ResultSummary
|
||||||
|
|
||||||
for _, nodeKey := range subgraph.NodeKeys() {
|
for _, nodeKey := range subgraph.NodeKeys() {
|
||||||
matchLabel, labels, _ := graph.DeserializeNodeKey(nodeKey)
|
matchLabel, labels, _ := graph.DeserializeNodeBatchKey(nodeKey)
|
||||||
nodeResultSummary, err := MergeNodes(
|
nodeResultSummary, err := MergeNodes(
|
||||||
ctx, tx,
|
ctx, tx,
|
||||||
matchLabel,
|
matchLabel,
|
||||||
@@ -68,7 +68,7 @@ func MergeSubgraph(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, relKey := range subgraph.RelKeys() {
|
for _, relKey := range subgraph.RelKeys() {
|
||||||
rtype, startLabel, endLabel, _ := graph.DeserializeRelKey(relKey)
|
rtype, startLabel, endLabel, _ := graph.DeserializeRelBatchKey(relKey)
|
||||||
relResultSummary, err := MergeRels(
|
relResultSummary, err := MergeRels(
|
||||||
ctx, tx,
|
ctx, tx,
|
||||||
rtype,
|
rtype,
|
||||||
|
|||||||
Reference in New Issue
Block a user