Skip to content

Commit def2bd0

Browse files
Add sllpa to business facade
1 parent 4d4bd0f commit def2bd0

File tree

4 files changed

+126
-33
lines changed

4 files changed

+126
-33
lines changed

algorithms-compute-business-facade/build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,16 @@ dependencies {
1010
implementation project(':algo-common') // TODO: extract the results to a separate module and depend on it
1111
implementation project(':algorithms-compute-facade')
1212
implementation project(':collections')
13+
implementation project(":community-configs") //Need for SLLPA
1314
implementation project(':community-params')
15+
implementation project(":config-api") //Need for SLLPA
16+
1417
implementation project(':core') // TODO: this is here because of the `GraphStoreCatalogService` --> refactor it so we can use the service without bringing the entire sub-project
1518
implementation project(':graph-schema-api')
1619
implementation project(':logging')
1720
implementation project(':node-embeddings-params')
1821
implementation project(':path-finding-params')
22+
implementation project(":pregel") //Need for SLLPA
1923
implementation project(':progress-tracking')
2024
implementation project(':string-formatting')
2125
implementation project(':termination')

algorithms-compute-business-facade/src/main/java/org/neo4j/gds/community/CommunityComputeBusinessFacade.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@
2626
import org.neo4j.gds.api.nodeproperties.ValueType;
2727
import org.neo4j.gds.approxmaxkcut.ApproxMaxKCutParameters;
2828
import org.neo4j.gds.approxmaxkcut.ApproxMaxKCutResult;
29+
import org.neo4j.gds.beta.pregel.PregelResult;
2930
import org.neo4j.gds.cliqueCounting.CliqueCountingResult;
3031
import org.neo4j.gds.cliquecounting.CliqueCountingParameters;
3132
import org.neo4j.gds.collections.ha.HugeLongArray;
3233
import org.neo4j.gds.community.validation.ApproxMaxKCutValidation;
34+
import org.neo4j.gds.community.validation.SpeakerListenerLPAGraphStoreValidation;
3335
import org.neo4j.gds.community.validation.TriangleCountGraphStoreValidation;
3436
import org.neo4j.gds.community.validation.UndirectedAndSeedableGraphStoreValidation;
3537
import org.neo4j.gds.conductance.ConductanceParameters;
@@ -62,6 +64,7 @@
6264
import org.neo4j.gds.result.TimedAlgorithmResult;
6365
import org.neo4j.gds.results.ResultTransformerBuilder;
6466
import org.neo4j.gds.scc.SccParameters;
67+
import org.neo4j.gds.sllpa.SpeakerListenerLPAConfig;
6568
import org.neo4j.gds.triangle.LocalClusteringCoefficientParameters;
6669
import org.neo4j.gds.triangle.LocalClusteringCoefficientResult;
6770
import org.neo4j.gds.triangle.TriangleCountParameters;
@@ -513,6 +516,35 @@ public <TR> CompletableFuture<TR> scc(
513516
).thenApply(resultTransformerBuilder.build(graphResources));
514517
}
515518

