Skip to content

Commit 1e49437

Browse files
Merge pull request #11161 from neo-technology/max-flow-write-facade
Max-flow stats, mutate and write facade
2 parents 1585ef0 + aca5aa8 commit 1e49437

File tree

46 files changed

+2070
-21
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+2070
-21
lines changed

applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsEstimationModeBusinessFacade.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@
1919
*/
2020
package org.neo4j.gds.applications.algorithms.pathfinding;
2121

22+
import org.neo4j.gds.allshortestpaths.AllShortestPathsConfig;
23+
import org.neo4j.gds.allshortestpaths.AllShortestPathsMemoryEstimateDefinition;
2224
import org.neo4j.gds.applications.algorithms.machinery.AlgorithmEstimationTemplate;
2325
import org.neo4j.gds.applications.algorithms.machinery.MemoryEstimateResult;
2426
import org.neo4j.gds.config.AlgoBaseConfig;
2527
import org.neo4j.gds.exceptions.MemoryEstimationNotImplementedException;
28+
import org.neo4j.gds.maxflow.MaxFlowBaseConfig;
2629
import org.neo4j.gds.mem.MemoryEstimation;
2730
import org.neo4j.gds.paths.astar.AStarMemoryEstimateDefinition;
2831
import org.neo4j.gds.paths.astar.config.ShortestPathAStarBaseConfig;
@@ -49,8 +52,6 @@
4952
import org.neo4j.gds.traversal.RandomWalkCountingVisitsMemoryEstimateDefinition;
5053
import org.neo4j.gds.traversal.RandomWalkMemoryEstimateDefinition;
5154
import org.neo4j.gds.traversal.RandomWalkMutateConfig;
52-
import org.neo4j.gds.allshortestpaths.AllShortestPathsMemoryEstimateDefinition;
53-
import org.neo4j.gds.allshortestpaths.AllShortestPathsConfig;
5455

