Skip to content

Commit 550dd5c

Browse files
committed
Construct inverse topology after relationship scanning
1 parent 39efdef commit 550dd5c

File tree

1 file changed

+41
-19
lines changed

1 file changed

+41
-19
lines changed

core/src/main/java/org/neo4j/gds/core/loading/RelationshipsAndProperties.java

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -89,44 +89,66 @@ static RelationshipsAndProperties of(Map<RelationshipTypeAndProjection, List<Rel
8989
.build();
9090
}
9191

92-
static RelationshipsAndProperties of(Collection<SingleTypeRelationshipImporter.SingleTypeRelationshipImportContext> builders) {
93-
var relTypeCount = builders.size();
94-
Map<RelationshipType, Relationships.Topology> relationships = new HashMap<>(relTypeCount);
92+
/**
93+
* This method creates the final {@link org.neo4j.gds.core.loading.RelationshipsAndProperties} in preparation
94+
* for the {@link org.neo4j.gds.api.GraphStore}.
95+
* <p>
96+
* The method is used in the context of native projection, where each projected relationship type (and its
97+
* properties) is represented by a {@link org.neo4j.gds.core.loading.SingleTypeRelationshipImporter.SingleTypeRelationshipImportContext}.
98+
*
99+
* @param importContexts each import context maps to a relationship type being created
100+
* @return a wrapper type ready to be consumed by a {@link org.neo4j.gds.api.GraphStore}
101+
*/
102+
static RelationshipsAndProperties of(Collection<SingleTypeRelationshipImporter.SingleTypeRelationshipImportContext> importContexts) {
103+
var relTypeCount = importContexts.size();
104+
Map<RelationshipType, ImmutableTopology.Builder> relationshipBuilders = new HashMap<>(relTypeCount);
95105
Map<RelationshipType, RelationshipPropertyStore> relationshipPropertyStores = new HashMap<>(relTypeCount);
96106
Map<RelationshipType, Direction> directions = new HashMap<>(relTypeCount);
97107

98-
builders.forEach((context) -> {
99-
var adjacencyListsWithProperties = context.singleTypeRelationshipImporter().build();
108+
importContexts.forEach((importContext) -> {
109+
var adjacencyListsWithProperties = importContext.singleTypeRelationshipImporter().build();
100110

101111
var adjacency = adjacencyListsWithProperties.adjacency();
102112
var properties = adjacencyListsWithProperties.properties();
103-
long relationshipCount = adjacencyListsWithProperties.relationshipCount();
104-
105-
RelationshipProjection projection = context.relationshipProjection();
113+
var relationshipCount = adjacencyListsWithProperties.relationshipCount();
114+
var relationshipProjection = importContext.relationshipProjection();
115+
116+
var topologyBuilder = relationshipBuilders.computeIfAbsent(
117+
importContext.relationshipType(),
118+
relationshipType -> ImmutableTopology.builder()
119+
.elementCount(relationshipCount)
120+
.isMultiGraph(relationshipProjection.isMultiGraph())
121+
);
106122

107-
relationships.put(
108-
context.relationshipType(),
109-
ImmutableTopology.of(
110-
adjacency,
111-
relationshipCount,
112-
projection.isMultiGraph()
113-
)
123+
importContext.inverseOfRelationshipType().ifPresentOrElse(
124+
__ -> topologyBuilder.inverseAdjacencyList(adjacency),
125+
() -> topologyBuilder.adjacencyList(adjacency)
114126
);
115127

116-
if (!projection.properties().isEmpty()) {
128+
// TODO: we only add the properties for the forward relationships for now
129+
if (!relationshipProjection.properties().isEmpty() && importContext.inverseOfRelationshipType().isEmpty()) {
117130
relationshipPropertyStores.put(
118-
context.relationshipType(),
131+
importContext.relationshipType(),
119132
constructRelationshipPropertyStore(
120-
projection,
133+
relationshipProjection,
121134
properties,
122135
relationshipCount
123136
)
124137
);
125138
}
126139

127-
directions.put(context.relationshipType(), Direction.fromOrientation(context.relationshipProjection().orientation()));
140+
directions.put(
141+
importContext.relationshipType(),
142+
Direction.fromOrientation(importContext.relationshipProjection().orientation())
143+
);
128144
});
129145

146+
var relationships = relationshipBuilders.entrySet().stream().collect(
147+
Collectors.toMap(
148+
Map.Entry::getKey,
149+
e -> e.getValue().build()
150+
));
151+
130152
return ImmutableRelationshipsAndProperties.builder()
131153
.relationships(relationships)
132154
.properties(relationshipPropertyStores)

0 commit comments

Comments
 (0)