Skip to content

Commit dece84a

Browse files
DarthMaxyuvalr1neo
authored andcommitted
Add Memory Estimation for ToUndirected
1 parent a32307e commit dece84a

File tree

4 files changed

+69
-0
lines changed

4 files changed

+69
-0
lines changed

algo/src/main/java/org/neo4j/gds/beta/undirected/ToUndirectedFactory.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,14 @@
2020
package org.neo4j.gds.beta.undirected;
2121

2222
import org.neo4j.gds.GraphStoreAlgorithmFactory;
23+
import org.neo4j.gds.RelationshipType;
2324
import org.neo4j.gds.api.GraphStore;
2425
import org.neo4j.gds.core.concurrency.Pools;
26+
import org.neo4j.gds.core.huge.CompressedAdjacencyList;
27+
import org.neo4j.gds.core.huge.UncompressedAdjacencyList;
28+
import org.neo4j.gds.core.utils.mem.MemoryEstimation;
29+
import org.neo4j.gds.core.utils.mem.MemoryEstimations;
30+
import org.neo4j.gds.core.utils.mem.MemoryRange;
2531
import org.neo4j.gds.core.utils.progress.tasks.ProgressTracker;
2632
import org.neo4j.gds.core.utils.progress.tasks.Task;
2733
import org.neo4j.gds.core.utils.progress.tasks.Tasks;
@@ -50,4 +56,24 @@ public Task progressTask(GraphStore graphStore, ToUndirectedConfig config) {
5056
Tasks.leaf("Build undirected Adjacency list")
5157
);
5258
}
59+
60+
@Override
61+
public MemoryEstimation memoryEstimation(ToUndirectedConfig configuration) {
62+
RelationshipType relationshipType = RelationshipType.of(configuration.relationshipType());
63+
64+
var builder = MemoryEstimations.builder(ToUndirected.class)
65+
.add("relationships", CompressedAdjacencyList.adjacencyListEstimation(relationshipType, true));
66+
67+
builder.perGraphDimension("properties", ((graphDimensions, integer) -> {
68+
long max = graphDimensions.relationshipPropertyTokens().keySet().stream().mapToLong(__ ->
69+
UncompressedAdjacencyList
70+
.adjacencyPropertiesEstimation(relationshipType, true)
71+
.estimate(graphDimensions, integer)
72+
.memoryUsage().max
73+
).sum();
74+
return MemoryRange.of(0, max);
75+
}));
76+
77+
return builder.build();
78+
}
5379
}

executor/src/main/java/org/neo4j/gds/executor/GraphStoreFromCatalogLoader.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.neo4j.gds.core.loading.GraphStoreWithConfig;
3333
import org.neo4j.gds.core.loading.ImmutableCatalogRequest;
3434

35+
import java.util.HashMap;
3536
import java.util.Map;
3637
import java.util.Optional;
3738
import java.util.Set;
@@ -78,10 +79,17 @@ public GraphDimensions graphDimensions() {
7879
);
7980
long relCount = filteredGraph.relationshipCount();
8081

82+
var relationshipTypeTokens = new HashMap<String, Integer>();
83+
var i = 0;
84+
for (String key : graphStore.relationshipPropertyKeys()) {
85+
relationshipTypeTokens.put(key, i++);
86+
}
87+
8188
return ImmutableGraphDimensions.builder()
8289
.nodeCount(filteredGraph.nodeCount())
8390
.relationshipCounts(filteredGraphRelationshipCounts(config, graphStore, filteredGraph))
8491
.relCountUpperBound(relCount)
92+
.relationshipPropertyTokens(relationshipTypeTokens)
8593
.build();
8694
}
8795

proc/beta/src/main/java/org/neo4j/gds/beta/undirected/ToUndirectedProc.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121

2222
import org.neo4j.gds.BaseProc;
2323
import org.neo4j.gds.core.loading.SingleTypeRelationshipImportResult;
24+
import org.neo4j.gds.executor.MemoryEstimationExecutor;
2425
import org.neo4j.gds.executor.ProcedureExecutor;
2526
import org.neo4j.gds.executor.ProcedureExecutorSpec;
27+
import org.neo4j.gds.results.MemoryEstimateResult;
2628
import org.neo4j.procedure.Description;
2729
import org.neo4j.procedure.Name;
2830
import org.neo4j.procedure.Procedure;
@@ -49,4 +51,20 @@ public Stream<ToUndirectedSpec.MutateResult> mutate(
4951
executionContext()
5052
).compute(graphName, configuration, true, true);
5153
}
54+
55+
@Procedure(value = "gds.beta.graph.relationships.toUndirected.estimate", mode = READ)
56+
@Description(ESTIMATE_DESCRIPTION)
57+
public Stream<MemoryEstimateResult> estimate(
58+
@Name(value = "graphNameOrConfiguration") Object graphNameOrConfiguration,
59+
@Name(value = "algoConfiguration") Map<String, Object> algoConfiguration
60+
) {
61+
var mutateSpec = new ToUndirectedSpec();
62+
var pipelineSpec = new ProcedureExecutorSpec<ToUndirected, SingleTypeRelationshipImportResult, ToUndirectedConfig>();
63+
64+
return new MemoryEstimationExecutor<>(
65+
mutateSpec,
66+
pipelineSpec,
67+
executionContext()
68+
).computeEstimate(graphNameOrConfiguration, algoConfiguration);
69+
}
5270
}

proc/beta/src/test/java/org/neo4j/gds/beta/undirected/ToUndirectedProcTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,21 @@ void shouldFailIfRelationshipTypeDoesNotExists() {
112112
);
113113
assertEquals(expectedMessage, throwable.getMessage());
114114
}
115+
116+
@Test
117+
void memoryEstimation() {
118+
String query = "CALL gds.beta.graph.relationships.toUndirected.estimate('graph', {relationshipType: 'REL', mutateRelationshipType: 'REL2'})";
119+
120+
assertCypherResult(query, List.of(Map.of(
121+
"mapView", instanceOf(Map.class),
122+
"treeView", instanceOf(String.class),
123+
"bytesMax", 524632L,
124+
"heapPercentageMin", 0.1D,
125+
"nodeCount", 3L,
126+
"requiredMemory", "[256 KiB ... 512 KiB]",
127+
"bytesMin", 262360L,
128+
"heapPercentageMax", 0.1D,
129+
"relationshipCount", 3L
130+
)));
131+
}
115132
}

0 commit comments

Comments
 (0)