5556
/**
5657
* Here is the top level business facade for all your path finding memory estimation needs.
@@ -130,10 +131,17 @@ MemoryEstimation longestPath() {
130131
throw new MemoryEstimationNotImplementedException();
131132
}
132133

133-
MemoryEstimation maxFlow() {
134+
public MemoryEstimation maxFlow() {
134135
throw new MemoryEstimationNotImplementedException();
135136
}
136137

138+
MemoryEstimation maxFlow(
139+
MaxFlowBaseConfig configuration,
140+
Object graphNameOrConfiguration
141+
) {
142+
return maxFlow();
143+
}
144+
137145
public MemoryEstimateResult pcst(
138146
PCSTBaseConfig configuration,
139147
Object graphNameOrConfiguration

applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsMutateModeBusinessFacade.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@
3232
import org.neo4j.gds.applications.algorithms.metadata.RelationshipsWritten;
3333
import org.neo4j.gds.collections.ha.HugeLongArray;
3434
import org.neo4j.gds.collections.haa.HugeAtomicLongArray;
35+
import org.neo4j.gds.maxflow.FlowResult;
36+
import org.neo4j.gds.maxflow.MaxFlowMutateConfig;
3537
import org.neo4j.gds.pathfinding.BellmanFordMutateStep;
38+
import org.neo4j.gds.pathfinding.MaxFlowMutateStep;
3639
import org.neo4j.gds.pathfinding.PrizeCollectingSteinerTreeMutateStep;
3740
import org.neo4j.gds.pathfinding.RandomWalkCountingNodeVisitsMutateStep;
3841
import org.neo4j.gds.pathfinding.SearchMutateStep;
@@ -67,6 +70,7 @@
6770
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.DFS;
6871
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.DeltaStepping;
6972
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.Dijkstra;
73+
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.MaxFlow;
7074
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.RandomWalk;
7175
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.SingleSourceDijkstra;
7276
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.SteinerTree;
@@ -182,6 +186,28 @@ public <RESULT> RESULT depthFirstSearch(
182186
);
183187
}
184188

189+
public <RESULT> RESULT maxFlow(
190+
GraphName graphName,
191+
MaxFlowMutateConfig configuration,
192+
ResultBuilder<MaxFlowMutateConfig, FlowResult, RESULT, RelationshipsWritten> resultBuilder
193+
) {
194+
var mutateStep = new MaxFlowMutateStep(
195+
configuration.mutateRelationshipType(),
196+
configuration.mutateProperty(),
197+
mutateRelationshipService
198+
);
199+
200+
return algorithmProcessingTemplateConvenience.processRegularAlgorithmInMutateMode(
201+
graphName,
202+
configuration,
203+
MaxFlow,
204+
estimationFacade::maxFlow,
205+
(graph, __) -> pathFindingAlgorithms.maxFlow(graph, configuration),
206+
mutateStep,
207+
resultBuilder
208+
);
209+
}
210+
185211
public <RESULT> RESULT pcst(
186212
GraphName graphName,
187213
PCSTMutateConfig configuration,

applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsStatsModeBusinessFacade.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import org.neo4j.gds.applications.algorithms.machinery.AlgorithmProcessingTemplateConvenience;
2525
import org.neo4j.gds.applications.algorithms.machinery.StatsResultBuilder;
2626
import org.neo4j.gds.collections.ha.HugeLongArray;
27+
import org.neo4j.gds.maxflow.FlowResult;
28+
import org.neo4j.gds.maxflow.MaxFlowStatsConfig;
2729
import org.neo4j.gds.paths.bellmanford.AllShortestPathsBellmanFordStatsConfig;
2830
import org.neo4j.gds.paths.bellmanford.BellmanFordResult;
2931
import org.neo4j.gds.paths.delta.config.AllShortestPathsDeltaStatsConfig;
@@ -42,6 +44,7 @@
4244
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.BFS;
4345
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.BellmanFord;
4446
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.DeltaStepping;
47+
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.MaxFlow;
4548
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.PCST;
4649
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.RandomWalk;
4750
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.SteinerTree;
@@ -107,6 +110,21 @@ public <RESULT> RESULT deltaStepping(
107110
);
108111
}
109112

113+
public <RESULT> RESULT maxFlow(
114+
GraphName graphName,
115+
MaxFlowStatsConfig configuration,
116+
StatsResultBuilder<FlowResult, RESULT> resultBuilder
117+
) {
118+
return algorithmProcessingTemplateConvenience.processRegularAlgorithmInStatsMode(
119+
graphName,
120+
configuration,
121+
MaxFlow,
122+
estimationFacade::maxFlow,
123+
(graph, __) -> pathFindingAlgorithms.maxFlow(graph, configuration),
124+
resultBuilder
125+
);
126+
}
127+
110128
public <RESULT> RESULT pcst(
111129
GraphName graphName,
112130
PCSTStatsConfig configuration,

applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsWriteModeBusinessFacade.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,12 @@
3535
import org.neo4j.gds.config.WriteRelationshipConfig;
3636
import org.neo4j.gds.kspanningtree.KSpanningTreeWriteConfig;
3737
import org.neo4j.gds.logging.Log;
38+
import org.neo4j.gds.maxflow.FlowResult;
39+
import org.neo4j.gds.maxflow.MaxFlowWriteConfig;
3840
import org.neo4j.gds.mem.MemoryEstimation;
3941
import org.neo4j.gds.pathfinding.BellmanFordWriteStep;
4042
import org.neo4j.gds.pathfinding.KSpanningTreeWriteStep;
43+
import org.neo4j.gds.pathfinding.MaxFlowWriteStep;
4144
import org.neo4j.gds.pathfinding.PrizeCollectingSteinerTreeWriteStep;
4245
import org.neo4j.gds.pathfinding.ShortestPathWriteStep;
4346
import org.neo4j.gds.pathfinding.SpanningTreeWriteStep;
@@ -65,6 +68,7 @@
6568
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.DeltaStepping;
6669
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.Dijkstra;
6770
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.KSpanningTree;
71+
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.MaxFlow;
6872
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.PCST;
6973
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.SingleSourceDijkstra;
7074
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.SteinerTree;
@@ -170,6 +174,30 @@ public <RESULT> RESULT kSpanningTree(
170174
);
171175
}
172176

177+
public <RESULT> RESULT maxFlow(
178+
GraphName graphName,
179+
MaxFlowWriteConfig configuration,
180+
ResultBuilder<MaxFlowWriteConfig, FlowResult, RESULT, RelationshipsWritten> resultBuilder
181+
) {
182+
var writeStep = new MaxFlowWriteStep(
183+
writeRelationshipService,
184+
configuration.writeRelationshipType(),
185+
configuration.writeProperty(),
186+
configuration::resolveResultStore,
187+
configuration.jobId()
188+
);
189+
190+
return runAlgorithmAndWrite(
191+
graphName,
192+
configuration,
193+
MaxFlow,
194+
estimationFacade::maxFlow,
195+
(graph, __) -> pathFindingAlgorithms.maxFlow(graph, configuration),
196+
writeStep,
197+
resultBuilder
198+
);
199+
}
200+
173201
public <RESULT> RESULT pcst(
174202
GraphName graphName,
175203
PCSTWriteConfig configuration,

doc/modules/ROOT/pages/operations-reference/algorithm-references.adoc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,11 @@
227227
| `gds.louvain.stream.estimate` label:procedure[Procedure]
228228
| `gds.louvain.stats` label:procedure[Procedure]
229229
| `gds.louvain.stats.estimate` label:procedure[Procedure]
230-
.1+<.^|Max flow
230+
.4+<.^|Max flow
231+
| `gds.maxFlow.mutate` label:procedure[Procedure]
232+
| `gds.maxFlow.stats` label:procedure[Procedure]
231233
| `gds.maxFlow.stream` label:procedure[Procedure]
234+
| `gds.maxFlow.write` label:procedure[Procedure]
232235
.4+<.^|xref:algorithms/approx-max-k-cut.adoc[Approximate Maximum k-cut]
233236
| `gds.maxkcut.mutate` label:procedure[Procedure]
234237
| `gds.maxkcut.mutate.estimate` label:procedure[Procedure]

open-packaging/src/test/java/org/neo4j/gds/OpenGdsProcedureSmokeTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,10 @@ class OpenGdsProcedureSmokeTest extends BaseProcTest {
469469
"gds.louvain.write",
470470
"gds.louvain.write.estimate",
471471

472+
"gds.maxFlow.mutate",
473+
"gds.maxFlow.stats",
472474
"gds.maxFlow.stream",
475+
"gds.maxFlow.write",
473476

474477
"gds.nodeSimilarity.mutate",
475478
"gds.nodeSimilarity.mutate.estimate",
@@ -631,7 +634,7 @@ void countShouldMatch() {
631634
);
632635

633636
// If you find yourself updating this count, please also update the count in SmokeTest.kt
634-
int expectedCount = 469;
637+
int expectedCount = 472;
635638
assertEquals(
636639
expectedCount,
637640
returnedRows,

pipeline/src/main/java/org/neo4j/gds/ml/pipeline/MutateModeAlgorithmLibrary.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ static CanonicalProcedureName algorithmToName(Algorithm algorithm) {
9898
case Leiden -> CanonicalProcedureName.parse("gds.leiden");
9999
case Louvain -> CanonicalProcedureName.parse("gds.louvain");
100100
case LongestPath -> null;
101-
case MaxFlow -> null;
101+
case MaxFlow -> CanonicalProcedureName.parse("gds.maxflow");
102102
case Modularity -> null;
103103
case ModularityOptimization -> CanonicalProcedureName.parse("gds.modularityOptimization");
104104
case NodeSimilarity -> CanonicalProcedureName.parse("gds.nodeSimilarity");

pipeline/src/main/java/org/neo4j/gds/ml/pipeline/StubbyHolder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import org.neo4j.gds.ml.pipeline.stubs.LccStub;
5252
import org.neo4j.gds.ml.pipeline.stubs.LeidenStub;
5353
import org.neo4j.gds.ml.pipeline.stubs.LouvainStub;
54+
import org.neo4j.gds.ml.pipeline.stubs.MaxFlowStub;
5455
import org.neo4j.gds.ml.pipeline.stubs.ModularityOptimizationStub;
5556
import org.neo4j.gds.ml.pipeline.stubs.Node2VecStub;
5657
import org.neo4j.gds.ml.pipeline.stubs.NodeSimilarityStub;
@@ -124,7 +125,7 @@ Stub get(Algorithm algorithm) {
124125
case Leiden -> new LeidenStub();
125126
case Louvain -> new LouvainStub();
126127
case LongestPath -> null;
127-
case MaxFlow -> null;
128+
case MaxFlow -> new MaxFlowStub();
128129
case Modularity -> null;
129130
case ModularityOptimization -> new ModularityOptimizationStub();
130131
case NodeSimilarity -> new NodeSimilarityStub();
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Neo4j is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
package org.neo4j.gds.ml.pipeline.stubs;
21+
22+
import org.neo4j.gds.maxflow.MaxFlowMutateConfig;
23+
import org.neo4j.gds.procedures.algorithms.AlgorithmsProcedureFacade;
24+
import org.neo4j.gds.procedures.algorithms.pathfinding.MaxFlowMutateResult;
25+
import org.neo4j.gds.procedures.algorithms.stubs.MutateStub;
26+
27+
public class MaxFlowStub extends AbstractStub<MaxFlowMutateConfig, MaxFlowMutateResult> {
28+
protected MutateStub<MaxFlowMutateConfig, MaxFlowMutateResult> stub(AlgorithmsProcedureFacade facade) {
29+
return facade.pathFinding().stubs().maxFlow();
30+
}
31+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Neo4j is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
package org.neo4j.gds.paths.maxflow;
21+
22+
import org.neo4j.gds.procedures.GraphDataScienceProcedures;
23+
import org.neo4j.gds.procedures.algorithms.pathfinding.MaxFlowMutateResult;
24+
import org.neo4j.procedure.Context;
25+
import org.neo4j.procedure.Description;
26+
import org.neo4j.procedure.Name;
27+
import org.neo4j.procedure.Procedure;
28+
29+
import java.util.Map;
30+
import java.util.stream.Stream;
31+
32+
import static org.neo4j.gds.paths.maxflow.MaxFlowConstants.MAXFLOW_DESCRIPTION;
33+
import static org.neo4j.procedure.Mode.READ;
34+
35+
public class MaxFlowMutateProc {
36+
@Context
37+
public GraphDataScienceProcedures facade;
38+
39+
@Procedure(value = "gds.maxFlow.mutate", mode = READ)
40+
@Description(MAXFLOW_DESCRIPTION)
41+
public Stream<MaxFlowMutateResult> maxFlow(
42+
@Name(value = "graphName") String graphName,
43+
@Name(value = "configuration", defaultValue = "{}") Map<String, Object> configuration
44+
) {
45+
return facade.algorithms().pathFinding().maxFlowMutate(graphName, configuration);
46+
}
47+
}

0 commit comments

Comments
 (0)