Skip to content

Commit 7e246ba

Browse files
Hits mutate procedure facade
1 parent 65ed672 commit 7e246ba

File tree

18 files changed

+584
-8
lines changed

18 files changed

+584
-8
lines changed

applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsMutateModeBusinessFacade.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.neo4j.gds.applications.algorithms.machinery.ResultBuilder;
2727
import org.neo4j.gds.applications.algorithms.metadata.NodePropertiesWritten;
2828
import org.neo4j.gds.articulationpoints.ArticulationPointsMutateConfig;
29+
import org.neo4j.gds.beta.pregel.PregelResult;
2930
import org.neo4j.gds.betweenness.BetweennessCentralityMutateConfig;
3031
import org.neo4j.gds.betweenness.BetwennessCentralityResult;
3132
import org.neo4j.gds.closeness.ClosenessCentralityMutateConfig;
@@ -34,6 +35,7 @@
3435
import org.neo4j.gds.degree.DegreeCentralityResult;
3536
import org.neo4j.gds.harmonic.HarmonicCentralityMutateConfig;
3637
import org.neo4j.gds.harmonic.HarmonicResult;
38+
import org.neo4j.gds.hits.HitsConfig;
3739
import org.neo4j.gds.indirectExposure.IndirectExposureMutateConfig;
3840
import org.neo4j.gds.indirectExposure.IndirectExposureResult;
3941
import org.neo4j.gds.influenceMaximization.CELFResult;
@@ -43,13 +45,17 @@
4345
import org.neo4j.gds.pagerank.PageRankMutateConfig;
4446
import org.neo4j.gds.pagerank.PageRankResult;
4547

48+
import java.util.List;
49+
import java.util.Optional;
50+
4651
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.ArticleRank;
4752
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.ArticulationPoints;
4853
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.BetweennessCentrality;
4954
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.CELF;
5055
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.ClosenessCentrality;
5156
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.DegreeCentrality;
5257
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.EigenVector;
58+
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.HITS;
5359
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.HarmonicCentrality;
5460
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.IndirectExposure;
5561
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.PageRank;
@@ -59,17 +65,21 @@ public class CentralityAlgorithmsMutateModeBusinessFacade {
5965
private final CentralityAlgorithms algorithms;
6066
private final AlgorithmProcessingTemplateConvenience algorithmProcessingTemplateConvenience;
6167
private final MutateNodeProperty mutateNodeProperty;
68+
private final HitsHookGenerator hitsHookGenerator;
69+
6270

6371
public CentralityAlgorithmsMutateModeBusinessFacade(
6472
CentralityAlgorithmsEstimationModeBusinessFacade estimation,
6573
CentralityAlgorithms algorithms,
6674
AlgorithmProcessingTemplateConvenience algorithmProcessingTemplateConvenience,
67-
MutateNodeProperty mutateNodeProperty
75+
MutateNodeProperty mutateNodeProperty,
76+
HitsHookGenerator hitsHookGenerator
6877
) {
6978
this.estimation = estimation;
7079
this.algorithms = algorithms;
7180
this.algorithmProcessingTemplateConvenience = algorithmProcessingTemplateConvenience;
7281
this.mutateNodeProperty = mutateNodeProperty;
82+
this.hitsHookGenerator = hitsHookGenerator;
7383
}
7484

7585
public <RESULT> RESULT articleRank(
@@ -253,5 +263,26 @@ public <RESULT> RESULT indirectExposure(
253263
);
254264
}
255265

266+
public <RESULT> RESULT hits(
267+
GraphName graphName,
268+
HitsConfig configuration,
269+
ResultBuilder<HitsConfig, PregelResult, RESULT, NodePropertiesWritten> resultBuilder
270+
) {
271+
var mutateStep = new HitsMutateStep(mutateNodeProperty, configuration);
272+
var hook = hitsHookGenerator.createETLHook(configuration);
273+
return algorithmProcessingTemplateConvenience.processAlgorithmInMutateMode(
274+
Optional.empty(),
275+
graphName,
276+
configuration,
277+
Optional.empty(),
278+
Optional.of(List.of(hook)),
279+
HITS,
280+
estimation::hits,
281+
(graph, __) -> algorithms.hits(graph, configuration),
282+
mutateStep,
283+
resultBuilder
284+
);
285+
}
286+
256287

257288
}

applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityApplications.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ public static CentralityApplications create(
6969
estimation,
7070
algorithms,
7171
algorithmProcessingTemplateConvenience,
72-
mutateNodeProperty
72+
mutateNodeProperty,
73+
hitsHookGenerator
7374
);
7475
var stats = new CentralityAlgorithmsStatsModeBusinessFacade(
7576
estimation,

applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/HitsHookGenerator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@
2323
import org.neo4j.gds.hits.HitsConfig;
2424
import org.neo4j.gds.termination.TerminationFlag;
2525

26-
class HitsHookGenerator {
26+
public class HitsHookGenerator {
2727

2828
private final ProgressTrackerCreator progressTrackerCreator;
2929
private final TerminationFlag terminationFlag;
3030

31-
HitsHookGenerator(ProgressTrackerCreator progressTrackerCreator, TerminationFlag terminationFlag) {
31+
public HitsHookGenerator(ProgressTrackerCreator progressTrackerCreator, TerminationFlag terminationFlag) {
3232
this.progressTrackerCreator = progressTrackerCreator;
3333
this.terminationFlag = terminationFlag;
3434
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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.applications.algorithms.centrality;
21+
22+
import org.neo4j.gds.api.Graph;
23+
import org.neo4j.gds.api.GraphStore;
24+
import org.neo4j.gds.api.properties.nodes.NodePropertyValues;
25+
import org.neo4j.gds.api.properties.nodes.NodePropertyValuesAdapter;
26+
import org.neo4j.gds.applications.algorithms.machinery.MutateNodeProperty;
27+
import org.neo4j.gds.applications.algorithms.machinery.MutateStep;
28+
import org.neo4j.gds.applications.algorithms.metadata.NodePropertiesWritten;
29+
import org.neo4j.gds.beta.pregel.PregelResult;
30+
import org.neo4j.gds.hits.HitsConfig;
31+
32+
class HitsMutateStep implements MutateStep<PregelResult, NodePropertiesWritten> {
33+
private final MutateNodeProperty mutateNodeProperty;
34+
private final HitsConfig configuration;
35+
36+
HitsMutateStep(
37+
MutateNodeProperty mutateNodeProperty,
38+
HitsConfig configuration) {
39+
this.mutateNodeProperty = mutateNodeProperty;
40+
this.configuration = configuration;
41+
}
42+
43+
@Override
44+
public NodePropertiesWritten execute(
45+
Graph graph,
46+
GraphStore graphStore,
47+
PregelResult result
48+
) {
49+
var authValues = NodePropertyValuesAdapter.adapt(result.nodeValues().doubleProperties(configuration.authProperty()));
50+
var hubValues = NodePropertyValuesAdapter.adapt(result.nodeValues().doubleProperties(configuration.authProperty()));
51+
var authProperty = configuration.authProperty().concat(configuration.mutateProperty());
52+
var hubProperty = configuration.hubProperty().concat(configuration.mutateProperty());
53+
54+
var authWritten = mutate(graph, graphStore, authProperty,authValues);
55+
var hubWritten = mutate(graph, graphStore, hubProperty,hubValues);
56+
57+
return new NodePropertiesWritten(
58+
authWritten.value() + hubWritten.value()
59+
);
60+
}
61+
62+
private NodePropertiesWritten mutate(
63+
Graph graph,
64+
GraphStore graphStore,
65+
String mutateProperty,
66+
NodePropertyValues values
67+
) {
68+
return mutateNodeProperty.mutateNodeProperties(
69+
graph,
70+
graphStore,
71+
configuration.nodeLabelIdentifiers(graphStore),
72+
mutateProperty,
73+
values
74+
);
75+
}
76+
}

applications/algorithms/machinery/src/main/java/org/neo4j/gds/applications/algorithms/machinery/AlgorithmLabel.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ public static Label from(Algorithm algorithm) {
117117
case FilteredNodeSimilarity -> FilteredNodeSimilarity;
118118
case GraphSage -> GraphSage;
119119
case GraphSageTrain -> GraphSageTrain;
120+
case HITS -> HITS;
120121
case HarmonicCentrality -> HarmonicCentrality;
121122
case HashGNN -> HashGNN;
122123
case IndexInverse -> IndexInverse;

applications/algorithms/machinery/src/main/java/org/neo4j/gds/applications/algorithms/metadata/Algorithm.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public enum Algorithm {
5151
FilteredNodeSimilarity,
5252
GraphSage,
5353
GraphSageTrain,
54+
HITS,
5455
HarmonicCentrality,
5556
HashGNN,
5657
IndexInverse,

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.neo4j.gds.embeddings.hashgnn.HashGNNMutateConfig;
3535
import org.neo4j.gds.embeddings.node2vec.Node2VecMutateConfig;
3636
import org.neo4j.gds.harmonic.HarmonicCentralityMutateConfig;
37+
import org.neo4j.gds.hits.HitsConfig;
3738
import org.neo4j.gds.indexInverse.InverseRelationshipsConfig;
3839
import org.neo4j.gds.influenceMaximization.InfluenceMaximizationMutateConfig;
3940
import org.neo4j.gds.k1coloring.K1ColoringMutateConfig;
@@ -105,6 +106,7 @@ public Function<CypherMapWrapper, AlgoBaseConfig> lookup(Algorithm algorithm) {
105106
case FilteredNodeSimilarity -> FilteredNodeSimilarityMutateConfig::of;
106107
case GraphSage -> graphSageParser();
107108
case GraphSageTrain -> null;
109+
case HITS -> HitsConfig::of;
108110
case HarmonicCentrality -> HarmonicCentralityMutateConfig::of;
109111
case HashGNN -> HashGNNMutateConfig::of;
110112
case IndexInverse -> InverseRelationshipsConfig::of;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ static CanonicalProcedureName algorithmToName(Algorithm algorithm) {
8181
case FilteredNodeSimilarity -> CanonicalProcedureName.parse("gds.nodeSimilarity.filtered");
8282
case GraphSage -> CanonicalProcedureName.parse("gds.beta.graphSage");
8383
case GraphSageTrain -> null;
84+
case HITS -> CanonicalProcedureName.parse("gds.hits");
8485
case HarmonicCentrality -> CanonicalProcedureName.parse("gds.closeness.harmonic");
8586
case HashGNN -> CanonicalProcedureName.parse("gds.hashgnn");
8687
case IndexInverse -> CanonicalProcedureName.parse("gds.graph.relationships.indexInverse");

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.neo4j.gds.ml.pipeline.stubs.GraphSageStub;
4040
import org.neo4j.gds.ml.pipeline.stubs.HarmonicCentralityStub;
4141
import org.neo4j.gds.ml.pipeline.stubs.HashGnnStub;
42+
import org.neo4j.gds.ml.pipeline.stubs.HitsStub;
4243
import org.neo4j.gds.ml.pipeline.stubs.IndexInverseStub;
4344
import org.neo4j.gds.ml.pipeline.stubs.K1ColoringStub;
4445
import org.neo4j.gds.ml.pipeline.stubs.KCoreStub;
@@ -104,6 +105,7 @@ Stub get(Algorithm algorithm) {
104105
case FilteredNodeSimilarity -> new FilteredNodeSimilarityStub();
105106
case GraphSage -> new GraphSageStub();
106107
case GraphSageTrain -> null;
108+
case HITS -> new HitsStub();
107109
case HarmonicCentrality -> new HarmonicCentralityStub();
108110
case HashGNN -> new HashGnnStub();
109111
case IndexInverse -> new IndexInverseStub();
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.hits.HitsConfig;
23+
import org.neo4j.gds.procedures.algorithms.AlgorithmsProcedureFacade;
24+
import org.neo4j.gds.procedures.algorithms.centrality.HitsMutateResult;
25+
import org.neo4j.gds.procedures.algorithms.stubs.MutateStub;
26+
27+
public class HitsStub extends AbstractStub<HitsConfig, HitsMutateResult> {
28+
protected MutateStub<HitsConfig, HitsMutateResult> stub(AlgorithmsProcedureFacade facade) {
29+
return facade.centrality().hitsMutateStub();
30+
}
31+
}

0 commit comments

Comments
 (0)