Skip to content

Commit f3e8b29

Browse files
authored
Merge pull request #6598 from s1ck/idx-inx-adapt-csr-graphstore
[IdxInc] Adapt CSRGraphStore to store indexed relationships
2 parents 6422127 + 98b87e9 commit f3e8b29

File tree

14 files changed

+380
-341
lines changed

14 files changed

+380
-341
lines changed

core/src/main/java/org/neo4j/gds/api/CSRGraphStoreFactory.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ protected CSRGraphStore createGraphStore(
5252
.schema(computeGraphSchema(nodeImportResult, relationshipImportResult))
5353
.nodes(nodeImportResult.idMap())
5454
.nodePropertyStore(nodeImportResult.properties())
55-
.relationships(relationshipImportResult.relationships())
56-
.relationshipPropertyStores(relationshipImportResult.properties())
55+
.relationshipImportResult(relationshipImportResult)
5756
.concurrency(graphProjectConfig.readConcurrency())
5857
.build();
5958
}

core/src/main/java/org/neo4j/gds/api/RelationshipPropertyStore.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ public interface RelationshipPropertyStore {
3131

3232
Map<String, RelationshipProperty> relationshipProperties();
3333

34-
default RelationshipProperty get(String propertyKey) {
35-
return relationshipProperties().get(propertyKey);
36-
}
37-
3834
default boolean isEmpty() {
3935
return relationshipProperties().isEmpty();
4036
}
4137

38+
default RelationshipProperty get(String propertyKey) {
39+
return relationshipProperties().get(propertyKey);
40+
}
41+
4242
default Set<String> keySet() {
4343
return relationshipProperties().keySet();
4444
}
@@ -51,10 +51,6 @@ default boolean containsKey(String propertyKey) {
5151
return relationshipProperties().containsKey(propertyKey);
5252
}
5353

54-
static RelationshipPropertyStore empty() {
55-
return ImmutableRelationshipPropertyStore.of(Collections.emptyMap());
56-
}
57-
5854
static Builder builder() {
5955
// need to initialize with empty map due to `deferCollectionAllocation = true`
6056
return new Builder().relationshipProperties(Collections.emptyMap());

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

Lines changed: 107 additions & 117 deletions
Large diffs are not rendered by default.

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

Lines changed: 75 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,11 @@
4545
import org.neo4j.values.storable.NumberType;
4646

4747
import java.util.Collection;
48-
import java.util.Collections;
4948
import java.util.List;
5049
import java.util.Map;
5150
import java.util.Optional;
5251
import java.util.function.Function;
5352

54-
import static java.util.Collections.singletonMap;
5553
import static org.neo4j.gds.utils.StringFormatting.formatWithLocale;
5654

5755
public final class CSRGraphStoreUtil {
@@ -64,7 +62,6 @@ public static CSRGraphStore createFromGraph(
6462
int concurrency
6563
) {
6664
var relationshipType = RelationshipType.of(relationshipTypeString);
67-
var relationships = graph.relationships();
6865
Direction direction = graph.schema().isUndirected() ? Direction.UNDIRECTED : Direction.DIRECTED;
6966

7067
var relationshipSchema = RelationshipSchema.empty();
@@ -86,29 +83,38 @@ public static CSRGraphStore createFromGraph(
8683
);
8784
});
8885

89-
var topology = Map.of(relationshipType, relationships.topology());
9086
var nodeProperties = constructNodePropertiesFromGraph(graph);
87+
88+
var relationships = graph.relationships();
9189
var relationshipProperties = constructRelationshipPropertiesFromGraph(
9290
graph,
9391
relationshipPropertyKey,
9492
relationships,
9593
relationshipType
9694
);
9795

96+
var relationshipImportResult = RelationshipImportResult.builder().putImportResult(
97+
relationshipType,
98+
SingleTypeRelationshipImportResult.builder()
99+
.topology(relationships.topology())
100+
.properties(relationshipProperties)
101+
.direction(direction)
102+
.build()
103+
).build();
104+
98105
var schema = GraphSchema.of(NodeSchema.from(graph.schema().nodeSchema()), relationshipSchema, Map.of());
99106

100-
return new CSRGraphStore(
101-
databaseId,
107+
return new GraphStoreBuilder()
108+
.databaseId(databaseId)
102109
// TODO: is it correct that we only use this for generated graphs?
103-
ImmutableStaticCapabilities.of(false),
104-
schema,
105-
graph.idMap(),
106-
nodeProperties,
107-
topology,
108-
relationshipProperties,
109-
GraphPropertyStore.empty(),
110-
concurrency
111-
);
110+
.capabilities(ImmutableStaticCapabilities.of(false))
111+
.schema(schema)
112+
.nodes(graph.idMap())
113+
.nodePropertyStore(nodeProperties)
114+
.relationshipImportResult(relationshipImportResult)
115+
.graphProperties(GraphPropertyStore.empty())
116+
.concurrency(concurrency)
117+
.build();
112118
}
113119

114120
@NotNull
@@ -133,52 +139,51 @@ private static NodePropertyStore constructNodePropertiesFromGraph(HugeGraph grap
133139
}
134140

135141
@NotNull
136-
private static Map<RelationshipType, RelationshipPropertyStore> constructRelationshipPropertiesFromGraph(
142+
private static Optional<RelationshipPropertyStore> constructRelationshipPropertiesFromGraph(
137143
Graph graph,
138144
Optional<String> relationshipProperty,
139145
Relationships relationships,
140146
RelationshipType relationshipType
141147
) {
142-
Map<RelationshipType, RelationshipPropertyStore> relationshipProperties = Collections.emptyMap();
143-
if (relationshipProperty.isPresent() && relationships.properties().isPresent()) {
144-
Map<String, RelationshipPropertySchema> relationshipPropertySchemas = graph
145-
.schema()
146-
.relationshipSchema()
147-
.get(relationshipType)
148-
.properties();
149-
150-
if (relationshipPropertySchemas.size() != 1) {
151-
throw new IllegalStateException(formatWithLocale(
152-
"Relationship schema is expected to have exactly one property but had %s",
153-
relationshipPropertySchemas.size()
154-
));
155-
}
156-
157-
RelationshipPropertySchema relationshipPropertySchema = relationshipPropertySchemas
158-
.values()
159-
.stream()
160-
.findFirst()
161-
.orElseThrow();
148+
if (relationshipProperty.isEmpty() || relationships.properties().isEmpty()) {
149+
return Optional.empty();
150+
}
162151

163-
String propertyKey = relationshipProperty.get();
164-
relationshipProperties = singletonMap(
165-
relationshipType,
166-
RelationshipPropertyStore.builder().putIfAbsent(
167-
propertyKey,
168-
RelationshipProperty.of(
169-
propertyKey,
170-
NumberType.FLOATING_POINT,
171-
relationshipPropertySchema.state(),
172-
relationships.properties().orElseThrow(),
173-
relationshipPropertySchema.defaultValue().isUserDefined()
174-
? relationshipPropertySchema.defaultValue()
175-
: ValueTypes.fromNumberType(NumberType.FLOATING_POINT).fallbackValue(),
176-
relationshipPropertySchema.aggregation()
177-
)
178-
).build()
179-
);
152+
Map<String, RelationshipPropertySchema> relationshipPropertySchemas = graph
153+
.schema()
154+
.relationshipSchema()
155+
.get(relationshipType)
156+
.properties();
157+
158+
if (relationshipPropertySchemas.size() != 1) {
159+
throw new IllegalStateException(formatWithLocale(
160+
"Relationship schema is expected to have exactly one property but had %s",
161+
relationshipPropertySchemas.size()
162+
));
180163
}
181-
return relationshipProperties;
164+
165+
RelationshipPropertySchema relationshipPropertySchema = relationshipPropertySchemas
166+
.values()
167+
.stream()
168+
.findFirst()
169+
.orElseThrow();
170+
171+
String propertyKey = relationshipProperty.get();
172+
173+
return Optional.of(RelationshipPropertyStore.builder().putIfAbsent(
174+
propertyKey,
175+
RelationshipProperty.of(
176+
propertyKey,
177+
NumberType.FLOATING_POINT,
178+
relationshipPropertySchema.state(),
179+
relationships.properties().orElseThrow(),
180+
relationshipPropertySchema.defaultValue().isUserDefined()
181+
? relationshipPropertySchema.defaultValue()
182+
: ValueTypes.fromNumberType(NumberType.FLOATING_POINT).fallbackValue(),
183+
relationshipPropertySchema.aggregation()
184+
)
185+
).build());
186+
182187
}
183188

184189
public static void extractNodeProperties(
@@ -235,46 +240,36 @@ public static GraphSchema computeGraphSchema(
235240
Function<NodeLabel, Collection<String>> propertiesByLabel,
236241
RelationshipImportResult relationshipImportResult
237242
) {
238-
var properties = nodeImportResult.properties().properties();
243+
var nodeProperties = nodeImportResult.properties().properties();
239244

240245
var nodeSchema = NodeSchema.empty();
241246
for (var label : nodeImportResult.idMap().availableNodeLabels()) {
242247
var entry = nodeSchema.getOrCreateLabel(label);
243248
for (var propertyKey : propertiesByLabel.apply(label)) {
244249
entry.addProperty(
245250
propertyKey,
246-
properties.get(propertyKey).propertySchema()
251+
nodeProperties.get(propertyKey).propertySchema()
247252
);
248253
}
249254
}
250255
nodeImportResult.idMap().availableNodeLabels().forEach(nodeSchema::getOrCreateLabel);
251256

252257
var relationshipSchema = RelationshipSchema.empty();
253-
relationshipImportResult
254-
.properties()
255-
.forEach((relType, propertyStore) -> {
256-
var entry = relationshipSchema.getOrCreateRelationshipType(
257-
relType,
258-
relationshipImportResult.directions().get(relType)
259-
);
260258

261-
propertyStore
262-
.relationshipProperties()
263-
.forEach((propertyKey, propertyValues) -> entry.addProperty(
264-
propertyKey,
265-
propertyValues.propertySchema()
266-
));
267-
});
268-
269-
relationshipImportResult
270-
.relationships()
271-
.keySet()
272-
.forEach(type -> {
273-
relationshipSchema.getOrCreateRelationshipType(
274-
type,
275-
relationshipImportResult.directions().get(type)
276-
);
277-
});
259+
relationshipImportResult.importResults().forEach(((relationshipType, singleTypeRelationshipImportResult) -> {
260+
relationshipSchema.getOrCreateRelationshipType(
261+
relationshipType,
262+
singleTypeRelationshipImportResult.direction()
263+
);
264+
singleTypeRelationshipImportResult.properties()
265+
.map(RelationshipPropertyStore::relationshipProperties)
266+
.ifPresent(properties -> properties.forEach((propertyKey, propertyValues) -> relationshipSchema
267+
.getOrCreateRelationshipType(
268+
relationshipType,
269+
singleTypeRelationshipImportResult.direction()
270+
)
271+
.addProperty(propertyKey, propertyValues.propertySchema())));
272+
}));
278273

279274
return GraphSchema.of(
280275
nodeSchema,

0 commit comments

Comments
 (0)