Skip to content

Commit caa467c

Browse files
Add clique counting in business facade
1 parent 297d2dd commit caa467c

File tree

3 files changed

+163
-0
lines changed

3 files changed

+163
-0
lines changed

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,12 @@
2525
import org.neo4j.gds.api.User;
2626
import org.neo4j.gds.approxmaxkcut.ApproxMaxKCutParameters;
2727
import org.neo4j.gds.approxmaxkcut.ApproxMaxKCutResult;
28+
import org.neo4j.gds.cliqueCounting.CliqueCountingResult;
29+
import org.neo4j.gds.cliquecounting.CliqueCountingParameters;
2830
import org.neo4j.gds.community.validation.ApproxMaxKCutValidation;
2931
import org.neo4j.gds.core.JobId;
3032
import org.neo4j.gds.core.loading.GraphStoreCatalogService;
33+
import org.neo4j.gds.core.loading.validation.UndirectedOnlyGraphStoreValidation;
3134
import org.neo4j.gds.result.TimedAlgorithmResult;
3235
import org.neo4j.gds.results.ResultTransformerBuilder;
3336

@@ -85,4 +88,35 @@ public <TR> CompletableFuture<TR> approxMaxKCut(
8588

8689
).thenApply(resultTransformerBuilder.build(graphResources));
8790
}
91+
92+
public <TR> CompletableFuture<TR> cliqueCounting(
93+
GraphName graphName,
94+
GraphParameters graphParameters,
95+
Optional<String> relationshipProperty,
96+
CliqueCountingParameters parameters,
97+
JobId jobId,
98+
boolean logProgress,
99+
ResultTransformerBuilder<TimedAlgorithmResult<CliqueCountingResult>, TR> resultTransformerBuilder
100+
) {
101+
// Fetch the Graph the algorithm will operate on
102+
var graphResources = graphStoreCatalogService.fetchGraphResources(
103+
graphName,
104+
graphParameters,
105+
relationshipProperty,
106+
new UndirectedOnlyGraphStoreValidation("Clique Counting"),
107+
Optional.empty(),
108+
user,
109+
databaseId
110+
);
111+
var graph = graphResources.graph();
112+
113+
return computeFacade.cliqueCounting(
114+
graph,
115+
parameters,
116+
jobId,
117+
logProgress
118+
119+
).thenApply(resultTransformerBuilder.build(graphResources));
120+
}
121+
88122
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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.core.loading.validation;
21+
22+
import org.neo4j.gds.NodeLabel;
23+
import org.neo4j.gds.RelationshipType;
24+
import org.neo4j.gds.api.GraphStore;
25+
26+
import java.util.Collection;
27+
import java.util.Set;
28+
import java.util.stream.Collectors;
29+
30+
import static org.neo4j.gds.utils.StringFormatting.formatWithLocale;
31+
32+
public final class UndirectedOnlyGraphStoreValidation extends GraphStoreValidation {
33+
34+
private final String algorithm;
35+
36+
public UndirectedOnlyGraphStoreValidation(String algorithm) {this.algorithm = algorithm;}
37+
38+
@Override
39+
public void validateAlgorithmRequirements(
40+
GraphStore graphStore,
41+
Collection<NodeLabel> selectedLabels,
42+
Collection<RelationshipType> selectedRelationshipTypes
43+
) {
44+
validateOnlyUndirected(graphStore,selectedRelationshipTypes);
45+
}
46+
47+
void validateOnlyUndirected(GraphStore graphStore,Collection<RelationshipType> selectedRelationshipTypes ){
48+
if (!graphStore.schema().filterRelationshipTypes(Set.copyOf(selectedRelationshipTypes)).isUndirected()) {
49+
throw new IllegalArgumentException(formatWithLocale(
50+
"%s requires relationship projections to be UNDIRECTED. " +
51+
"Selected relationships `%s` are not all undirected.",
52+
algorithm,
53+
selectedRelationshipTypes.stream().map(RelationshipType::name).collect(Collectors.toSet())
54+
));
55+
}
56+
}
57+
58+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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.core.loading.validation;
21+
22+
import org.junit.jupiter.api.Test;
23+
import org.neo4j.gds.RelationshipType;
24+
import org.neo4j.gds.api.GraphStore;
25+
import org.neo4j.gds.api.schema.GraphSchema;
26+
27+
import java.util.List;
28+
29+
import static org.assertj.core.api.Assertions.assertThatNoException;
30+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
31+
import static org.mockito.ArgumentMatchers.anySet;
32+
import static org.mockito.Mockito.mock;
33+
import static org.mockito.Mockito.when;
34+
35+
class UndirectedOnlyGraphStoreValidationTest {
36+
37+
@Test
38+
void shouldNotThrowForUndirectedSchema() {
39+
var graphStore = mock(GraphStore.class);
40+
var schema = mock(GraphSchema.class);
41+
var schema2 = mock(GraphSchema.class);
42+
when(schema2.isUndirected()).thenReturn(true);
43+
when(graphStore.schema()).thenReturn(schema);
44+
when(schema.filterRelationshipTypes(anySet())).thenReturn(schema2);
45+
46+
var validation = new UndirectedOnlyGraphStoreValidation("foo");
47+
assertThatNoException().isThrownBy(() -> validation.validateOnlyUndirected(
48+
graphStore,
49+
List.of(RelationshipType.of("REL1"))
50+
));
51+
52+
}
53+
54+
@Test
55+
void shouldThrowForDirectedSchema() {
56+
var graphStore = mock(GraphStore.class);
57+
var schema = mock(GraphSchema.class);
58+
var schema2 = mock(GraphSchema.class);
59+
when(schema2.isUndirected()).thenReturn(false);
60+
when(graphStore.schema()).thenReturn(schema);
61+
when(schema.filterRelationshipTypes(anySet())).thenReturn(schema2);
62+
63+
64+
var validation = new UndirectedOnlyGraphStoreValidation("foo");
65+
assertThatThrownBy(() -> validation.validateOnlyUndirected(graphStore, List.of(RelationshipType.of("REL1"))))
66+
.hasMessageContaining("foo requires relationship projections to be UNDIRECTED. " +
67+
"Selected relationships `[REL1]` are not all undirected");
68+
69+
}
70+
71+
}

0 commit comments

Comments
 (0)