Skip to content

Commit

Permalink
migrate node classification mutate
Browse files Browse the repository at this point in the history
  • Loading branch information
lassewesth committed Sep 25, 2024
1 parent a0e2ba7 commit 3760663
Show file tree
Hide file tree
Showing 35 changed files with 962 additions and 271 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.gds.applications.algorithms.machinery;

import org.neo4j.gds.api.Graph;
import org.neo4j.gds.api.GraphStore;
import org.neo4j.gds.applications.algorithms.metadata.NodePropertiesWritten;
import org.neo4j.gds.config.AlgoBaseConfig;
import org.neo4j.gds.core.huge.FilteredNodePropertyValues;
import org.neo4j.gds.core.write.NodeProperty;
import org.neo4j.gds.logging.Log;

import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

public class GraphStoreService {
private final Log log;

public GraphStoreService(Log log) {
this.log = log;
}

public NodePropertiesWritten addNodeProperties(
Graph graph,
GraphStore graphStore,
AlgoBaseConfig configuration,
List<NodeProperty> nodeProperties
) {
var translatedProperties = translateProperties(graph, nodeProperties);

log.info("Updating in-memory graph store");
var labelsToUpdate = configuration.nodeLabelIdentifiers(graphStore);

translatedProperties.forEach(nodeProperty -> graphStore.addNodeProperty(
new HashSet<>(labelsToUpdate),
nodeProperty.key(),
nodeProperty.values()
));

return new NodePropertiesWritten(translatedProperties.size() * graph.nodeCount());
}

private List<NodeProperty> translateProperties(Graph graph, List<NodeProperty> nodeProperties) {
return graph
.asNodeFilteredGraph()
.map(filteredGraph -> nodeProperties
.stream()
.map(nodeProperty -> NodeProperty.of(
nodeProperty.key(),
FilteredNodePropertyValues.OriginalToFilteredNodePropertyValues.create(
nodeProperty.values(),
filteredGraph
)
))
.collect(Collectors.toList()))
.orElse(nodeProperties);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
*/
package org.neo4j.gds.applications.algorithms.machinery;

record StandardLabel(String value) implements Label {
public record StandardLabel(String value) implements Label {
@Override
public String asString() {
return value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.neo4j.gds.applications.algorithms.machinery.AlgorithmProcessingTemplateConvenience;
import org.neo4j.gds.applications.algorithms.machinery.ProgressTrackerCreator;
import org.neo4j.gds.applications.algorithms.machinery.RequestScopedDependencies;
import org.neo4j.gds.applications.algorithms.machinery.WriteContext;
import org.neo4j.gds.logging.Log;

public final class SimilarityApplications {
Expand Down Expand Up @@ -53,7 +54,7 @@ public static SimilarityApplications create(
AlgorithmEstimationTemplate algorithmEstimationTemplate,
AlgorithmProcessingTemplateConvenience algorithmProcessingTemplateConvenience,
ProgressTrackerCreator progressTrackerCreator,
WriteRelationshipService writeRelationshipService
WriteContext writeContext
) {
var estimationModeFacade = new SimilarityAlgorithmsEstimationModeBusinessFacade(algorithmEstimationTemplate);
var similarityAlgorithms = new SimilarityAlgorithms(progressTrackerCreator, requestScopedDependencies);
Expand All @@ -77,6 +78,8 @@ public static SimilarityApplications create(
algorithmProcessingTemplateConvenience
);

var writeRelationshipService = new WriteRelationshipService(log, requestScopedDependencies, writeContext);

var writeModeFacade = new SimilarityAlgorithmsWriteModeBusinessFacade(
estimationModeFacade,
similarityAlgorithms,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,13 @@
*/
package org.neo4j.gds.applications;

import org.neo4j.gds.algorithms.similarity.WriteRelationshipService;
import org.neo4j.gds.applications.algorithms.centrality.CentralityApplications;
import org.neo4j.gds.applications.algorithms.community.CommunityApplications;
import org.neo4j.gds.applications.algorithms.embeddings.NodeEmbeddingApplications;
import org.neo4j.gds.applications.algorithms.machinelearning.MachineLearningApplications;
import org.neo4j.gds.applications.algorithms.machinery.AlgorithmEstimationTemplate;
import org.neo4j.gds.applications.algorithms.machinery.AlgorithmProcessingTemplate;
import org.neo4j.gds.applications.algorithms.machinery.AlgorithmProcessingTemplateConvenience;
import org.neo4j.gds.applications.algorithms.machinery.DefaultAlgorithmProcessingTemplate;
import org.neo4j.gds.applications.algorithms.machinery.MemoryGuard;
import org.neo4j.gds.applications.algorithms.machinery.MutateNodeProperty;
import org.neo4j.gds.applications.algorithms.machinery.ProgressTrackerCreator;
import org.neo4j.gds.applications.algorithms.machinery.RequestScopedDependencies;
Expand All @@ -47,8 +44,6 @@
import org.neo4j.gds.core.loading.GraphStoreCatalogService;
import org.neo4j.gds.core.model.ModelCatalog;
import org.neo4j.gds.logging.Log;
import org.neo4j.gds.memest.DatabaseGraphStoreEstimationService;
import org.neo4j.gds.metrics.algorithms.AlgorithmMetricsService;
import org.neo4j.gds.metrics.projections.ProjectionMetricsService;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Transaction;
Expand Down Expand Up @@ -105,43 +100,23 @@ public final class ApplicationsFacade {
public static ApplicationsFacade create(
Log log,
ExportLocation exportLocation,
Optional<Function<AlgorithmProcessingTemplate, AlgorithmProcessingTemplate>> algorithmProcessingTemplateDecorator,
Optional<Function<GraphCatalogApplications, GraphCatalogApplications>> graphCatalogApplicationsDecorator,
Optional<Function<ModelCatalogApplications, ModelCatalogApplications>> modelCatalogApplicationsDecorator,
FeatureTogglesRepository featureTogglesRepository,
GraphStoreCatalogService graphStoreCatalogService,
MemoryGuard memoryGuard,
AlgorithmMetricsService algorithmMetricsService,
ProjectionMetricsService projectionMetricsService,
RequestScopedDependencies requestScopedDependencies,
WriteContext writeContext,
ModelCatalog modelCatalog,
ModelRepository modelRepository,
GraphDatabaseService graphDatabaseService,
Transaction procedureTransaction
Transaction procedureTransaction,
ProgressTrackerCreator progressTrackerCreator,
AlgorithmEstimationTemplate algorithmEstimationTemplate,
AlgorithmProcessingTemplate algorithmProcessingTemplate
) {
var databaseGraphStoreEstimationService = new DatabaseGraphStoreEstimationService(
requestScopedDependencies.getGraphLoaderContext(),
requestScopedDependencies.getUser()
);
var algorithmEstimationTemplate = new AlgorithmEstimationTemplate(
graphStoreCatalogService,
databaseGraphStoreEstimationService,
requestScopedDependencies
);

var algorithmProcessingTemplate = createAlgorithmProcessingTemplate(
log,
algorithmProcessingTemplateDecorator,
graphStoreCatalogService,
memoryGuard,
algorithmMetricsService,
requestScopedDependencies
);
var algorithmProcessingTemplateConvenience = new AlgorithmProcessingTemplateConvenience(algorithmProcessingTemplate);

var progressTrackerCreator = new ProgressTrackerCreator(log, requestScopedDependencies);

var mutateNodeProperty = new MutateNodeProperty(log);

var centralityApplications = CentralityApplications.create(
Expand Down Expand Up @@ -223,15 +198,13 @@ public static ApplicationsFacade create(
mutateNodeProperty
);

var writeRelationshipService = new WriteRelationshipService(log, requestScopedDependencies, writeContext);

var similarityApplications = SimilarityApplications.create(
log,
requestScopedDependencies,
algorithmEstimationTemplate,
algorithmProcessingTemplateConvenience,
progressTrackerCreator,
writeRelationshipService
writeContext
);

return new ApplicationsFacadeBuilder()
Expand All @@ -248,27 +221,6 @@ public static ApplicationsFacade create(
.build();
}

private static AlgorithmProcessingTemplate createAlgorithmProcessingTemplate(
Log log,
Optional<Function<AlgorithmProcessingTemplate, AlgorithmProcessingTemplate>> algorithmProcessingTemplateDecorator,
GraphStoreCatalogService graphStoreCatalogService,
MemoryGuard memoryGuard,
AlgorithmMetricsService algorithmMetricsService,
RequestScopedDependencies requestScopedDependencies
) {
var algorithmProcessingTemplate = DefaultAlgorithmProcessingTemplate.create(
log,
algorithmMetricsService,
graphStoreCatalogService,
memoryGuard,
requestScopedDependencies
);

if (algorithmProcessingTemplateDecorator.isEmpty()) return algorithmProcessingTemplate;

return algorithmProcessingTemplateDecorator.get().apply(algorithmProcessingTemplate);
}

private static GraphCatalogApplications createGraphCatalogApplications(
Log log,
ExportLocation exportLocation,
Expand Down
1 change: 1 addition & 0 deletions proc/common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ dependencies {
api(project(':model-catalog-api'))

implementation project(':algo-common')
implementation project(':algorithms-machinery')
implementation project(':algorithms-procedure-facade')
implementation project(':annotations')
implementation project(':config-api')
Expand Down
45 changes: 15 additions & 30 deletions proc/common/src/main/java/org/neo4j/gds/GraphStoreUpdater.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,16 @@

import org.neo4j.gds.api.Graph;
import org.neo4j.gds.api.GraphStore;
import org.neo4j.gds.applications.algorithms.machinery.GraphStoreService;
import org.neo4j.gds.config.AlgoBaseConfig;
import org.neo4j.gds.config.MutateNodePropertyConfig;
import org.neo4j.gds.core.huge.FilteredNodePropertyValues;
import org.neo4j.gds.core.write.NodeProperty;
import org.neo4j.gds.executor.ComputationResult;
import org.neo4j.gds.executor.ExecutionContext;
import org.neo4j.gds.result.AbstractResultBuilder;
import org.neo4j.gds.logging.Log;
import org.neo4j.gds.result.AbstractResultBuilder;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

/**
* Extracting some common code so that it is reusable; eventually this can probably move to where it is used
Expand All @@ -57,38 +55,25 @@ public static <ALGO extends Algorithm<ALGO_RESULT>, ALGO_RESULT, CONFIG extends
);
}

/**
* Let's eventually get rid of this
*/
@Deprecated
public static void updateGraphStore(
Graph graph,
GraphStore graphStore,
AbstractResultBuilder<?> resultBuilder,
MutateNodePropertyConfig mutatePropertyConfig,
AlgoBaseConfig configuration,
Log log,
final List<NodeProperty> nodePropertyList
) {
var maybeTranslatedProperties = graph
.asNodeFilteredGraph()
.map(filteredGraph -> nodePropertyList
.stream()
.map(nodeProperty -> NodeProperty.of(
nodeProperty.key(),
FilteredNodePropertyValues.OriginalToFilteredNodePropertyValues.create(
nodeProperty.values(),
filteredGraph
)
))
.collect(Collectors.toList()))
.orElse(nodePropertyList);

// TODO: stop using Neo4j Log...
log.info("Updating in-memory graph store");
Collection<NodeLabel> labelsToUpdate = mutatePropertyConfig.nodeLabelIdentifiers(graphStore);

maybeTranslatedProperties.forEach(nodeProperty -> graphStore.addNodeProperty(
new HashSet<>(labelsToUpdate),
nodeProperty.key(),
nodeProperty.values()
));
var nodePropertiesWritten = new GraphStoreService(log).addNodeProperties(
graph,
graphStore,
configuration,
nodePropertyList
);

resultBuilder.withNodePropertiesWritten(maybeTranslatedProperties.size() * graph.nodeCount());
resultBuilder.withNodePropertiesWritten(nodePropertiesWritten.value());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@
import org.neo4j.gds.api.User;
import org.neo4j.gds.api.nodeproperties.ValueType;
import org.neo4j.gds.applications.ApplicationsFacade;
import org.neo4j.gds.applications.algorithms.machinery.DefaultAlgorithmProcessingTemplate;
import org.neo4j.gds.applications.algorithms.machinery.MemoryGuard;
import org.neo4j.gds.applications.algorithms.machinery.ProgressTrackerCreator;
import org.neo4j.gds.applications.algorithms.machinery.RequestScopedDependencies;
import org.neo4j.gds.applications.algorithms.machinery.WriteContext;
import org.neo4j.gds.catalog.GraphProjectProc;
Expand Down Expand Up @@ -500,27 +502,33 @@ private GraphDataScienceProcedures constructFacade() {
.with(EmptyUserLogRegistryFactory.INSTANCE)
.build();


var configurationParser = new UserSpecificConfigurationParser(new ConfigurationParser(DefaultsConfiguration.Instance, LimitsConfiguration.Instance),requestScopedDependencies.getUser());

var genericStub = new GenericStub(configurationParser, null);
var algorithmProcessingTemplate = DefaultAlgorithmProcessingTemplate.create(
logMock,
new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar()),
graphStoreCatalogService,
MemoryGuard.DISABLED,
requestScopedDependencies
);
var applicationsFacade = ApplicationsFacade.create(
logMock,
null,
Optional.empty(),
Optional.empty(),
Optional.empty(),
null,
graphStoreCatalogService,
MemoryGuard.DISABLED,
new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar()),
null,
requestScopedDependencies,
WriteContext.builder().build(),
null,
null,
null,
null
null,
new ProgressTrackerCreator(logMock, requestScopedDependencies),
null,
algorithmProcessingTemplate
);
var communityProcedureFacade = LocalCommunityProcedureFacade.create(
applicationsFacade.community(),
Expand Down
Loading

0 comments on commit 3760663

Please sign in to comment.