Skip to content

Commit 2bb2e19

Browse files
committed
Ensure RelationshipPropertyStore is never empty on construction
1 parent d1e75ce commit 2bb2e19

File tree

4 files changed

+37
-34
lines changed

4 files changed

+37
-34
lines changed

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020
package org.neo4j.gds.api;
2121

22+
import org.immutables.value.Value;
2223
import org.neo4j.gds.annotation.ValueClass;
2324

2425
import java.util.Collection;
@@ -35,10 +36,6 @@ default RelationshipProperty get(String propertyKey) {
3536
return relationshipProperties().get(propertyKey);
3637
}
3738

38-
default boolean isEmpty() {
39-
return relationshipProperties().isEmpty();
40-
}
41-
4239
default Set<String> keySet() {
4340
return relationshipProperties().keySet();
4441
}
@@ -51,8 +48,11 @@ default boolean containsKey(String propertyKey) {
5148
return relationshipProperties().containsKey(propertyKey);
5249
}
5350

54-
static RelationshipPropertyStore empty() {
55-
return ImmutableRelationshipPropertyStore.of(Collections.emptyMap());
51+
@Value.Check
52+
default void validate() {
53+
if (relationshipProperties().isEmpty()) {
54+
throw new IllegalStateException("Relationship property store must not be empty.");
55+
}
5656
}
5757

5858
static Builder builder() {

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ public RelationshipProperty relationshipPropertyValues(RelationshipType relation
403403
return Optional.ofNullable(relationships.get(relationshipType))
404404
.flatMap(SingleTypeRelationshipImportResult::properties)
405405
.map(propertyStore -> propertyStore.get(propertyKey))
406-
.orElseGet(() -> RelationshipPropertyStore.empty().get(propertyKey));
406+
.orElseThrow(() -> new IllegalArgumentException("No relationship properties found for relationship type `" + relationshipType + "` and property key `" + propertyKey + "`."));
407407
}
408408

409409
@Override
@@ -557,13 +557,12 @@ public CompositeRelationshipIterator getCompositeRelationshipIterator(
557557

558558
var relationship = relationships.get(relationshipType);
559559
var adjacencyList = relationship.topology().adjacencyList();
560-
var relationshipPropertyStore = relationship.properties().orElse(RelationshipPropertyStore.empty());
561560

562561
var properties = propertyKeys.isEmpty()
563562
? CSRCompositeRelationshipIterator.EMPTY_PROPERTIES
564563
: propertyKeys
565564
.stream()
566-
.map(relationshipPropertyStore::get)
565+
.map(propertyKey -> relationshipPropertyValues(relationshipType, propertyKey))
567566
.map(RelationshipProperty::values)
568567
.map(Relationships.Properties::propertiesList)
569568
.toArray(AdjacencyProperties[]::new);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static RelationshipImportResult of(
6262
relationshipType,
6363
SingleTypeRelationshipImportResult.builder()
6464
.topology(topology)
65-
.properties(Optional.ofNullable(properties.get(relationshipType)).filter(p -> !p.isEmpty()))
65+
.properties(Optional.ofNullable(properties.get(relationshipType)))
6666
.direction(directions.get(relationshipType))
6767
.build()
6868
));

test-utils/src/main/java/org/neo4j/gds/gdl/GdlFactory.java

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -235,35 +235,39 @@ public CSRGraphStore build() {
235235
var relationshipImportResultBuilder = RelationshipImportResult.builder();
236236

237237
relationships.forEach(loadResult -> {
238-
var propertyStoreBuilder = loadResult
239-
.properties()
240-
.entrySet()
241-
.stream()
242-
.reduce(RelationshipPropertyStore.builder(), (builder, stringPropertiesEntry) -> {
243-
var propertyKey = stringPropertiesEntry.getKey();
244-
var properties = stringPropertiesEntry.getValue();
238+
var singleTypeRelationshipImportBuilder = SingleTypeRelationshipImportResult.builder()
239+
.direction(Direction.fromOrientation(graphProjectConfig().orientation()))
240+
.topology(loadResult.topology());
241+
242+
if (!loadResult.properties().isEmpty()) {
243+
var propertyStoreBuilder = loadResult
244+
.properties()
245+
.entrySet()
246+
.stream()
247+
.reduce(RelationshipPropertyStore.builder(), (builder, stringPropertiesEntry) -> {
248+
var propertyKey = stringPropertiesEntry.getKey();
249+
var properties = stringPropertiesEntry.getValue();
245250

246-
builder.putIfAbsent(
247-
propertyKey,
248-
RelationshipProperty.of(
251+
builder.putIfAbsent(
249252
propertyKey,
250-
NumberType.FLOATING_POINT,
251-
PropertyState.PERSISTENT,
252-
properties,
253-
DefaultValue.forDouble(),
254-
graphProjectConfig.aggregation()
255-
)
256-
);
257-
return builder;
258-
}, (builder, __) -> builder);
253+
RelationshipProperty.of(
254+
propertyKey,
255+
NumberType.FLOATING_POINT,
256+
PropertyState.PERSISTENT,
257+
properties,
258+
DefaultValue.forDouble(),
259+
graphProjectConfig.aggregation()
260+
)
261+
);
262+
return builder;
263+
}, (builder, __) -> builder);
264+
265+
singleTypeRelationshipImportBuilder.properties(propertyStoreBuilder.build());
266+
}
259267

260268
relationshipImportResultBuilder.putImportResult(
261269
loadResult.relationshipType(),
262-
SingleTypeRelationshipImportResult.builder()
263-
.direction(Direction.fromOrientation(graphProjectConfig().orientation()))
264-
.topology(loadResult.topology())
265-
.properties(propertyStoreBuilder.build())
266-
.build()
270+
singleTypeRelationshipImportBuilder.build()
267271
);
268272
});
269273

0 commit comments

Comments
 (0)