519+
public <TR> CompletableFuture<TR> sllpa(
520+
GraphName graphName,
521+
GraphParameters graphParameters,
522+
Optional<String> relationshipProperty,
523+
SpeakerListenerLPAConfig config,
524+
JobId jobId,
525+
boolean logProgress,
526+
ResultTransformerBuilder<TimedAlgorithmResult<PregelResult>, TR> resultTransformerBuilder
527+
) {
528+
// Fetch the Graph the algorithm will operate on
529+
var graphResources = graphStoreCatalogService.fetchGraphResources(
530+
graphName,
531+
graphParameters,
532+
relationshipProperty,
533+
new SpeakerListenerLPAGraphStoreValidation(config.writeProperty()),
534+
Optional.empty(),
535+
user,
536+
databaseId
537+
);
538+
var graph = graphResources.graph();
539+
540+
return computeFacade.sllpa(
541+
graph,
542+
config,
543+
jobId,
544+
logProgress
545+
).thenApply(resultTransformerBuilder.build(graphResources));
546+
}
547+
516548
public <TR> CompletableFuture<TR> triangleCount(
517549
GraphName graphName,
518550
GraphParameters graphParameters,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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.community.validation;
21+
22+
import org.neo4j.gds.NodeLabel;
23+
import org.neo4j.gds.RelationshipType;
24+
import org.neo4j.gds.api.GraphStore;
25+
import org.neo4j.gds.core.loading.validation.GraphStoreValidation;
26+
27+
import java.util.Collection;
28+
29+
public class SpeakerListenerLPAGraphStoreValidation extends GraphStoreValidation {
30+
31+
private final String writeProperty;
32+
33+
public SpeakerListenerLPAGraphStoreValidation(String writeProperty) {
34+
this.writeProperty = writeProperty;
35+
}
36+
37+
@Override
38+
protected void validateAlgorithmRequirements(
39+
GraphStore graphStore,
40+
Collection<NodeLabel> selectedLabels,
41+
Collection<RelationshipType> selectedRelationshipTypes
42+
) {
43+
validateCanWrite(graphStore);
44+
}
45+
46+
private void validateCanWrite(GraphStore graphStore){
47+
// See PregelProcedureConfig for exaplanation of this
48+
if (writeProperty.isBlank()) {
49+
return;
50+
}
51+
52+
if (!graphStore.capabilities().canWriteToLocalDatabase() && !graphStore.capabilities()
53+
.canWriteToRemoteDatabase()) { //skip result store ¯\\_(ツ)_/¯
54+
throw new IllegalArgumentException("The provided graph does not support `write` execution mode.");
55+
}
56+
}
57+
}

algorithms-compute-facade/src/main/java/org/neo4j/gds/community/CommunityComputeFacade.java

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,39 @@ CompletableFuture<TimedAlgorithmResult<HugeLongArray>> scc(
565565
);
566566
}
567567

568+
CompletableFuture<TimedAlgorithmResult<PregelResult>> sllpa(
569+
Graph graph,
570+
SpeakerListenerLPAConfig configuration,
571+
JobId jobId,
572+
boolean logProgress
573+
) {
574+
575+
if (graph.isEmpty()) {
576+
var empty = NodeValue.of(new PregelSchema.Builder().build(),0,new Concurrency(1));
577+
return CompletableFuture.completedFuture(TimedAlgorithmResult.empty(ImmutablePregelResult.of(empty, 0, false)));
578+
}
579+
580+
var progressTracker = progressTrackerFactory.create(
581+
tasks.speakerListenerLPA(graph,configuration),
582+
jobId,
583+
configuration.concurrency(),
584+
logProgress
585+
);
586+
587+
var algorithm = new SpeakerListenerLPA(
588+
graph,
589+
configuration,
590+
DefaultPool.INSTANCE,
591+
progressTracker,
592+
Optional.empty()
593+
);
594+
595+
return algorithmCaller.run(
596+
algorithm::compute,
597+
jobId
598+
);
599+
}
600+
568601
CompletableFuture<TimedAlgorithmResult<TriangleCountResult>> triangleCount(
569602
Graph graph,
570603
TriangleCountParameters parameters,
@@ -655,37 +688,4 @@ CompletableFuture<TimedAlgorithmResult<DisjointSetStruct>> wcc(
655688
);
656689
}
657690

658-
CompletableFuture<TimedAlgorithmResult<PregelResult>> sllpa(
659-
Graph graph,
660-
SpeakerListenerLPAConfig configuration,
661-
JobId jobId,
662-
boolean logProgress
663-
) {
664-
665-
if (graph.isEmpty()) {
666-
var empty = NodeValue.of(new PregelSchema.Builder().build(),0,new Concurrency(1));
667-
return CompletableFuture.completedFuture(TimedAlgorithmResult.empty(ImmutablePregelResult.of(empty, 0, false)));
668-
}
669-
670-
var progressTracker = progressTrackerFactory.create(
671-
tasks.speakerListenerLPA(graph,configuration),
672-
jobId,
673-
configuration.concurrency(),
674-
logProgress
675-
);
676-
677-
var algorithm = new SpeakerListenerLPA(
678-
graph,
679-
configuration,
680-
DefaultPool.INSTANCE,
681-
progressTracker,
682-
Optional.empty()
683-
);
684-
685-
return algorithmCaller.run(
686-
algorithm::compute,
687-
jobId
688-
);
689-
}
690-
691691
}

0 commit comments

Comments
 (0)